diff --git a/build_src.xml b/build_src.xml new file mode 100644 index 0000000..b5a4d2d --- /dev/null +++ b/build_src.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/eu/engys/application/AbstractApplication.java b/src/eu/engys/application/AbstractApplication.java new file mode 100644 index 0000000..b8c087f --- /dev/null +++ b/src/eu/engys/application/AbstractApplication.java @@ -0,0 +1,252 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.application; + +import static eu.engys.launcher.StartUpMonitor.close; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GraphicsDevice; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Arrays; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JPanel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.Arguments; +import eu.engys.core.OpenFOAMEnvironment; +import eu.engys.core.controller.Controller; +import eu.engys.core.presentation.ActionContainer; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.gui.AboutWindow; +import eu.engys.gui.GlassPane; +import eu.engys.gui.PreferencesDialog; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.view.View; +import eu.engys.gui.view3D.View3DEventListener; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; + +public abstract class AbstractApplication implements Application, ActionContainer { + + private static final Logger logger = LoggerFactory.getLogger(AbstractApplication.class); + + protected JFrame frame; + public View view; + protected Model model; + public Controller controller; + protected View3DEventListener view3dListener; + + public AbstractApplication(Model model, View view, Controller controller) { + this.model = model; + this.view = view; + this.controller = controller; + } + + @Override + public JFrame getFrame() { + return frame; + } + + @Override + public boolean isDemo() { + return false; + } + + @Override + public void checkVersion() { + } + + @Override + public void run() { + initFrame(); + frame.setVisible(true); + trySettingOpenFoamFolder(); + + if (Arguments.stlFiles != null) { + if (Arguments.baseDir != null) { + ActionManager.getInstance().invoke("application.open"); + } else { + ActionManager.getInstance().invoke("application.create"); + } + } else { + if (Arguments.baseDir != null) { + controller.openCase(Arguments.baseDir); + } else { + view.showStartupDialog(this); + } + } + close(); + } + + protected void trySettingOpenFoamFolder() { + OpenFOAMEnvironment.trySettingOpenFoamFolder(frame); + } + + @Override + public void initFrame() { + view.layoutComponents(); + frame = new JFrame(getTitle()) { + @Override + public void dispose() { + EventManager.unregisterAllEventSubscriptions(); + super.dispose(); + } + + /** + * This method fixes the Synthetica laf bug that causes incorrect + * fullscreen window size on secondary monitor. + */ + @Override + public void setMaximizedBounds(Rectangle bounds) { + GraphicsDevice currentFrame = getGraphicsConfiguration().getDevice(); + if (UiUtil.isSecondaryScreen(currentFrame) && getExtendedState() == JFrame.NORMAL) { + super.setMaximizedBounds(UiUtil.getCurrentScreenSize(frame)); + } else { + super.setMaximizedBounds(bounds); + } + } + }; + view.setProgressMonitorParent(frame); + + Dimension preferredDimension = UiUtil.getPreferredScreenSize(); + logger.info("Set dimendions to {}", preferredDimension); + frame.setSize(preferredDimension); + frame.setLocationRelativeTo(null); + + UiUtil.center(frame); + + frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + + frame.setIconImages(Arrays.asList(new Image[] { ((ImageIcon) getSmallIcon()).getImage(), ((ImageIcon) getBigIcon()).getImage() })); + + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + ActionManager.getInstance().invoke("application.exit"); + } + }); + frame.setName("MainFrame"); + frame.getRootPane().updateUI(); + frame.setJMenuBar(view.getMenuBar()); + + frame.getContentPane().setLayout(new BorderLayout()); + frame.getContentPane().add(view, BorderLayout.CENTER); + frame.getContentPane().add(view.getStatusBar(), BorderLayout.SOUTH); + + GlassPane glassPane = new GlassPane(); + frame.setGlassPane(glassPane); + glassPane.setVisible(false); + + + customizeGUIFrame(view); + } + + public View getView() { + return view; + } + + public Model getModel() { + return model; + } + + public abstract String getTitle(); + + protected abstract void customizeGUIFrame(View view); + + protected void addPreferencesItem(final View view) { + JMenuItem preferencesItem = new JMenuItem(new AbstractAction("Preferences", PREFERENCES_ICON) { + @Override + public void actionPerformed(ActionEvent e) { + new PreferencesDialog(isOS(), hasParaview(), hasFieldView(), hasEnsight(), hasSolverPreferences(), model.getDefaults().getDictDataFolder()).show(); + } + }); + preferencesItem.setName("Application Preferences"); + view.getMenuBar().getEditMenu().add(preferencesItem); + } + + protected abstract boolean hasParaview(); + + protected abstract boolean hasFieldView(); + + protected abstract boolean hasEnsight(); + + protected boolean hasSolverPreferences() { + return true; + } + + protected boolean isOS() { + return false; + } + + protected void addHelpItem(final View view) { + view.getMenuBar().getHelpMenu().add(new AbstractAction("About", INFO_ICON) { + @Override + public void actionPerformed(ActionEvent e) { + new AboutWindow(getMediumIcon(), getBannerIcon()); + } + }); + } + + + @Override + public JPanel createAdPanel() { + return new JPanel(); + } + + @Override + public JPanel createVersionPanel() { + return new JPanel(); + } + + /** + * RESOURCES + */ + + public static final Icon PREFERENCES_ICON = ResourcesUtil.getIcon("preferences.icon"); + public static final Icon LICENSE_ICON = ResourcesUtil.getIcon("license.icon"); + public static final Icon INFO_ICON = ResourcesUtil.getIcon("info.icon"); + public static final Icon PDF_ICON = ResourcesUtil.getIcon("file.pdf"); + public static final Icon FOLDER_ICON = ResourcesUtil.getIcon("application.open.icon"); + + public static final Icon SMALL_LOGO = ResourcesUtil.getIcon("engys.logo"); + public static final Icon BIG_LOGO = ResourcesUtil.getIcon("engys.logo.big"); + public static final Icon MEDIUM_LOGO = ResourcesUtil.getIcon("engys.logo.medium"); + public static final Icon FULL_LOGO = ResourcesUtil.getIcon("engys.logo.full"); +} diff --git a/src/eu/engys/application/AdPanel.java b/src/eu/engys/application/AdPanel.java new file mode 100644 index 0000000..ecba263 --- /dev/null +++ b/src/eu/engys/application/AdPanel.java @@ -0,0 +1,133 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.application; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.net.MalformedURLException; +import java.net.URL; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import eu.engys.util.Symbols; +import eu.engys.util.Util; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; + +public class AdPanel extends JPanel { + + private static final String ENGYS = "ENGYS" + Symbols.REGISTERED; + + public static final Icon FAQ = ResourcesUtil.getIcon("helyxos.faq"); + public static final Icon ENGYS_PRODUCTS = ResourcesUtil.getIcon("helyxos.products"); + public static final Icon HELYX_BOX = ResourcesUtil.getIcon("helyxos.helyx.box"); + public static final Icon HELYX_OS_BOX = ResourcesUtil.getIcon("helyxos.helyxos.box"); + public static final Icon ELEMENTS_BOX = ResourcesUtil.getIcon("helyxos.elements.box"); + public static final Icon FULL_LOGO = ResourcesUtil.getIcon("engys.logo.full"); + + public AdPanel() { + super(new BorderLayout()); + layoutComponents(); + + setBorder(BorderFactory.createTitledBorder(ENGYS + " products")); + } + + private void layoutComponents() { + createCentralPanel(); + createSouthPanel(); + } + + private void createCentralPanel() { + JPanel productsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + productsPanel.add(new JLabel(HELYX_BOX)); + productsPanel.add(new JLabel(HELYX_OS_BOX)); + productsPanel.add(new JLabel(ELEMENTS_BOX)); + + add(productsPanel, BorderLayout.CENTER); + } + + private void createSouthPanel() { + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + buttonsPanel.add(createShowImageButton("FAQ", FAQ)); + buttonsPanel.add(createShowImageButton("Products Comparison", ENGYS_PRODUCTS)); + buttonsPanel.add(createOpenEngysSiteButton()); + + JPanel southPanel = new JPanel(new GridLayout(2, 1)); + southPanel.add(new JLabel(FULL_LOGO, JLabel.CENTER)); + southPanel.add(buttonsPanel); + + add(southPanel, BorderLayout.SOUTH); + + } + + private JButton createShowImageButton(final String title, final Icon image) { + return new JButton(new AbstractAction(title) { + + @Override + public void actionPerformed(ActionEvent e) { + JDialog dialog = new JDialog(UiUtil.getActiveWindow(), title); + dialog.setModal(true); + dialog.setSize(1000, 600); + dialog.setLocationRelativeTo(null); + dialog.getContentPane().setLayout(new BorderLayout()); + + JLabel label = new JLabel(image); + label.setBackground(Color.WHITE); + + JScrollPane jsp = new JScrollPane(label); + jsp.setOpaque(false); + jsp.getViewport().setOpaque(false); + jsp.getVerticalScrollBar().setUnitIncrement(20); + dialog.getContentPane().add(jsp, BorderLayout.CENTER); + + dialog.setVisible(true); + } + }); + } + + private JButton createOpenEngysSiteButton() { + return new JButton(new AbstractAction(ENGYS + " Website") { + @Override + public void actionPerformed(ActionEvent e) { + try { + Util.openWebpage(new URL("http://www.engys.com")); + } catch (MalformedURLException e1) { + e1.printStackTrace(); + } + } + }); + } +} diff --git a/src/eu/engys/application/Application.java b/src/eu/engys/application/Application.java new file mode 100644 index 0000000..41278b3 --- /dev/null +++ b/src/eu/engys/application/Application.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.application; + +import javax.swing.Icon; +import javax.swing.JFrame; +import javax.swing.JPanel; + +public interface Application extends Runnable { + + public JFrame getFrame(); + public void initFrame(); + + public abstract String getTitle(); + + public abstract Icon getSmallIcon(); + public abstract Icon getMediumIcon(); + public abstract Icon getBigIcon(); + public abstract Icon getFullLogo(); + + public abstract Icon getBannerIcon(); + public abstract Icon getBgIcon(); + + public abstract JPanel createAdPanel(); + public abstract JPanel createVersionPanel(); + + public void checkVersion(); + +} diff --git a/src/eu/engys/application/ApplicationEventListener.java b/src/eu/engys/application/ApplicationEventListener.java new file mode 100644 index 0000000..21dec04 --- /dev/null +++ b/src/eu/engys/application/ApplicationEventListener.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.application; + +import java.io.File; + +import eu.engys.core.project.CaseParameters; +import eu.engys.gui.events.EventManager.GenericEventListener; + +public interface ApplicationEventListener extends GenericEventListener { + + void createCase(CaseParameters params); + + void openCase(File file); + + void saveCase(File file); + + void setupMesh(); + + void runMesh(); + + void setupCase(); + + void runCase(); + + +} diff --git a/src/eu/engys/application/Batch.java b/src/eu/engys/application/Batch.java new file mode 100644 index 0000000..66e8147 --- /dev/null +++ b/src/eu/engys/application/Batch.java @@ -0,0 +1,35 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.application; + + +public interface Batch extends Runnable { + + public abstract String getTitle(); + +} + diff --git a/src/eu/engys/application/HELYXOS.java b/src/eu/engys/application/HELYXOS.java new file mode 100644 index 0000000..3e70ead --- /dev/null +++ b/src/eu/engys/application/HELYXOS.java @@ -0,0 +1,217 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.application; + +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.net.MalformedURLException; +import java.net.URL; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.inject.Inject; + +import eu.engys.core.OpenFOAMEnvironment; +import eu.engys.core.controller.Controller; +import eu.engys.core.presentation.Action; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.gui.view.View; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.Symbols; +import eu.engys.util.Util; +import eu.engys.util.VersionChecker; +import eu.engys.util.VersionChecker.VersionType; +import eu.engys.util.ui.ResourcesUtil; + +public class HELYXOS extends AbstractApplication { + + private static final Logger logger = LoggerFactory.getLogger(HELYXOS.class); + private static final String DISCLAIMER = "This offering is not approved or endorsed by OpenCFD" + Symbols.COPYRIGHT + " Limited, the producer of the OPENFOAM" + Symbols.COPYRIGHT + " software and owner of the OPENFOAM" + Symbols.COPYRIGHT + " and OpenCFD" + Symbols.COPYRIGHT + " trade marks."; + + private JLabel versionLabel; + private JButton versionButton; + + @Inject + public HELYXOS(Model model, View view, Controller controller) { + super(model, view, controller); + ActionManager.getInstance().parseActions(this); + + BoundaryType.registerBoundaryType(BoundaryType.PATCH); + BoundaryType.registerBoundaryType(BoundaryType.WALL); + BoundaryType.registerBoundaryType(BoundaryType.EMPTY); + BoundaryType.registerBoundaryType(BoundaryType.CYCLIC_AMI); + BoundaryType.registerBoundaryType(BoundaryType.CYCLIC); + BoundaryType.registerBoundaryType(BoundaryType.SYMMETRY_PLANE); + BoundaryType.registerBoundaryType(BoundaryType.SYMMETRY); + BoundaryType.registerBoundaryType(BoundaryType.WEDGE); + } + + @Override + public String getTitle() { + return ApplicationInfo.getName() + " - powered by " + ApplicationInfo.getVendor() + Symbols.REGISTERED; + } + + @Override + protected void customizeGUIFrame(final View view) { + addPreferencesItem(view); + addHelpItem(view); + addSupportItem(view); + } + + @Override + protected void trySettingOpenFoamFolder() { + OpenFOAMEnvironment.trySettingOpenFoamFolderOS(frame); + } + + private void addSupportItem(final View view) { + view.getMenuBar().getHelpMenu().add(new AbstractAction("Support", INFO_ICON) { + @Override + public void actionPerformed(ActionEvent e) { + showSupportWindow(); + } + }); + } + + @Action(key = "application.support.window") + public void showSupportWindow() { + new SupportWindow(getMediumIcon(), getBannerIcon(), DISCLAIMER); + } + + @Override + public void checkVersion() { + new Thread(new Runnable() { + @Override + public void run() { + VersionType versionType = VersionChecker.isNewVersionAvailable(); + if (versionType.isUpdated()) { + versionLabel.setText("Your version is up to date!"); + versionLabel.setForeground(Color.GREEN.darker()); + versionButton.setVisible(false); + } else if (versionType.isOld()) { + versionLabel.setText("Version " + VersionChecker.getOnlineVersion() + " is available for download!"); + versionLabel.setForeground(Color.RED); + versionButton.setVisible(true); + } else if (versionType.isNotAvailable()) { + versionLabel.setText("Version not available!"); + versionButton.setVisible(false); + } + } + }).start(); + } + + @Override + public JPanel createAdPanel() { + return new AdPanel(); + } + + @Override + public JPanel createVersionPanel() { + JPanel panel = new JPanel(new FlowLayout()); + panel.add(versionLabel = new JLabel("Checking for updates...")); + versionLabel.setFont(new Font(versionLabel.getFont().getFontName(), Font.BOLD, versionLabel.getFont().getSize())); + + panel.add(versionButton = new JButton(new AbstractAction("Download") { + @Override + public void actionPerformed(ActionEvent e) { + String downloadPage = ApplicationInfo.getSite() + "/files"; + try { + Util.openWebpage(new URL(downloadPage)); + } catch (MalformedURLException e1) { + logger.error("Cannot open " + downloadPage); + } + } + })); + versionButton.setVisible(false); + panel.setBorder(BorderFactory.createTitledBorder("Version")); + return panel; + } + + @Override + protected boolean isOS() { + return true; + } + + @Override + protected boolean hasParaview() { + return true; + } + + @Override + protected boolean hasFieldView() { + return false; + } + + @Override + protected boolean hasEnsight() { + return false; + } + + @Override + public Icon getSmallIcon() { + return SMALL_LOGO; + } + + @Override + public Icon getBigIcon() { + return BIG_LOGO; + } + + @Override + public Icon getBannerIcon() { + return BANNER; + } + + @Override + public Icon getBgIcon() { + return STARTUP_BACKGROUND; + } + + @Override + public Icon getMediumIcon() { + return MEDIUM_LOGO; + } + + @Override + public Icon getFullLogo() { + return null; + } + + public static final Icon BANNER = ResourcesUtil.getIcon("helyxos.banner"); + public static final Icon STARTUP_BACKGROUND = ResourcesUtil.getIcon("helyxos.startup"); + +} diff --git a/src/eu/engys/application/SupportWindow.java b/src/eu/engys/application/SupportWindow.java new file mode 100644 index 0000000..946395d --- /dev/null +++ b/src/eu/engys/application/SupportWindow.java @@ -0,0 +1,198 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.application; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextPane; +import javax.swing.JWindow; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; + +import eu.engys.util.ApplicationInfo; +import eu.engys.util.Symbols; +import eu.engys.util.ui.UiUtil; + +public class SupportWindow { + + private static final String MESSAGE = "If you require technical assistance with HELYX-OS and OPENFOAM" + Symbols.COPYRIGHT + ", ENGYS offers a dedicated user support package. For more information please contact "; + private static final String SUBJECT = "HELYX-OS%20Info%20Request"; + private final String disclaimer; + + private JWindow window; + private final Icon vendorIcon; + private final Icon applicationIcon; + + public SupportWindow(Icon vendorIcon, Icon applicationIcon, String disclaimer) { + this.vendorIcon = vendorIcon; + this.applicationIcon = applicationIcon; + this.disclaimer = disclaimer; + createWindow(); + } + + private void createWindow() { + window = new JWindow(UiUtil.getActiveWindow()); + window.getContentPane().setLayout(new BorderLayout()); + window.getContentPane().add(createMainPanel(), BorderLayout.CENTER); + window.setSize(420, 320); + window.setLocationRelativeTo(null); + window.setVisible(true); + } + + private JPanel createMainPanel() { + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.setBackground(Color.WHITE); + mainPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + mainPanel.add(createNorthPanel(), BorderLayout.NORTH); + mainPanel.add(createCenterPanel(), BorderLayout.CENTER); + mainPanel.add(createCloseButtonPanel(), BorderLayout.SOUTH); + return mainPanel; + } + + private JPanel createNorthPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.setBackground(Color.WHITE); + panel.add(getImage(vendorIcon), BorderLayout.WEST); + panel.add(getImage(applicationIcon), BorderLayout.CENTER); + panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + return panel; + } + + private JLabel getImage(Icon imageIcon) { + JLabel label = new JLabel(imageIcon); + label.setOpaque(true); + label.setBackground(Color.WHITE); + return label; + } + + private JPanel createCloseButtonPanel() { + JPanel panel = new JPanel(new FlowLayout()); + panel.setBackground(Color.WHITE); + panel.add(new JButton(new AbstractAction("Close") { + @Override + public void actionPerformed(ActionEvent e) { + window.dispose(); + } + })); + return panel; + } + + private JPanel createCenterPanel() { + JLabel vers = center("" + ApplicationInfo.getVersion() + "", 20f, Color.BLACK); + JLabel copy = left("" + ApplicationInfo.getCopyright() + "", 10f, Color.BLACK); + + JPanel infoPanel = new JPanel(new GridBagLayout()); + infoPanel.setBackground(Color.WHITE); + infoPanel.add(vers, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(30, 10, 0, 10), 0, 0)); + infoPanel.add(copy, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 10, 30, 10), 0, 0)); + + JTextPane textPane = createTextPane(); + JScrollPane scrollPane = new JScrollPane(textPane); + + JPanel textPanePanel = new JPanel(new BorderLayout()); + textPanePanel.setBackground(Color.WHITE); + textPanePanel.add(scrollPane, BorderLayout.CENTER); + textPanePanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(infoPanel, BorderLayout.NORTH); + mainPanel.add(textPanePanel, BorderLayout.CENTER); + return mainPanel; + } + + private JTextPane createTextPane() { + JTextPane textPane = new JTextPane(); + textPane.setText(MESSAGE + ApplicationInfo.getMail() + ".\n\n" + disclaimer); + StyledDocument doc = textPane.getStyledDocument(); + SimpleAttributeSet center = new SimpleAttributeSet(); + StyleConstants.setAlignment(center, StyleConstants.ALIGN_LEFT); + doc.setParagraphAttributes(0, doc.getLength(), center, false); + textPane.setCaretPosition(0); + return textPane; + } + + private JButton createMailButton() { + final JButton button = new JButton(new AbstractAction(ApplicationInfo.getMail()) { + + @Override + public void actionPerformed(ActionEvent e) { + // MailManagerSupport.mail(TO, SUBJECT); + } + }); + button.setForeground(Color.BLUE); + return button; + } + + private JLabel center(String text, float size, Color color) { + JLabel label = new JLabel(text) { + @Override + public void paintComponent(Graphics g) { + Graphics2D graphics2d = (Graphics2D) g; + graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + super.paintComponent(g); + } + }; + label.setAlignmentX(JLabel.CENTER_ALIGNMENT); + label.setHorizontalAlignment(JLabel.CENTER); + label.setFont(label.getFont().deriveFont(size)); + label.setForeground(color); + return label; + } + + private JLabel left(String text, float size, Color color) { + JLabel label = new JLabel(text) { + @Override + public void paintComponent(Graphics g) { + Graphics2D graphics2d = (Graphics2D) g; + graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + super.paintComponent(g); + } + }; + label.setAlignmentX(JLabel.LEFT_ALIGNMENT); + label.setHorizontalAlignment(JLabel.LEFT); + label.setFont(label.getFont().deriveFont(size)); + label.setForeground(color); + return label; + } +} diff --git a/src/eu/engys/application/modules/HELYXOSModule.java b/src/eu/engys/application/modules/HELYXOSModule.java new file mode 100644 index 0000000..68a9b81 --- /dev/null +++ b/src/eu/engys/application/modules/HELYXOSModule.java @@ -0,0 +1,285 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.application.modules; + +import com.google.inject.AbstractModule; +import com.google.inject.Singleton; +import com.google.inject.multibindings.Multibinder; +import com.google.inject.name.Names; + +import eu.engys.application.Application; +import eu.engys.application.HELYXOS; +import eu.engys.core.Arguments; +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.HelyxOSController; +import eu.engys.core.controller.ScriptFactory; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.DefaultProjectReader; +import eu.engys.core.project.DefaultProjectWriter; +import eu.engys.core.project.Model; +import eu.engys.core.project.NullProjectReader; +import eu.engys.core.project.NullProjectWriter; +import eu.engys.core.project.ProjectReader; +import eu.engys.core.project.ProjectWriter; +import eu.engys.core.project.defaults.Defaults; +import eu.engys.core.project.defaults.DictDataFolder; +import eu.engys.core.project.defaults.JarDictDataFolder; +import eu.engys.core.project.geometry.factory.DefaultGeometryFactory; +import eu.engys.core.project.geometry.factory.GeometryFactory; +import eu.engys.core.project.materials.MaterialsReader; +import eu.engys.core.project.materials.MaterialsWriter; +import eu.engys.core.project.state.Table15; +import eu.engys.core.project.system.fieldmanipulationfunctionobjects.FieldManipulationFunctionObjectType; +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObjectType; +import eu.engys.core.project.zero.cellzones.CellZoneType; +import eu.engys.core.project.zero.cellzones.CellZonesBuilder; +import eu.engys.core.project.zero.fields.Initialisations; +import eu.engys.gui.Actions; +import eu.engys.gui.GUIPanel; +import eu.engys.gui.StandardScriptFactory; +import eu.engys.gui.casesetup.CaseSetup; +import eu.engys.gui.casesetup.CaseSetup3DElement; +import eu.engys.gui.casesetup.CaseSetupElement; +import eu.engys.gui.casesetup.RuntimeControlsPanel; +import eu.engys.gui.casesetup.actions.StandardCaseSetupActions; +import eu.engys.gui.casesetup.boundaryconditions.BoundaryConditionsPanel; +import eu.engys.gui.casesetup.boundaryconditions.panels.CyclicSettingsPanel; +import eu.engys.gui.casesetup.boundaryconditions.panels.StandardCyclicAMISettingsPanel; +import eu.engys.gui.casesetup.boundaryconditions.panels.patch.PatchSettingsPanel; +import eu.engys.gui.casesetup.boundaryconditions.panels.wall.StandardWallSettingsPanel; +import eu.engys.gui.casesetup.cellzones.CellZonesPanel; +import eu.engys.gui.casesetup.cellzones.StandardCellZonesBuilder; +import eu.engys.gui.casesetup.cellzones.mrf.StandardMRF; +import eu.engys.gui.casesetup.cellzones.porous.StandardPorous; +import eu.engys.gui.casesetup.cellzones.thermal.StandardThermal; +import eu.engys.gui.casesetup.fields.StandardFieldsInitialisationPanel; +import eu.engys.gui.casesetup.fields.StandardInitialisations; +import eu.engys.gui.casesetup.materials.CompressibleMaterialsPanel; +import eu.engys.gui.casesetup.materials.IncompressibleMaterialsPanel; +import eu.engys.gui.casesetup.materials.StandardCompressibleMaterialsPanel; +import eu.engys.gui.casesetup.materials.StandardIncompressibleMaterialsPanel; +import eu.engys.gui.casesetup.materials.StandardMaterialsReader; +import eu.engys.gui.casesetup.materials.StandardMaterialsWriter; +import eu.engys.gui.casesetup.materials.panels.MaterialsDatabasePanel; +import eu.engys.gui.casesetup.materials.panels.MaterialsPanel; +import eu.engys.gui.casesetup.run.StandardTable15; +import eu.engys.gui.casesetup.schemes.NumericalSchemesPanel; +import eu.engys.gui.casesetup.solution.StandardSolutionModellingPanel; +import eu.engys.gui.casesetup.solver.SolverSettingsPanel; +import eu.engys.gui.custom.CustomNodePanel; +import eu.engys.gui.mesh.Mesh; +import eu.engys.gui.mesh.Mesh3DElement; +import eu.engys.gui.mesh.MeshElement; +import eu.engys.gui.mesh.actions.StandardMeshActions; +import eu.engys.gui.mesh.panels.DefaultBoundaryMeshPanel; +import eu.engys.gui.mesh.panels.DefaultMeshAdvancedOptionsPanel; +import eu.engys.gui.mesh.panels.MaterialPointsPanel; +import eu.engys.gui.mesh.panels.SolverBoundaryMeshPanel; +import eu.engys.gui.mesh.panels.StandardBaseMeshPanel; +import eu.engys.gui.mesh.panels.StandardFeatureLinesPanel; +import eu.engys.gui.mesh.panels.StandardGeometryPanel; +import eu.engys.gui.mesh.panels.StandardMeshAdvancedOptionsPanel; +import eu.engys.gui.solver.DefaultRunOptionsPanel; +import eu.engys.gui.solver.Solver; +import eu.engys.gui.solver.Solver3DElement; +import eu.engys.gui.solver.SolverElement; +import eu.engys.gui.solver.SolverRuntimeControlsPanel; +import eu.engys.gui.solver.actions.StandardSolverActions; +import eu.engys.gui.solver.postprocessing.panels.residuals.ResidualsPanel; +import eu.engys.gui.view.View; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view.ViewElement; +import eu.engys.gui.view3D.CanvasPanel; +import eu.engys.gui.view3D.Controller3D; +import eu.engys.gui.view3D.Geometry3DController; +import eu.engys.gui.view3D.Mesh3DController; +import eu.engys.gui.view3D.fallback.FallbackGeometry3DController; +import eu.engys.gui.view3D.fallback.FallbackMesh3DController; +import eu.engys.gui.view3D.fallback.FallbackView3D; +import eu.engys.gui.view3D.widget.Widget; +import eu.engys.launcher.ApplicationLauncher; +import eu.engys.launcher.HELYXOSLauncher; +import eu.engys.standardVOF.StandardVOFModule; +import eu.engys.util.VTKSettings; +import eu.engys.util.plaf.HelyxOSLookAndFeel; +import eu.engys.util.plaf.ILookAndFeel; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.progress.ProgressMonitorImpl; +import eu.engys.vtk.VTKEmptyView3D; +import eu.engys.vtk.VTKGeometry3DController; +import eu.engys.vtk.VTKMesh3DController; +import eu.engys.vtk.VTKView3D; +import eu.engys.vtk.WidgetPanel; + +public class HELYXOSModule extends AbstractModule { + + @Override + protected void configure() { + configureApp(); + configureMVC(); + configureModules(); + configure3D(); + configurePanels(); + configureBoundaryConditions(); + configureCellZones(); + configureFunctionObjects(); + } + + protected void configureApp() { + bind(ILookAndFeel.class).to(HelyxOSLookAndFeel.class).in(Singleton.class); + bind(ApplicationLauncher.class).to(HELYXOSLauncher.class).in(Singleton.class); + bind(String.class).annotatedWith(Names.named("Application")).toInstance("HELYX-OS"); + bind(Application.class).to(HELYXOS.class).in(Singleton.class); + } + + private void configureMVC() { + bind(DictDataFolder.class).to(JarDictDataFolder.class).in(Singleton.class); + bind(Defaults.class).in(Singleton.class); + bind(Model.class).in(Singleton.class); + bind(View.class).in(Singleton.class); + bind(Controller.class).to(HelyxOSController.class).in(Singleton.class); + bind(ProgressMonitor.class).to(ProgressMonitorImpl.class).in(Singleton.class); + + bind(Initialisations.class).to(StandardInitialisations.class).in(Singleton.class); + + bind(ProjectWriter.class).to(DefaultProjectWriter.class); + bind(ProjectReader.class).to(DefaultProjectReader.class); + bind(ProjectWriter.class).annotatedWith(CaseSetup.class).to(NullProjectWriter.class); + bind(ProjectReader.class).annotatedWith(CaseSetup.class).to(NullProjectReader.class); + + bind(CellZonesBuilder.class).to(StandardCellZonesBuilder.class); + + bind(MaterialsReader.class).to(StandardMaterialsReader.class); + bind(MaterialsWriter.class).to(StandardMaterialsWriter.class); + bind(CompressibleMaterialsPanel.class).to(StandardCompressibleMaterialsPanel.class); + + bind(Table15.class).to(StandardTable15.class).in(Singleton.class); + bind(ScriptFactory.class).to(StandardScriptFactory.class).in(Singleton.class); + } + + private void configureModules() { + Multibinder applicationModules = Multibinder.newSetBinder(binder(), ApplicationModule.class); + applicationModules.addBinding().to(StandardVOFModule.class).in(Singleton.class); + } + + protected void configure3D() { + bind(WidgetPanel.class).in(Singleton.class); + if (!VTKSettings.librariesAreLoaded()) { + VTKSettings.LoadAllNativeLibraries(); + } + if (VTKSettings.librariesAreLoaded()) { + if (Arguments.no3D) { + bind(CanvasPanel.class).to(VTKEmptyView3D.class).in(Singleton.class); + } else { + bind(CanvasPanel.class).to(VTKView3D.class).in(Singleton.class); + } + bind(Geometry3DController.class).to(VTKGeometry3DController.class).in(Singleton.class); + bind(Mesh3DController.class).to(VTKMesh3DController.class).in(Singleton.class); + } else { + bind(CanvasPanel.class).to(FallbackView3D.class).in(Singleton.class); + bind(Geometry3DController.class).to(FallbackGeometry3DController.class).in(Singleton.class); + bind(Mesh3DController.class).to(FallbackMesh3DController.class).in(Singleton.class); + } + + Multibinder controllers = Multibinder.newSetBinder(binder(), Controller3D.class); + controllers.addBinding().to(Geometry3DController.class).in(Singleton.class); + controllers.addBinding().to(Mesh3DController.class).in(Singleton.class); + + Multibinder.newSetBinder(binder(), Widget.class); + } + + private void configurePanels() { + bind(String.class).annotatedWith(Mesh.class).toInstance("Mesh"); + bind(String.class).annotatedWith(CaseSetup.class).toInstance("Case Setup"); + bind(String.class).annotatedWith(Solver.class).toInstance("Solver"); + + bind(View3DElement.class).annotatedWith(Mesh.class).to(Mesh3DElement.class); + bind(View3DElement.class).annotatedWith(CaseSetup.class).to(CaseSetup3DElement.class); + bind(View3DElement.class).annotatedWith(Solver.class).to(Solver3DElement.class); + + bind(Actions.class).annotatedWith(Mesh.class).to(StandardMeshActions.class).in(Singleton.class); + bind(Actions.class).annotatedWith(CaseSetup.class).to(StandardCaseSetupActions.class).in(Singleton.class); + bind(Actions.class).annotatedWith(Solver.class).to(StandardSolverActions.class).in(Singleton.class); + + bind(GeometryFactory.class).to(DefaultGeometryFactory.class); + bind(DefaultMeshAdvancedOptionsPanel.class).to(StandardMeshAdvancedOptionsPanel.class); + + bind(MaterialsDatabasePanel.class).in(Singleton.class); + bind(CompressibleMaterialsPanel.class).to(StandardCompressibleMaterialsPanel.class); + bind(IncompressibleMaterialsPanel.class).to(StandardIncompressibleMaterialsPanel.class); + + Multibinder binder = Multibinder.newSetBinder(binder(), ViewElement.class); + binder.addBinding().to(MeshElement.class).in(Singleton.class); + binder.addBinding().to(CaseSetupElement.class).in(Singleton.class); + binder.addBinding().to(SolverElement.class).in(Singleton.class); + + Multibinder panelsMesh = Multibinder.newSetBinder(binder(), GUIPanel.class, Mesh.class); + panelsMesh.addBinding().to(StandardBaseMeshPanel.class).in(Singleton.class); + panelsMesh.addBinding().to(StandardGeometryPanel.class).in(Singleton.class); + panelsMesh.addBinding().to(StandardFeatureLinesPanel.class).in(Singleton.class); + panelsMesh.addBinding().to(MaterialPointsPanel.class).in(Singleton.class); + panelsMesh.addBinding().to(DefaultBoundaryMeshPanel.class).in(Singleton.class); + panelsMesh.addBinding().to(CustomNodePanel.class).in(Singleton.class); + + Multibinder panelsCaseSetup = Multibinder.newSetBinder(binder(), GUIPanel.class, CaseSetup.class); + panelsCaseSetup.addBinding().to(StandardSolutionModellingPanel.class).in(Singleton.class); + panelsCaseSetup.addBinding().to(MaterialsPanel.class).in(Singleton.class); + panelsCaseSetup.addBinding().to(BoundaryConditionsPanel.class).in(Singleton.class); + panelsCaseSetup.addBinding().to(CellZonesPanel.class).in(Singleton.class); + panelsCaseSetup.addBinding().to(NumericalSchemesPanel.class).in(Singleton.class); + panelsCaseSetup.addBinding().to(SolverSettingsPanel.class).in(Singleton.class); + panelsCaseSetup.addBinding().to(RuntimeControlsPanel.class).in(Singleton.class); + panelsCaseSetup.addBinding().to(StandardFieldsInitialisationPanel.class).in(Singleton.class); + panelsCaseSetup.addBinding().to(CustomNodePanel.class).in(Singleton.class); + + Multibinder panelsSolver = Multibinder.newSetBinder(binder(), GUIPanel.class, Solver.class); + panelsSolver.addBinding().to(DefaultRunOptionsPanel.class).in(Singleton.class); + panelsSolver.addBinding().to(SolverRuntimeControlsPanel.class).in(Singleton.class); + panelsSolver.addBinding().to(ResidualsPanel.class).in(Singleton.class); + panelsSolver.addBinding().to(SolverBoundaryMeshPanel.class).in(Singleton.class); + } + + private void configureBoundaryConditions() { + Multibinder bcMultibinder = Multibinder.newSetBinder(binder(), BoundaryTypePanel.class); + bcMultibinder.addBinding().to(PatchSettingsPanel.class).in(Singleton.class); + bcMultibinder.addBinding().to(StandardWallSettingsPanel.class).in(Singleton.class); + bcMultibinder.addBinding().to(CyclicSettingsPanel.class).in(Singleton.class); + bcMultibinder.addBinding().to(StandardCyclicAMISettingsPanel.class).in(Singleton.class); + } + + private void configureCellZones() { + Multibinder zonesMultibinder = Multibinder.newSetBinder(binder(), CellZoneType.class); + zonesMultibinder.addBinding().to(StandardMRF.class).in(Singleton.class); + zonesMultibinder.addBinding().to(StandardPorous.class).in(Singleton.class); + zonesMultibinder.addBinding().to(StandardThermal.class).in(Singleton.class); + } + + private void configureFunctionObjects() { + Multibinder.newSetBinder(binder(), FieldManipulationFunctionObjectType.class); + Multibinder.newSetBinder(binder(), MonitoringFunctionObjectType.class); + } +} diff --git a/src/eu/engys/core/Arguments.java b/src/eu/engys/core/Arguments.java new file mode 100644 index 0000000..90ca5a5 --- /dev/null +++ b/src/eu/engys/core/Arguments.java @@ -0,0 +1,232 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core; + +import java.io.File; +import java.io.FilenameFilter; + +import org.apache.log4j.Level; + +import eu.engys.util.ApplicationInfo; +import eu.engys.util.Util; + +public class Arguments { + + private static final String LINE = " ********************************"; + private static final String TAB = " "; + + public enum CaseType { + SERIAL, PARALLEL + } + + public static boolean verbose = false; + public static boolean no3D = false; + public static boolean load3Dmesh = true; + public static boolean load3Dgeometry = true; + public static Level logLevel = Level.ERROR; + + public static File baseDir = null; + + public static boolean mesh = false; + public static boolean run = false; + public static boolean setup = false; + public static boolean all = false; + public static boolean initialise = false; + + public static boolean server = false; + public static CaseType caseType = null; + public static File[] stlFiles = null; +// public static long timeout = -1L; + + private static final String OPTION_V = "-v"; + private static final String OPTION_VV = "-V"; + private static final String OPTION_HELP = "-help"; + private static final String OPTION_NO3D = "-no3D"; + private static final String OPTION_CASE = "-case"; + + public static final String OPTION_MESH = "-mesh"; + public static final String OPTION_RUN = "-run"; + public static final String OPTION_SETUP = "-setup"; + public static final String OPTION_ALL = "-all"; + public static final String OPTION_INITIALISE = "-initialise"; + + private static final String OPTION_SERVER = "-server"; /* INTERNAL */ + private static final String OPTION_IMPORT = "-import"; /* INTERNAL */ + private static final String OPTION_NOMESH = "-no3Dmesh"; /* INTERNAL */ + private static final String OPTION_NOGEOM = "-no3DGeom"; /* INTERNAL */ +// private static final String OPTION_CORE = "-core"; /* INTERNAL */ +// private static final String OPTION_TIMEOUT = "-timeout"; /* INTERNAL */ + + public static void init(final String[] argv) { + for (int i = 0; i < argv.length; i++) { + final String arg = argv[i]; + + if (arg.charAt(0) == '-') { + switch (arg) { + case OPTION_V: logLevel = Level.INFO; verbose = true; break; + case OPTION_VV: logLevel = Level.DEBUG; verbose = true; break; + case OPTION_NO3D: no3D = true; break; + + case OPTION_CASE: + if (i == argv.length - 1) { + fatal("Missing case folder"); + printUsage(); + exit(-1); + } + String baseDirPath = argv[++i]; + final File baseDir = new File(baseDirPath); + if (!baseDir.exists()) { + warning("Case Folder \"" + baseDir.getAbsolutePath() + "\" Does Not Exist!"); + } else { + Arguments.baseDir = baseDir; + } + break; + + case OPTION_MESH: mesh = true; break; + case OPTION_RUN: run = true; break; + case OPTION_SETUP: setup = true; break; + case OPTION_ALL: all = true; break; + case OPTION_INITIALISE: initialise = true; break; + case OPTION_SERVER: server = true; break; + + case OPTION_NOGEOM: load3Dgeometry = false; break; + case OPTION_NOMESH: load3Dmesh = false; break; + + case OPTION_IMPORT: + if (i == argv.length - 1) { + fatal("Missing import folder"); + printUsage(); + exit(-1); + } + String importPath = argv[++i]; + final File importFolder = new File(importPath); + if (!importFolder.exists()) { + fatal("Import Folder Does Not Exist!"); + exit(-1); + } else if (importFolder.isFile()) { + String name = importFolder.getName(); + if (name.endsWith("stl") || name.endsWith("STL")) { + Arguments.stlFiles = new File[]{importFolder}; + } else { + fatal("Import Folder Does Not Exist!"); + exit(-1); + } + } else { + File[] stls = importFolder.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith("stl") || name.endsWith("STL"); + } + }); + if (stls.length == 0) { + fatal("No files to import!"); + exit(-1); + } else { + Arguments.stlFiles = stls; + } + } + break; + case OPTION_HELP: + printUsage(); + exit(0); + break; + default: + fatal("Unknown Option " + arg); + printUsage(); + exit(0); + break; + } + } + } + checkCase(); + } + + private static void checkCase() { + if (hasCommand()) { + if (Arguments.baseDir == null) { + fatal("Missing case folder"); + printUsage(); + exit(-1); + } + } + } + + private static void fatal(String msg) { + System.err.println(); + System.err.println(LINE); + System.err.println(" " + TAB + "FATAL ERROR:"); + System.err.println(" " + TAB + TAB + msg); + System.err.println(LINE); + } + + private static void warning(String msg) { + System.err.println(); + System.err.println(LINE); + System.err.println(" " + TAB+"WARNING:"); + System.err.println(" " + TAB + TAB + msg); + System.err.println(TAB+LINE); + } + + private static void exit(int status) { + System.exit(status); + } + + private static void printUsage() { + + System.err.println(" USAGE"); + System.err.println(" -----------------------------------------------------"); + if (Util.isWindows()) + System.err.println(" "+ApplicationInfo.getName()+".bat ["+OPTION_V+"] ["+OPTION_VV+"] [-case ] [command] "); + else + System.err.println(" "+ApplicationInfo.getName()+".sh ["+OPTION_V+"] ["+OPTION_VV+"] [-case ] [command] "); + + System.err.println(); + System.err.println(" Options:"); + System.err.println(" " + Util.padWithSpaces(OPTION_HELP, 12) + " Print this help screen."); + System.err.println(" " + Util.padWithSpaces(OPTION_V, 12) + " The verbose output."); + System.err.println(" " + Util.padWithSpaces(OPTION_VV, 12) + " The very verbose output."); + System.err.println(" " + Util.padWithSpaces(OPTION_CASE, 12) + " Specify the case directory for the application."); + System.err.println(" " + Util.padWithSpaces(OPTION_NO3D, 12) + " Does not display 3D window."); + System.err.println(); + System.err.println(" Commands:"); + System.err.println(" " + Util.padWithSpaces(OPTION_MESH, 12) + " Launch mesh creation according to system/snappyHexMeshDict."); + System.err.println(" " + Util.padWithSpaces(OPTION_SETUP, 12) + " Setup the cfd case according to system/caseSetupDict."); + System.err.println(" " + Util.padWithSpaces(OPTION_INITIALISE, 12) + " Initialise the fields according to system/caseSetupDict."); + System.err.println(" " + Util.padWithSpaces(OPTION_RUN, 12) + " Launch the solver."); + System.err.println(" " + Util.padWithSpaces(OPTION_ALL, 12) + " Launch mesh + setup + run."); + System.err.println(" -----------------------------------------------------"); + } + + public static boolean isBatch() { + return Arguments.server || hasCommand(); + } + + private static boolean hasCommand() { + return Arguments.mesh || Arguments.setup || Arguments.run || Arguments.all || Arguments.initialise; + } + +} diff --git a/src/eu/engys/core/LoggerUtil.java b/src/eu/engys/core/LoggerUtil.java new file mode 100644 index 0000000..3e9eec8 --- /dev/null +++ b/src/eu/engys/core/LoggerUtil.java @@ -0,0 +1,153 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core; + +import java.io.File; +import java.io.IOException; + +import org.apache.log4j.ConsoleAppender; +import org.apache.log4j.FileAppender; +import org.apache.log4j.Layout; +import org.apache.log4j.Level; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.Priority; +import org.apache.log4j.spi.LoggingEvent; + +import eu.engys.util.Symbols; +import eu.engys.util.Util; + +public class LoggerUtil { + + public static void initLogger() { + if (Util.isWindows()) { + initNormalLogger(); + } else { + initColorLogger(); + } + } + + private static void initColorLogger() { + org.apache.log4j.Logger.getRootLogger().addAppender(new ColorConsoleAppender(new PatternLayout("%6r - %-30.30t - %-5p %-30.30c{1} %x - %m%n"))); + org.apache.log4j.Logger.getRootLogger().setLevel(Arguments.logLevel); + } + + private static void initNormalLogger() { + org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%6r - %-30.30t - %-5p %-30.30c{1} %x - %m%n"))); + org.apache.log4j.Logger.getRootLogger().setLevel(Arguments.logLevel); + } + + public static void initFlatLogger() { + org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%-5p %m%n"))); + org.apache.log4j.Logger.getRootLogger().setLevel(Arguments.logLevel); + } + + public static void initTestLogger() { + org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%r [%t] %p %c %x - %m%n"))); + org.apache.log4j.Logger.getRootLogger().setLevel(Level.INFO); + } + + public static void initTestLogger(Level level) { + org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%r [%t] %p %c %x - %m%n"))); + org.apache.log4j.Logger.getRootLogger().setLevel(level); + } + + public static void initFileLogger(String file, Level level) throws IOException { + org.apache.log4j.Logger.getRootLogger().removeAllAppenders(); + org.apache.log4j.Logger.getRootLogger().addAppender(new FileAppender(new PatternLayout("%r [%t] %p %c %x - %m%n"), file, false)); + org.apache.log4j.Logger.getRootLogger().setLevel(level); + } + + private static final String LOG_FILE_NAME = "log"; + private static final String TXT_EXT = ".txt"; + + public static void redirectLog(File tempDirectory) { + File log = new File(tempDirectory, LOG_FILE_NAME + TXT_EXT); + try { + initFileLogger(log.getAbsolutePath(), Level.DEBUG); + } catch (Exception e) { + System.out.println("ERROR : Unable to open logger file!"); + System.exit(-1); + } + } + + static class ColorConsoleAppender extends ConsoleAppender { + private static final int NORMAL = 0; + private static final int BRIGHT = 1; + // private static final int FOREGROUND_BLACK = 30; + private static final int FOREGROUND_RED = 31; + private static final int FOREGROUND_GREEN = 32; + private static final int FOREGROUND_YELLOW = 33; + private static final int FOREGROUND_BLUE = 34; + // private static final int FOREGROUND_MAGENTA = 35; + private static final int FOREGROUND_CYAN = 36; + // private static final int FOREGROUND_WHITE = 37; + + private static final String PREFIX = Symbols.ESC + "["; + private static final String SUFFIX = "m"; + private static final char SEPARATOR = ';'; + private static final String END_COLOUR = PREFIX + SUFFIX; + + private static final String FATAL_COLOUR = PREFIX + BRIGHT + SEPARATOR + FOREGROUND_RED + SUFFIX; + private static final String ERROR_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_RED + SUFFIX; + private static final String WARN_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_YELLOW + SUFFIX; + private static final String INFO_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_GREEN + SUFFIX; + private static final String DEBUG_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_CYAN + SUFFIX; + private static final String TRACE_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_BLUE + SUFFIX; + + public ColorConsoleAppender(Layout layout) { + super(layout); + } + + @Override + protected void subAppend(LoggingEvent event) { + this.qw.write(getColour(event.getLevel())); + super.subAppend(event); + this.qw.write(END_COLOUR); + + if (this.immediateFlush) { + this.qw.flush(); + } + } + + private String getColour(Level level) { + switch (level.toInt()) { + case Priority.FATAL_INT: + return FATAL_COLOUR; + case Priority.ERROR_INT: + return ERROR_COLOUR; + case Priority.WARN_INT: + return WARN_COLOUR; + case Priority.INFO_INT: + return INFO_COLOUR; + case Priority.DEBUG_INT: + return DEBUG_COLOUR; + default: + return TRACE_COLOUR; + } + } + } +} diff --git a/src/eu/engys/core/OpenFOAMEnvironment.java b/src/eu/engys/core/OpenFOAMEnvironment.java new file mode 100644 index 0000000..ca14fd9 --- /dev/null +++ b/src/eu/engys/core/OpenFOAMEnvironment.java @@ -0,0 +1,417 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core; + +import static eu.engys.core.project.openFOAMProject.LOG; + +import java.io.File; +import java.io.FileFilter; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JFrame; + +import org.apache.commons.exec.CommandLine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.ScriptBuilder; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.JavaExecutor; +import eu.engys.core.project.Model; +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; +import eu.engys.util.ui.UiUtil; + +public class OpenFOAMEnvironment { + + private static final Logger logger = LoggerFactory.getLogger(OpenFOAMEnvironment.class); + + private static final String[] VARIABLES_TO_UNSET = new String[] { "LD_LIBRARY_PATH", "WM_COMPILER", "WM_PROJECT_VERSION", "WM_THIRDPARTY_VERSION", "ParaView_MAJOR", "ParaView_VERSION", "WM_MPLIB", "FOAM_MPI" }; + + public static void loadEnvironment(ScriptBuilder sb) { + cleanEnvironment(sb); + sb.newLine(); + if (Util.isWindowsScriptStyle()) { + sb.append("call \"%ENV_LOADER%\""); + } else { + sb.append("export ParaView_VERSION=$PV_VERSION"); + sb.append("export FOAM_INST_DIR=$VENDOR_HOME"); + sb.append(". $ENV_LOADER"); + sb.newLine(); + sb.append("set -e"); + sb.append("set -o pipefail"); + } + sb.newLine(); + } + + public static void cleanEnvironment(ScriptBuilder sb) { + for (String var : VARIABLES_TO_UNSET) { + if (Util.isWindowsScriptStyle()) { + sb.append("set " + var + "="); + } else { + sb.append("unset " + var); + } + } + } + + public static void printVariables(ScriptBuilder sb) { + if (Util.isWindowsScriptStyle()) { + sb.append("echo \"Case : %CASE%\""); + sb.append("echo \"Procs : %NP%\""); + sb.append("echo \"Log : %LOG%\""); + sb.append("echo \"Env : %ENV_LOADER%\""); + sb.append("echo \"MachineFile : %MACHINEFILE%\""); + sb.append("echo \"Solver : %SOLVER%\""); + } else { + sb.append("echo \"Case : $CASE\""); + sb.append("echo \"Procs : $NP\""); + sb.append("echo \"Log : $LOG\""); + sb.append("echo \"Env : $ENV_LOADER\""); + sb.append("echo \"Vendor : $VENDOR_HOME\""); + sb.append("echo \"Paraview : $PV_VERSION\""); + sb.append("echo \"MachineFile : $MACHINEFILE\""); + sb.append("echo \"Solver : $SOLVER\""); + } + sb.newLine(); + } + + public static Map getEnvironment(Model model) { + return getEnvironment(model, ""); + } + +// public static Map getEnvironment(Model model, File baseDir) { +// return getEnvironment(model, baseDir, null, null); +// } + + public static Map getEnvironment(Model model, String logFileName) { + return getEnvironment(model, model.getProject().getBaseDir(), logFileName, null); + } + + public static Map getEnvironment(Model model, File baseDir, String logFileName) { + return getEnvironment(model, baseDir, logFileName, null); + } + + public static Map getEnvironment(Model model, String logFileName, String option) { + return getEnvironment(model, model.getProject().getBaseDir(), logFileName, option); + } + + private static Map getEnvironment(Model model, File baseDir, String logFileName, String option) { + Map map = new HashMap<>(); + + Path hostfilePath = Paths.get(model.getProject().getBaseDir().getAbsolutePath()).resolve(model.getSolverModel().getHostfilePath()); + + map.put("CASE", baseDir.getAbsolutePath()); + + map.put("NP", String.valueOf(model.getProject().getProcessors())); + + map.put("SOLVER", model.getState().getSolver().getName()); + + if (logFileName != null) { + map.put("LOG", Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, logFileName).toString()); + } + + map.put("VENDOR_HOME", getVendorHome().getAbsolutePath()); + + map.put("PV_VERSION", getParaviewVersion()); + + map.put("ENV_LOADER", getEnvLoader().getAbsolutePath()); + + if (option != null) { + JavaExecutor executor = Executor.jvm("eu.engys.launcher.Launcher", option, "-V"); + executor.inFolder(baseDir); + + CommandLine cmdLine = executor.getCommandLine(); + map.put("APPLICATION", cmdLine.toString()); + } + + // DPC + if (model.getSolverModel().isQueue()) { + map.put("MACHINEFILE", "-machinefile " + System.getenv("HOSTFILE")); + } else { + map.put("MACHINEFILE", model.getSolverModel().getMultiMachine() ? "-machinefile " + hostfilePath : ""); + } + + return map; + } + + public static Map getTestEnvironment() { + Map map = new HashMap<>(); + map.put("VENDOR_HOME", getVendorHome().getAbsolutePath()); + map.put("ENV_LOADER", getEnvLoader().getAbsolutePath()); + return map; + } + + public static void printHeader(ScriptBuilder sb, String header) { + if (Util.isWindowsScriptStyle()) { + sb.append("@echo off"); + } else { + sb.append("#!/bin/bash"); + } + sb.append(getHeaderDelimiter(header.length())); + sb.append(getHeaderTitle(header)); + sb.append(getHeaderDelimiter(header.length())); + sb.newLine(); + } + + private static String getHeaderTitle(String header) { + StringBuilder sb = new StringBuilder("echo \""); + sb.append("*"); + sb.append(" "); + sb.append(" "); + sb.append(" "); + sb.append(" "); + sb.append(header); + sb.append(" "); + sb.append(" "); + sb.append(" "); + sb.append(" "); + sb.append("*"); + sb.append("\""); + return sb.toString(); + } + + private static String getHeaderDelimiter(int headerLength) { + StringBuilder sb = new StringBuilder("echo \""); + for (int i = 0; i < headerLength + 10; i++) { + sb.append("*"); + } + sb.append("\""); + return sb.toString(); + } + + /* + * Other + */ + + public static void trySettingOpenFoamFolder(JFrame frame) { + if (!OpenFOAMEnvironment.isEnvironementLoaded()) { + File[] openFoamDir = getOpenFoamDir(); + if (Util.isVarArgsNotNullAndOfSize(1, openFoamDir)) { + PrefUtil.setOpenFoamEntry(openFoamDir[0]); + logger.info("Environment set to {}", PrefUtil.getOpenFoamEntry()); + } else { + UiUtil.showCoreEnvironmentNotLoadedWarning(frame); + } + } + } + + public static void trySettingOpenFoamFolderOS(JFrame frame) { + if (!OpenFOAMEnvironment.isEnvironementLoaded()) { + File[] openFoamDir = null; + if (Util.isUnix()) { + openFoamDir = getOpenFoamDirOS_onUnix(); + } else { + openFoamDir = getOpenFoamDir(); + } + if (Util.isVarArgsNotNullAndOfSize(1, openFoamDir)) { + PrefUtil.setOpenFoamEntry(openFoamDir[0]); + logger.info("Environment set to {}", PrefUtil.getOpenFoamEntry()); + } else { + UiUtil.showCoreEnvironmentNotLoadedWarning(frame); + } + } + } + + public static void trySettingParaviewExecutable() { + if (!OpenFOAMEnvironment.isParaviewPathSet() && OpenFOAMEnvironment.isEnvironementLoaded()) { + File paraviewExecutable = getParaViewExecutablePath(); + if (paraviewExecutable != null) { + PrefUtil.setParaViewEntry(paraviewExecutable); + logger.info("ParaView path set to {}", PrefUtil.getParaViewEntry()); + } else { + logger.warn("ParaView path NOT set"); + } + } + } + + public static File[] getOpenFoamDir() { + File[] openFoamFolders = new File[0]; + String jarPath = ""; + try { + jarPath = new File(OpenFOAMEnvironment.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getAbsolutePath(); + File vendorHome = Paths.get(jarPath).getParent().getParent().getParent().getParent().toFile(); + logger.info("Check for valid OpenFOAM folder in {}", vendorHome); + openFoamFolders = vendorHome.listFiles(new FileFilter() { + + @Override + public boolean accept(File file) { + return file.isDirectory() && file.getName().startsWith("OpenFOAM"); + } + }); + } catch (URISyntaxException e) { + logger.error("JarPath {}", jarPath); + } + return openFoamFolders; + } + + private static File getParaViewExecutablePath() { + File[] paraviewFolders = new File[0]; + File[] thirdPartyDirs = getThirdPartyDir(); + if (Util.isVarArgsNotNullAndOfSize(1, thirdPartyDirs)) { + File thirdPartyDir = thirdPartyDirs[0]; + logger.info("Check for valid ParaView folder in {}", thirdPartyDir); + paraviewFolders = thirdPartyDir.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + return file.isDirectory() && file.getName().startsWith("ParaView"); + } + }); + } + if (Util.isVarArgsNotNull(paraviewFolders)) { + for (File pvFolder : paraviewFolders) { + File pvExecutable = Paths.get(pvFolder.getAbsolutePath(), "platforms", "linux64Gcc", "bin", "paraview").toFile(); + if (pvExecutable.exists()) { + return pvExecutable; + } + } + } + return null; + } + + private static File[] getThirdPartyDir() { + File[] openFoamFolders = getOpenFoamDir(); + File[] thirdPartyFolders = new File[0]; + if (Util.isVarArgsNotNullAndOfSize(1, openFoamFolders)) { + File vendorHome = getOpenFoamDir()[0].getParentFile(); + logger.info("Check for valid ThirdParty folder in {}", vendorHome); + thirdPartyFolders = vendorHome.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + return file.isDirectory() && file.getName().startsWith("ThirdParty"); + } + }); + } + return thirdPartyFolders; + } + + private static File[] getOpenFoamDirOS_onUnix() { + File[] openFoamFolders = new File[0]; + File optFolder = new File("/opt"); + logger.info("Check for valid OpenFOAM folder in {}", optFolder); + openFoamFolders = optFolder.listFiles(new FileFilter() { + + @Override + public boolean accept(File file) { + boolean isDir = file.isDirectory(); + String fileName = file.getName(); + boolean ubuntuNameCheck = fileName.startsWith("openfoam"); + boolean fedoraNameCheck = fileName.startsWith("OpenFOAM") && !fileName.contains("ParaView") && !fileName.contains("scotch"); + boolean suseNameCheck = fileName.startsWith("OpenFOAM") && !fileName.contains("ParaView") && !fileName.contains("scotch"); + return isDir && (ubuntuNameCheck || fedoraNameCheck || suseNameCheck); + } + }); + return openFoamFolders; + } + + public static File[] getDocumentationDir() { + File[] documentationFolders = new File[0]; + String jarPath = ""; + try { + jarPath = new File(OpenFOAMEnvironment.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getAbsolutePath(); + File vendorHome = Paths.get(jarPath).getParent().getParent().getParent().getParent().toFile(); + logger.info("Check for valid documentation folder in {}", vendorHome); + documentationFolders = vendorHome.listFiles(new FileFilter() { + + @Override + public boolean accept(File file) { + return file.isDirectory() && file.getName().equals("doc"); + } + }); + } catch (URISyntaxException e) { + logger.error("JarPath {}", jarPath); + } + return documentationFolders; + } + + public static boolean isEnvironementLoaded() { + File openFoamDir = PrefUtil.getOpenFoamEntry(); + if (openFoamDir == null || !openFoamDir.exists() || !openFoamDir.isDirectory()) { + return false; + } + return true; + } + + public static boolean isParaviewPathSet() { + File paraView = PrefUtil.getParaViewEntry(); + if (paraView == null || !paraView.exists() || !paraView.isFile() || !paraView.canExecute()) { + return false; + } + return true; + } + + public static boolean isFieldViewPathSet() { + File fieldView = PrefUtil.getFieldViewEntry(); + if (fieldView == null || !fieldView.exists() || !fieldView.isFile() || !fieldView.canExecute()) { + return false; + } + return true; + } + + public static boolean isEnSightPathSet() { + File enSight = PrefUtil.getEnsightEntry(); + if (enSight == null || !enSight.exists() || !enSight.isFile() || !enSight.canExecute()) { + return false; + } + return true; + } + + private static File getEnvLoader() { + File openFoamEntry = PrefUtil.getOpenFoamEntry(); + if (openFoamEntry != null) { + if (Util.isWindowsScriptStyle()) { + return openFoamEntry.toPath().resolve("etc").resolve("batchrc.bat").toFile(); + } else { + return openFoamEntry.toPath().resolve("etc").resolve("bashrc").toFile(); + } + } + return new File(""); + } + + public static File getVendorHome() { + File openFoamEntry = PrefUtil.getOpenFoamEntry(); + if (openFoamEntry != null) { + return openFoamEntry.getParentFile(); + } + return new File(""); + } + + public static String getParaviewVersion() { + File pvHome = PrefUtil.getParaViewEntry(); + if (pvHome != null && pvHome.exists()) { + String name = pvHome.getName(); + if (name.startsWith("ParaView-")) { + String version = name.substring("ParaView-".length()); + return version; + } + } + return ""; + } + +} diff --git a/src/eu/engys/core/controller/AbstractController.java b/src/eu/engys/core/controller/AbstractController.java new file mode 100644 index 0000000..9c322da --- /dev/null +++ b/src/eu/engys/core/controller/AbstractController.java @@ -0,0 +1,541 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.io.File; +import java.rmi.RemoteException; +import java.util.Set; + +import javax.swing.Icon; +import javax.swing.JOptionPane; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.Arguments; +import eu.engys.core.controller.actions.CommandException; +import eu.engys.core.controller.actions.DeleteMesh; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.presentation.Action; +import eu.engys.core.presentation.ActionContainer; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.CaseParameters; +import eu.engys.core.project.InvalidProjectException; +import eu.engys.core.project.Model; +import eu.engys.core.project.Project200To210Converter; +import eu.engys.core.project.ProjectFolderAnalyzer; +import eu.engys.core.project.ProjectReader; +import eu.engys.core.project.ProjectWriter; +import eu.engys.core.project.SolverState; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.system.monitoringfunctionobjects.ParserView; +import eu.engys.core.project.zero.cellzones.CellZonesBuilder; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.PrefUtil; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; + +public abstract class AbstractController implements Controller, ActionContainer { + + public static final String STOP_SOLVER = "Stop Solver"; + public static final String KILL_SOLVER = "Kill Solver"; + + public static final String STOP_EXECUTION = "Stop Execution"; + public static final String KILL_PROCESS = "Kill Process"; + + public static final String STOP_FIELDS_INITIALISATION = "Stop Fields Initialisation"; + public static final String STOP_MESH_GENERATOR = "Stop Mesh Generator"; + + public static final String CANCEL = "Cancel"; + public static final String CONTINUE_IN_BATCH = "Continue in Batch"; + + private static final Icon EXIT_BIG_ICON = ResourcesUtil.getIcon("application.exit.big.icon"); + private static final String EXIT_LABEL = ResourcesUtil.getString("application.exit.label"); + private static final Logger logger = LoggerFactory.getLogger(Controller.class); + + protected final Model model; + protected final Set modules; + protected final ProjectReader reader; + protected final ProjectWriter writer; + protected final ProgressMonitor monitor; + protected final ScriptFactory scriptFactory; + protected ControllerListener listener; + protected CellZonesBuilder cellZonesBuilder; + + public AbstractController(Model model, Set modules, ProjectReader reader, ProjectWriter writer, CellZonesBuilder cellZonesBuilder, ProgressMonitor monitor, ScriptFactory scriptFactory) { + this.cellZonesBuilder = cellZonesBuilder; + logger.info("Loading {}", getClass().getSimpleName()); + this.model = model; + this.modules = modules; + this.reader = reader; + this.writer = writer; + this.monitor = monitor; + this.scriptFactory = scriptFactory; + } + + /* + * NEW CASE + */ + + @Override + public void createCase(CaseParameters params) { + if (params != null) { + newCaseInAThread(params); + } + } + + private void newCaseInAThread(final CaseParameters params) { + monitor.setTotal(10); + monitor.start(String.format("Creating %s", params), false, new Runnable() { + @Override + public void run() { + create(params); + PrefUtil.putFile(PrefUtil.WORK_DIR, model.getProject().getBaseDir().getParentFile()); + monitor.end(); + } + }); + } + + @Override + public void create(final CaseParameters params) { + if (listener != null) { + listener.beforeNewCase(); + } + clearModel(); + writer.create(params); + if (listener != null) { + listener.afterNewCase(); + } + } + + /* + * OPEN + */ + + @Override + public void openCase(File file) { + if (file == null) { + file = fileToOpenOrNull(); + } + if (file != null) { + ActionManager.getInstance().invoke("application.startup.hide"); + openInAThread(file); + } + Arguments.load3Dgeometry = true; + Arguments.load3Dmesh = true; + } + + private File fileToOpenOrNull() { + final File[] openFile = new File[1]; + Runnable r = new Runnable() { + @Override + public void run() { + File workDir = PrefUtil.getWorkDir(PrefUtil.WORK_DIR); + HelyxFileChooser fileChooser = new HelyxFileChooser(workDir.getAbsolutePath()); + fileChooser.setTitle("Open"); + fileChooser.setSelectionMode(SelectionMode.DIRS_AND_ARCHIVES); + + View3DOptions options = new View3DOptions(); + ReturnValue returnValue = fileChooser.showOpenDialog(options); + if (returnValue.isApprove()) { + File selectedCase = fileChooser.getSelectedFile(); + if (isSuitable(selectedCase)) { + PrefUtil.putFile(PrefUtil.WORK_DIR, selectedCase.getParentFile()); + Arguments.load3Dgeometry = true; + Arguments.load3Dmesh = options.loadMesh(); + openFile[0] = selectedCase; + return; + } + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), selectedCase + "\n appears not to be a valid case folder", "File System Error", JOptionPane.ERROR_MESSAGE); + } + openFile[0] = null; + return; + } + }; + ExecUtil.invokeAndWait(r); + return openFile[0]; + } + + private void openInAThread(final File file) { + monitor.setTotal(10); + monitor.start("Open " + file.getName(), false, new Runnable() { + @Override + public void run() { + open(file); + monitor.end(); + } + }); + } + + @Override + public void open(File file) { + final File baseDir = file.isAbsolute() ? file : file.getAbsoluteFile(); + logger.debug("OPEN file {}", baseDir.getAbsolutePath()); + if (listener != null) { + listener.beforeLoadCase(); + } + clearModel(); + + model.setProject(openFOAMProject.createProject(baseDir, monitor)); + + new Project200To210Converter(model.getProject(), cellZonesBuilder).convert(); + + _read(); + + if (listener != null) { + listener.afterLoadCase(); + } + + logger.debug("OPEN file {} done.", baseDir.getName()); + } + + @Override + public void reopen(OpenOptions options) { + File baseDir = model.getProject().getBaseDir(); + int np = model.getProject().getProcessors(); + boolean parallel = model.getProject().isParallel(); + + logger.debug("REOPEN file {} with option {}", baseDir.getAbsolutePath(), options); + if (listener != null) { + listener.beforeReopenCase(); + } + + if (options == OpenOptions.MESH_ONLY) { + reader.readMesh(); + if (listener != null) { + listener.afterReopenCase(); + } + return; + } + clearModel(); + + switch (options) { + case SERIAL: + model.setProject(openFOAMProject.newSerialProject(baseDir)); + break; + case PARALLEL: + model.setProject(openFOAMProject.newParallelProject(baseDir)); + break; + case CHECK_FOLDER: + model.setProject(openFOAMProject.createProject(baseDir, monitor)); + break; + case CURRENT_SETTINGS: + model.setProject(parallel ? openFOAMProject.newParallelProject(baseDir, np) : openFOAMProject.newSerialProject(baseDir)); + break; + case MESH_ONLY: + break; + default: + break; + } + + reader.read(); + + if (listener != null) { + listener.afterReopenCase(); + } + logger.debug("Open file {} done.", baseDir.getName()); + } + + private void _read() { + try { + reader.read(); + } catch (InvalidProjectException e) { + logger.error(e.getMessage()); + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), e.getMessage(), "Project error", JOptionPane.ERROR_MESSAGE); + clearModel(); + } + } + + @Override + public void reopenCase(final OpenOptions options) { + monitor.start("Reopen " + model.getProject().getBaseDir(), false, new Runnable() { + @Override + public void run() { + reopen(options); + monitor.end(); + } + }); + } + + /* + * SAVE + */ + + @Override + public void saveCase(File file) { + if (file == null) { + file = fileToSaveOrNull(); + } + if (file != null) { + saveInAThread(file); + } + } + + protected void saveInAThread(final File baseDir) { + monitor.info(""); + monitor.start("Save: " + baseDir.getAbsolutePath(), false, new Runnable() { + @Override + public void run() { + save(baseDir); + monitor.end(); + } + }); + } + + @Override + public void save(File baseDir) { + if (baseDir == null) { + baseDir = model.getProject().getBaseDir(); + } + logger.debug("Save file {}", baseDir.getAbsolutePath()); + if (listener != null) + listener.beforeSaveCase(); + writer.write(baseDir); + writeScripts(); + if (listener != null) { + listener.afterSaveCase(); + } + logger.debug("Save file {} done.", baseDir.getName()); + } + + private File fileToSaveOrNull() { + final File[] file = new File[1]; + Runnable r = new Runnable() { + @Override + public void run() { + File workDir = PrefUtil.getWorkDir(PrefUtil.WORK_DIR); + + HelyxFileChooser fileChooser = new HelyxFileChooser(workDir.getAbsolutePath()); + if (model.getProject().getBaseDir().getAbsoluteFile().getParentFile().equals(workDir)) { + fileChooser.selectFile(model.getProject().getBaseDir()); + } + fileChooser.setTitle("Save As"); + fileChooser.setSelectionMode(SelectionMode.DIRS_ONLY); + + ReturnValue returnValue = fileChooser.showSaveAsDialog(); + if (returnValue.isApprove()) { + File baseDir = fileChooser.getSelectedFile(); + if (baseDir != null) { + if (baseDir.exists() && !baseDir.equals(model.getProject().getBaseDir())) { + int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "Folder already exists. Continue anyway?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (retVal == JOptionPane.NO_OPTION) { + file[0] = fileToSaveOrNull(); + return; + } + } + PrefUtil.putFile(PrefUtil.WORK_DIR, baseDir.getParentFile()); + } + file[0] = baseDir; + return; + } + file[0] = null; + return; + } + }; + ExecUtil.invokeAndWait(r); + return file[0]; + } + + /* + * MESH + */ + + @Action(key = "mesh.delete") + public void deleteMesh() { + int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "This action will delete the existing mesh.\nContinue?", "Delete Mesh", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (retVal == JOptionPane.YES_OPTION) { + saveInAThread(model.getProject().getBaseDir()); + new DeleteMesh(model, this).executeClient(); + reopenCase(OpenOptions.CURRENT_SETTINGS); + } + } + + private void writeScripts() { + scriptFactory.getMeshScript(model); + scriptFactory.getInitialiseScript(model); + scriptFactory.getSolverScript(model); + if (model.getSolverModel().isQueue()) { + scriptFactory.getQueueDriver(model); + scriptFactory.getQueueLauncher(model); + } + } + + /* + * OTHER + */ + + @Override + public void createReport() { + } + + protected void clearModel() { + logger.info("--- CLEAR MODEL ---"); + model.init(); + model.setProject(null); + System.gc(); + } + + @Override + public ProjectReader getReader() { + return reader; + } + + @Override + public ProjectWriter getWriter() { + return writer; + } + + public boolean isSuitable(File file) { + return ProjectFolderAnalyzer.isSuitable(file); + } + + @Override + public boolean allowActionsOnRunning(boolean exit) { + if (model != null && model.getSolverModel() != null) { + SolverState solverState = model.getSolverModel().getServerState().getSolverState(); + if (solverState.isMeshing()) { + return handleExitOnMeshRunning(); + } else if (solverState.isInitialising()) { + return handleExitOnFieldsInitialising(); + } else if (solverState.isRunning()) { + return handleExitOnSolverRunning(); + } else if (exit) { + int option = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), EXIT_LABEL + " " + ApplicationInfo.getName() + "?", EXIT_LABEL, JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, EXIT_BIG_ICON); + if (option == JOptionPane.CANCEL_OPTION) { + return false; + } else { + if (getClient() != null && getClient().getServer() != null) { + shutdownServer(); + } + return true; + } + } else if (getClient() != null && getClient().getServer() != null) { + shutdownServer(); + return true; + } + } else if (exit) {// If no case has been loaded yet + int option = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), EXIT_LABEL + " " + ApplicationInfo.getName() + "?", EXIT_LABEL, JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, EXIT_BIG_ICON); + if (option == JOptionPane.CANCEL_OPTION) { + return false; + } + } + return true; + } + + private void shutdownServer() { + try { + getClient().getServer().shutdown(); + } catch (RemoteException e) { + logger.error("Error shutting down server: {}" + e.getMessage()); + } catch (Exception e) { + logger.error("Error shutting down server: {}" + e.getMessage()); + } + } + + protected boolean handleExitOnMeshRunning() { + Object[] options = new Object[] { STOP_MESH_GENERATOR, CONTINUE_IN_BATCH, CANCEL }; + int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Mesh Generator is Running. Select an action to perform.", "Mesh Generator Running", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); + + if (getClient() != null && option == JOptionPane.YES_OPTION) { + kill(); + return true; + } else if (getClient() != null && option == JOptionPane.NO_OPTION) { + getClient().goToBatch(); + return true; + } else { + return false; + } + } + + protected boolean handleExitOnFieldsInitialising() { + Object[] options = new Object[] { STOP_FIELDS_INITIALISATION, CONTINUE_IN_BATCH, CANCEL }; + int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Fields Initialisation is Running. Select an action to perform.", "Fields Initialisation Running", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); + + if (getClient() != null && option == JOptionPane.YES_OPTION) { + kill(); + return true; + } else if (getClient() != null && option == JOptionPane.NO_OPTION) { + getClient().goToBatch(); + return true; + } else { + return false; + } + } + + protected boolean handleExitOnSolverRunning() { + Object[] options = new Object[] { STOP_SOLVER, CONTINUE_IN_BATCH, CANCEL }; + int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Solver is Running. Select an action to perform.", "Solver Running", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); + + if (getClient() != null && option == JOptionPane.YES_OPTION) { + getClient().stopCommand(Command.ANY); + return true; + } else if (getClient() != null && option == JOptionPane.NO_OPTION) { + getClient().goToBatch(); + return true; + } else { + return false; + } + } + + @Override + public void addListener(ControllerListener listener) { + this.listener = listener; + } + + @Override + public ControllerListener getListener() { + return listener; + } + + @Override + public void executeCommand(Command command) throws CommandException { + } + + @Override + public void executeCommands(Command... commands) throws CommandException { + } + + @Override + public boolean isRunningCommand() { + return false; + } + + @Override + public String submitCommand(Command command) throws CommandException { + return null; + } + + @Override + public ParserView getResidualView() { + return null; + } + +} diff --git a/src/eu/engys/core/controller/AbstractScriptFactory.java b/src/eu/engys/core/controller/AbstractScriptFactory.java new file mode 100644 index 0000000..f38e7c3 --- /dev/null +++ b/src/eu/engys/core/controller/AbstractScriptFactory.java @@ -0,0 +1,337 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.io.File; +import java.util.List; + +import eu.engys.core.project.Model; +import eu.engys.util.IOUtils; +import eu.engys.util.Util; + +public abstract class AbstractScriptFactory implements ScriptFactory { + + protected static final String RUN_MESH = "Run Mesh"; + public static final String MESH_SERIAL_RUN = "mesh_serial.run"; + public static final String MESH_SERIAL_BAT = "mesh_serial.bat"; + public static final String MESH_PARALLEL_RUN = "mesh_parallel.run"; + public static final String MESH_PARALLEL_BAT = "mesh_parallel.bat"; + + protected static final String CHECK_MESH = "Check Mesh"; + public static final String CHECK_MESH_SERIAL_RUN = "check_mesh_serial.run"; + public static final String CHECK_MESH_SERIAL_BAT = "check_mesh_serial.bat"; + public static final String CHECK_MESH_PARALLEL_RUN = "check_mesh_parallel.run"; + public static final String CHECK_MESH_PARALLEL_BAT = "check_mesh_parallel.bat"; + + protected static final String RUN_CASE = "Run Case"; + public static final String SOLVER_SERIAL_RUN = "solver_serial.run"; + public static final String SOLVER_SERIAL_BAT = "solver_serial.bat"; + public static final String SOLVER_PARALLEL_RUN = "solver_parallel.run"; + public static final String SOLVER_PARALLEL_BAT = "solver_parallel.bat"; + + protected static final String INITIALISE_FIELDS = "Initialise Fields"; + public static final String INITIALISE_FIELDS_SERIAL_RUN = "initialiseFields_serial.run"; + public static final String INITIALISE_FIELDS_SERIAL_BAT = "initialiseFields_serial.bat"; + public static final String INITIALISE_FIELDS_PARALLEL_RUN = "initialiseFields_parallel.run"; + public static final String INITIALISE_FIELDS_PARALLEL_BAT = "initialiseFields_parallel.bat"; + + protected static final String EXTRUDEMESH = "Extrude To Region"; + private static final String EXTRUDEMESH_SERIAL_RUN = "extrudeMesh_serial.run"; + private static final String EXTRUDEMESH_SERIAL_BAT = "extrudeMesh_serial.bat"; + private static final String EXTRUDEMESH_PARALLEL_RUN = "extrudeMesh_parallel.run"; + private static final String EXTRUDEMESH_PARALLEL_BAT = "extrudeMesh_parallel.bat"; + + /* + * MESH + */ + @Override + public File getMeshScript(Model model) { + File parallelScript = getMeshParallelScript(model); + File serialScript = getMeshSerialScript(model); + + if (model.getProject().isParallel()) { + return parallelScript; + } else { + return serialScript; + } + } + + @Override + public void deleteMeshScripts(Model model) { + File serialFile = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? MESH_SERIAL_BAT : MESH_SERIAL_RUN); + if (serialFile.exists()) { + serialFile.delete(); + } + File parallelFile = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? MESH_PARALLEL_BAT : MESH_PARALLEL_RUN); + if (parallelFile.exists()) { + parallelFile.delete(); + } + } + + @Override + public List getDefaultMeshScript(Model model) { + List script = null; + if (model.getProject().isParallel()) { + script = getParallelMeshScript(); + } else { + script = getSerialMeshScript(); + } + return script; + } + + private File getMeshParallelScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? MESH_PARALLEL_BAT : MESH_PARALLEL_RUN); + writeFileIfNeeded(file, getParallelMeshScript()); + file.setExecutable(true); + return file; + } + + private File getMeshSerialScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? MESH_SERIAL_BAT : MESH_SERIAL_RUN); + writeFileIfNeeded(file, getSerialMeshScript()); + file.setExecutable(true); + return file; + } + + protected abstract List getParallelMeshScript(); + + protected abstract List getSerialMeshScript(); + + @Override + public File getCheckMeshScript(Model model) { + File parallelScript = getCheckMeshParallelScript(model); + File serialScript = getCheckMeshSerialScript(model); + + if (model.getProject().isParallel()) { + return parallelScript; + } else { + return serialScript; + } + } + + @Override + public List getDefaultCheckMeshScript(Model model) { + List script = null; + if (model.getProject().isParallel()) { + script = getParallelMeshScript(); + } else { + script = getSerialMeshScript(); + } + return script; + } + + private File getCheckMeshParallelScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? CHECK_MESH_PARALLEL_BAT : CHECK_MESH_PARALLEL_RUN); + writeFileIfNeeded(file, getParallelCheckMeshScript()); + file.setExecutable(true); + return file; + } + + private File getCheckMeshSerialScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? CHECK_MESH_SERIAL_BAT : CHECK_MESH_SERIAL_RUN); + writeFileIfNeeded(file, getSerialCheckMeshScript()); + file.setExecutable(true); + return file; + } + + protected abstract List getParallelCheckMeshScript(); + + protected abstract List getSerialCheckMeshScript(); + + /* + * SOLVER + */ + + @Override + public File getSolverScript(Model model) { + File parallelScript = getSolverParallelScript(model); + File serialScript = getSolverSerialScript(model); + + if (model.getProject().isParallel()) { + return parallelScript; + } else { + return serialScript; + } + } + + @Override + public List getDefaultSolverScript(Model model) { + List script = null; + if (model.getProject().isParallel()) { + script = getParallelSolverScript(); + } else { + script = getSerialSolverScript(); + } + return script; + } + + protected File getSolverParallelScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? SOLVER_PARALLEL_BAT : SOLVER_PARALLEL_RUN); + writeFileIfNeeded(file, getParallelSolverScript()); + file.setExecutable(true); + return file; + } + + protected File getSolverSerialScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? SOLVER_SERIAL_BAT : SOLVER_SERIAL_RUN); + writeFileIfNeeded(file, getSerialSolverScript()); + file.setExecutable(true); + return file; + } + + protected abstract List getParallelSolverScript(); + + protected abstract List getSerialSolverScript(); + + @Override + public File getInitialiseScript(Model model) { + File parallelScript = getInitialiseParallelScript(model); + File serialScript = getInitialiseSerialScript(model); + + if (model.getProject().isParallel()) { + return parallelScript; + } else { + return serialScript; + } + } + + protected File getInitialiseParallelScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? INITIALISE_FIELDS_PARALLEL_BAT : INITIALISE_FIELDS_PARALLEL_RUN); + writeFileIfNeeded(file, getParallelInitialiseScript()); + file.setExecutable(true); + return file; + } + + protected File getInitialiseSerialScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? INITIALISE_FIELDS_SERIAL_BAT : INITIALISE_FIELDS_SERIAL_RUN); + writeFileIfNeeded(file, getSerialInitialiseScript()); + file.setExecutable(true); + return file; + } + + protected abstract List getParallelInitialiseScript(); + + protected abstract List getSerialInitialiseScript(); + + @Override + public List getDefaultInitialiseScript(Model model) { + List script = null; + if (model.getProject().isParallel()) { + script = getParallelInitialiseScript(); + } else { + script = getSerialInitialiseScript(); + } + return script; + } + + @Override + public File getExtrudeScript(Model model) { + File parallelScript = getExtrudeParallelScript(model); + File serialScript = getExtrudeSerialScript(model); + + if (model.getProject().isParallel()) { + return parallelScript; + } else { + return serialScript; + } + } + + protected File getExtrudeParallelScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? EXTRUDEMESH_PARALLEL_BAT : EXTRUDEMESH_PARALLEL_RUN); + writeFileIfNeeded(file, getParallelExtrudeScript()); + file.setExecutable(true); + return file; + } + + protected File getExtrudeSerialScript(Model model) { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? EXTRUDEMESH_SERIAL_BAT : EXTRUDEMESH_SERIAL_RUN); + writeFileIfNeeded(file, getSerialExtrudeScript()); + file.setExecutable(true); + return file; + } + + protected abstract List getParallelExtrudeScript(); + + protected abstract List getSerialExtrudeScript(); + + @Override + public List getDefaultExtrudeScript(Model model) { + List script = null; + if (model.getProject().isParallel()) { + script = getParallelExtrudeScript(); + } else { + script = getSerialExtrudeScript(); + } + return script; + } + + @Override + public File getQueueLauncher(Model model) { + // if (Util.isWindowsScriptStyle()) { + // File file = new File(model.getProject().getBaseDir(), "driver.pbs"); + // writeFileIfNeeded(file, getWindowsQueueLauncher()); + // return file; + // } else { + File file = new File(model.getProject().getBaseDir(), "pbs.run"); + writeFileIfNeeded(file, getLinuxQueueLauncher()); + return file; + // } + } + + protected abstract List getWindowsQueueLauncher(); + + protected abstract List getLinuxQueueLauncher(); + + @Override + public List getDefaultQueueLauncher(Model model) { + return getLinuxQueueLauncher(); + } + + protected abstract List getWindowsSetupCaseScript(); + + protected abstract List getLinuxSetupCaseScript(); + + @Override + public File getExportScript(Model model) { + File file = new File(model.getProject().getBaseDir(), "export.py"); + writeFileIfNeeded(file, getExportScript()); + return file; + } + + @Override + public List getDefaultExportScript(Model model) { + return getExportScript(); + } + + protected abstract List getExportScript(); + + protected void writeFileIfNeeded(File file, List script) { + if (!file.exists()) { + IOUtils.writeLinesToFile(file, script); + file.setExecutable(true); + } + } +} diff --git a/src/eu/engys/core/controller/ApplicationActions.java b/src/eu/engys/core/controller/ApplicationActions.java new file mode 100644 index 0000000..6c5f5ef --- /dev/null +++ b/src/eu/engys/core/controller/ApplicationActions.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.controller; + +import java.io.File; + +import eu.engys.core.controller.Controller.OpenOptions; +import eu.engys.core.project.CaseParameters; + +public interface ApplicationActions { + + void createCase(CaseParameters params); + + void openCase(File file); + + void reopenCase(OpenOptions options); + + void saveCase(File file); + +} diff --git a/src/eu/engys/core/controller/BatchActions.java b/src/eu/engys/core/controller/BatchActions.java new file mode 100644 index 0000000..1dccc86 --- /dev/null +++ b/src/eu/engys/core/controller/BatchActions.java @@ -0,0 +1,46 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.controller; + +import java.io.File; + +import eu.engys.core.controller.Controller.OpenOptions; +import eu.engys.core.controller.actions.TimeoutException; +import eu.engys.core.project.CaseParameters; + +public interface BatchActions { + + void create(CaseParameters params); + void open(File file); + void reopen(OpenOptions options); + void save(File file); + + void setupCase(); + void stopCase() throws TimeoutException; + void kill(); + +} diff --git a/src/eu/engys/core/controller/Client.java b/src/eu/engys/core/controller/Client.java new file mode 100644 index 0000000..a5aa530 --- /dev/null +++ b/src/eu/engys/core/controller/Client.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import javax.swing.JComponent; + +import eu.engys.core.project.system.monitoringfunctionobjects.ParserView; + +public interface Client { + + void executeCommand(Command command); + + void executeCommands(Command... command); + + ParserView getResidualView(); + + void refreshOnce(); + + void loadState(); + + void stopCommand(Command command); + + void killCommand(Command command); + + void goToBatch(); + + void reset(); + + Server getServer(); + + void createReport(); + + JComponent getServerPanel(); + + JComponent getQueuePanel(); + + void waitForFinished(); + +} diff --git a/src/eu/engys/core/controller/ClientInfo.java b/src/eu/engys/core/controller/ClientInfo.java new file mode 100644 index 0000000..719c8b3 --- /dev/null +++ b/src/eu/engys/core/controller/ClientInfo.java @@ -0,0 +1,50 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.io.Serializable; + +public class ClientInfo implements Serializable { + + private boolean connected; + + private ClientInfo(boolean connected) { + this.connected = connected; + } + + public boolean isConnected() { + return connected; + } + + public static ClientInfo clientConnected() { + return new ClientInfo(true); + } + + public static ClientInfo clientDisconnected() { + return new ClientInfo(false); + } + +} diff --git a/src/eu/engys/core/controller/ClientServerCommand.java b/src/eu/engys/core/controller/ClientServerCommand.java new file mode 100644 index 0000000..4ecee38 --- /dev/null +++ b/src/eu/engys/core/controller/ClientServerCommand.java @@ -0,0 +1,99 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.io.Serializable; + +public class ClientServerCommand implements Serializable { + + private Command[] commands; + private String open; + private boolean parallel; + private boolean startParsers; + private boolean queue; + + public ClientServerCommand(Command... commands) { + this.commands = commands; + this.open = null; + this.parallel = false; + this.startParsers = false; + } + + public ClientServerCommand(Command command, String open, boolean parallel, boolean startParsers) { + this.commands = new Command[]{command}; + this.open = open; + this.parallel = parallel; + this.startParsers = startParsers; + } + + public Command getCommand() { + return commands[0]; + } + + public Command[] getCommands() { + return commands; + } + + public void setCommands(Command[] commands) { + this.commands = commands; + } + + public String getOpen() { + return open; + } + + public void setOpen(String open) { + this.open = open; + } + + public boolean isParallel() { + return parallel; + } + + public void setParallel(boolean parallel) { + this.parallel = parallel; + } + + public boolean isStartParsers() { + return startParsers; + } + + public void setStartParsers(boolean startParsers) { + this.startParsers = startParsers; + } + + public boolean isCommandSequence() { + return commands.length > 1; + } + + public void setQueue(boolean queue) { + this.queue = queue; + } + + public boolean isQueue() { + return queue; + } +} diff --git a/src/eu/engys/core/controller/Command.java b/src/eu/engys/core/controller/Command.java new file mode 100644 index 0000000..fbbc050 --- /dev/null +++ b/src/eu/engys/core/controller/Command.java @@ -0,0 +1,59 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +public enum Command { + + CREATE_MESH("", ""), + RUN_CASE("", ""), + INITIALISE_FIELDS("", ""), + RUN_ALL("", ""), + EXTRUDE_TO_REGION("", ""), + ANY("any", "Any"), + NONE("none", "None"); + + private String key; + private String label; + + private Command(String key, String label) { + this.key = key; + this.label = label; + } + + public String label() { + return label; + } + + public String key() { + return key; + } + + public boolean isRunCase(){ + return this == RUN_CASE || this == RUN_ALL; + } + + +} diff --git a/src/eu/engys/core/controller/CommandInfo.java b/src/eu/engys/core/controller/CommandInfo.java new file mode 100644 index 0000000..81afbf7 --- /dev/null +++ b/src/eu/engys/core/controller/CommandInfo.java @@ -0,0 +1,91 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.io.Serializable; +import java.rmi.RemoteException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CommandInfo implements Serializable { + + private static final Logger logger = LoggerFactory.getLogger(CommandInfo.class); + + public boolean success; + public String message; + public Exception exception; + public String jobID; + + public static CommandInfo remoteException(RemoteException e) { + logger.warn(">>> SERVER REMOTE ERROR", e); + CommandInfo ci = new CommandInfo(); + ci.message = "Error"; + ci.exception = e; + ci.success = false; + return ci; + } + + public static CommandInfo genericException(Exception e) { + logger.error(">>> SERVER GENERIC ERROR", e); + CommandInfo ci = new CommandInfo(); + ci.message = "Error"; + ci.exception = e; + ci.success = false; + return ci; + } + + public static CommandInfo error(String message) { + logger.warn(">>> SERVER WARNING: {}", message); + CommandInfo ci = new CommandInfo(); + ci.message = message; + ci.exception = null; + ci.success = false; + return ci; + } + + public static CommandInfo notConnected() { + CommandInfo ci = new CommandInfo(); + ci.message = "Not Connected"; + ci.exception = null; + ci.success = false; + return ci; + } + + public static CommandInfo success() { + return success("Success"); + } + + public static CommandInfo success(String message) { + logger.info(">>> SERVER: {}", message); + CommandInfo ci = new CommandInfo(); + ci.message = message; + ci.exception = null; + ci.success = true; + return ci; + } + +} diff --git a/src/eu/engys/core/controller/Controller.java b/src/eu/engys/core/controller/Controller.java new file mode 100644 index 0000000..a8aedc9 --- /dev/null +++ b/src/eu/engys/core/controller/Controller.java @@ -0,0 +1,68 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.controller; + +import eu.engys.core.controller.actions.CommandException; +import eu.engys.core.project.ProjectReader; +import eu.engys.core.project.ProjectWriter; +import eu.engys.core.project.system.monitoringfunctionobjects.ParserView; + +public interface Controller extends ApplicationActions, BatchActions { + + public enum CloseOptions { + EXIT, CONTINUE, NONE + } + + public enum OpenOptions { + SERIAL, PARALLEL, CURRENT_SETTINGS, CHECK_FOLDER, MESH_ONLY + } + + boolean isDemo(); + + ProjectWriter getWriter(); + ProjectReader getReader(); + + void addListener(ControllerListener l); + ControllerListener getListener(); + + public Client getClient(); + public Server getServer(); + public ParserView getResidualView(); + + boolean allowActionsOnRunning(boolean exit); + + void createReport(); + + void executeCommand(Command command) throws CommandException; + + void executeCommands(Command... commands) throws CommandException; + + String submitCommand(Command command) throws CommandException; + + boolean isRunningCommand(); + +} diff --git a/src/eu/engys/core/controller/ControllerListener.java b/src/eu/engys/core/controller/ControllerListener.java new file mode 100644 index 0000000..6225c74 --- /dev/null +++ b/src/eu/engys/core/controller/ControllerListener.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.controller; + + +public interface ControllerListener { + + void beforeNewCase(); + void afterNewCase(); + + void beforeLoadCase(); + void afterLoadCase(); + + void beforeReopenCase(); + void afterReopenCase(); + + void beforeSaveCase(); + void afterSaveCase(); + + void beforeRunCase(); + void afterRunCase(); + + void beforeVirtualise(); + void afterVirtualise(GeometryToMesh g2m); + + void beforeCheckMesh(); + void afterCheckMesh(); + + void selectDestinationAndGo(); + + void saveLocation(); + void goToLocation(); + + void afterBlockMesh(); + +} diff --git a/src/eu/engys/core/controller/DefaultNamingConvention.java b/src/eu/engys/core/controller/DefaultNamingConvention.java new file mode 100644 index 0000000..b8a8bdd --- /dev/null +++ b/src/eu/engys/core/controller/DefaultNamingConvention.java @@ -0,0 +1,41 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import eu.engys.core.controller.actions.NamingConvention; +import eu.engys.core.project.geometry.Surface; + +public class DefaultNamingConvention implements NamingConvention { + @Override + public String getCellZoneName(Surface surface) { + return surface.getZoneName(); + } + + @Override + public String getPatchName(Surface surface) { + return surface.getPatchName(); + } +} diff --git a/src/eu/engys/core/controller/DefaultScriptFactory.java b/src/eu/engys/core/controller/DefaultScriptFactory.java new file mode 100644 index 0000000..03fb1d2 --- /dev/null +++ b/src/eu/engys/core/controller/DefaultScriptFactory.java @@ -0,0 +1,398 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.controller; + +import static eu.engys.core.OpenFOAMEnvironment.loadEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.printHeader; +import static eu.engys.core.OpenFOAMEnvironment.printVariables; +import static eu.engys.util.OpenFOAMCommands.BLOCK_MESH; +import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR; +import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR_ALLREGIONS; +import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR_CONSTANT_ALLREGIONS; +import static eu.engys.util.OpenFOAMCommands.EXTRUDE_REGION_TO_MESH; +import static eu.engys.util.OpenFOAMCommands.INITIALISE_FIELDS_PARALLEL; +import static eu.engys.util.OpenFOAMCommands.INITIALISE_FIELDS_SERIAL; +import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR_MESH; +import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR_MESH_CONSTANT; +import static eu.engys.util.OpenFOAMCommands.RUN_CASE_PARALLEL; +import static eu.engys.util.OpenFOAMCommands.RUN_CASE_SERIAL; +import static eu.engys.util.OpenFOAMCommands.RUN_MESH_PARALLEL; +import static eu.engys.util.OpenFOAMCommands.RUN_MESH_SERIAL; +//import static eu.engys.util.OpenFOAMCommands.CHECK_MESH_PARALLEL; +//import static eu.engys.util.OpenFOAMCommands.CHECK_MESH_SERIAL; +import static eu.engys.util.OpenFOAMCommands.SNAPPY_CHECK_MESH_PARALLEL; +import static eu.engys.util.OpenFOAMCommands.SNAPPY_CHECK_MESH_SERIAL; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.commons.io.FileUtils; + +import eu.engys.core.project.Model; +import eu.engys.util.IOUtils; +import eu.engys.util.Util; +import eu.engys.util.connection.QueueParameters; + +public class DefaultScriptFactory extends AbstractScriptFactory { + + private static final String DO_NOT_EDIT_BELOW_THIS_LINE = "# DO NOT EDIT BELOW THIS LINE"; + private static final String DO_NOT_EDIT_ABOVE_THIS_LINE = "# DO NOT EDIT ABOVE THIS LINE"; + protected Model model; + + @Inject + public DefaultScriptFactory(Model model) { + this.model = model; + } + + /* + * MESH + */ + + @Override + protected List getSerialMeshScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, RUN_MESH); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.appendIf(performBlockMesh(), BLOCK_MESH()); + sb.newLine(); + sb.append(RUN_MESH_SERIAL()); + sb.newLine(); + return sb.getLines(); + } + + @Override + protected List getParallelMeshScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, RUN_MESH); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.appendIf(performBlockMesh(), BLOCK_MESH()); + sb.newLine(); + sb.appendIf(performBlockMesh(), DECOMPOSE_PAR()); + sb.newLine(); + sb.append(RUN_MESH_PARALLEL()); + sb.newLine(); + sb.appendIf(performBlockMesh() && Util.isUnixScriptStyle(), "rm -rf constant/polyMesh"); + sb.newLine(); + return sb.getLines(); + } + + @Override + protected List getSerialCheckMeshScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, CHECK_MESH); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(SNAPPY_CHECK_MESH_SERIAL()); + sb.newLine(); + return sb.getLines(); + } + + @Override + protected List getParallelCheckMeshScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, CHECK_MESH); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(SNAPPY_CHECK_MESH_PARALLEL()); + sb.newLine(); + return sb.getLines(); + } + + /* + * SOLVER + */ + + @Override + protected List getSerialSolverScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, RUN_CASE); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(RUN_CASE_SERIAL()); + sb.newLine(); + return sb.getLines(); + } + + @Override + protected List getParallelSolverScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, RUN_CASE); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(RUN_CASE_PARALLEL()); + sb.newLine(); + return sb.getLines(); + } + + /* + * INITIALISE + */ + + @Override + protected List getSerialInitialiseScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, INITIALISE_FIELDS.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(INITIALISE_FIELDS_SERIAL()); + sb.newLine(); + return sb.getLines(); + } + + @Override + protected List getParallelInitialiseScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, INITIALISE_FIELDS.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(INITIALISE_FIELDS_PARALLEL()); + sb.newLine(); + return sb.getLines(); + } + + /* + * EXTRUDE REGION + */ + + @Override + protected List getSerialExtrudeScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, EXTRUDEMESH.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(EXTRUDE_REGION_TO_MESH()); + sb.newLine(); + return sb.getLines(); + } + + @Override + protected List getParallelExtrudeScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, EXTRUDEMESH.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.appendIf(meshOnZero(), RECONSTRUCT_PAR_MESH(), RECONSTRUCT_PAR_MESH_CONSTANT()); + sb.append(EXTRUDE_REGION_TO_MESH()); + sb.appendIf(meshOnZero(), DECOMPOSE_PAR_ALLREGIONS(), DECOMPOSE_PAR_CONSTANT_ALLREGIONS()); + sb.newLine(); + return sb.getLines(); + } + + private boolean meshOnZero() { + return model.getProject().isMeshOnZero(); + } + + /* + * QUEUE + */ + + @Override + public List getDefaultQueueDriver(Model model) { + return getLinuxQueueDriver(defaultBody()); + } + + @Override + public File getQueueDriver(Model model) { + File file = new File(model.getProject().getBaseDir(), "driver.pbs"); + List lines = null; + if (file.exists()) { + lines = getLinuxQueueDriver(extractBody(file)); + } else { + lines = getLinuxQueueDriver(defaultBody()); + } + + IOUtils.writeLinesToFile(file, lines); + return file; + } + + private List extractBody(File file) { + try { + return extractLine(file, DO_NOT_EDIT_ABOVE_THIS_LINE, DO_NOT_EDIT_BELOW_THIS_LINE); + } catch (IOException e) { + e.printStackTrace(); + return Collections.emptyList(); + } + } + + public static List extractLine(File file, String start, String end) throws IOException { + List lines = FileUtils.readLines(file); + List support = new LinkedList(); + + boolean copy = false; + for (String l : lines) { + if(l.startsWith(end)){ + break; + } + if(copy){ + support.add(l); + } + if(l.startsWith(start)){ + copy = true; + } + } + return support; + } + + private List defaultBody() { + InputStream inputStream = DefaultScriptFactory.class.getClassLoader().getResourceAsStream("eu/engys/resources/driver.pbs"); + try { + String body = IOUtils.readStringFromStream(inputStream); + return Arrays.asList(body.split(IOUtils.EOL)); + } catch (IOException e) { + e.printStackTrace(); + return Collections.emptyList(); + } + } + + private List getWindowsQueueDriver() { + throw new RuntimeException("NOT IMPLEMENTED"); + } + + private List getLinuxQueueDriver(List body) { + + String name = model.getProject().getBaseDir().getName(); + QueueParameters queueParameters = model.getSolverModel().getQueueParameters(); + int nodes = queueParameters.getNumberOfNodes(); + int cpus = queueParameters.getCpuPerNode(); + int timeout = queueParameters.getTimeout(); + String feature = queueParameters.getFeature(); + String names = queueParameters.getNodeNames(); + + ScriptBuilder sb = new ScriptBuilder(); + sb.append("#PBS -o " + name + ".out"); + // sb.append("#PBS -e " + name + ".err"); + sb.append("#PBS -j oe"); + // sb.append("#PBS -k oe"); + sb.append("#PBS -N " + name); + if (names == null || names.isEmpty()) { + sb.append("#PBS -l nodes=" + nodes + ":ppn=" + cpus + (feature.isEmpty() ? "" : (":" + feature))); + } else { + sb.append("#PBS -l nodes=" + names + ":ppn=" + cpus + (feature.isEmpty() ? "" : (":" + feature))); + } + sb.append("#PBS -l walltime=" + timeout + ":00:00"); + sb.append("#PBS -V"); + sb.newLine(); + sb.append(DO_NOT_EDIT_ABOVE_THIS_LINE); + sb.newLine(); + for (String line : body) { + sb.append(line); + } + sb.newLine(); + sb.append(DO_NOT_EDIT_BELOW_THIS_LINE); + sb.newLine(); + sb.append("echo \" Environment\""); + sb.append("echo \"---------------------------------\""); + sb.append("echo \" APPLICATION = $APPLICATION\""); + sb.append("echo \" ENV_LOADER = $ENV_LOADER\""); + sb.append("echo \" HOSTFILE = $HOSTFILE\""); + sb.append("echo \" CASE = $CASE\""); + sb.append("echo \" LOG = $LOG\""); + sb.append("echo \" NP = $NP\""); + sb.append("echo \"---------------------------------\""); + sb.append("echo \" PBS_O_WORKDIR = $PBS_O_WORKDIR\""); + sb.append("echo \" PBS_NODEFILE = $PBS_NODEFILE\""); + sb.append("echo \"---------------------------------\""); + sb.append("echo \" HOSTNAME = `hostname`\""); + sb.append("echo \" TIME = `date`\""); + sb.append("echo \" PWD = `pwd`\""); + sb.append("echo \"---------------------------------\""); + sb.newLine(); + sb.append("unset DISPLAY"); + sb.append("export HOSTFILE=$PBS_NODEFILE"); + sb.append("NPROCS=`wc -l < $HOSTFILE`"); + sb.append("NNODES=`uniq $HOSTFILE | wc -l`"); + sb.append("echo \" Using $NPROCS processors across $NNODES nodes\""); + sb.newLine(); + sb.append("cd $PBS_O_WORKDIR"); + sb.newLine(); + sb.append("$APPLICATION -case $CASE &> $LOG"); + sb.newLine(); + sb.append("exit $?"); + + return sb.getLines(); + } + + @Override + protected List getLinuxSetupCaseScript() { + throw new RuntimeException("NOT IMPLEMENTED"); + } + + @Override + protected List getWindowsSetupCaseScript() { + throw new RuntimeException("NOT IMPLEMENTED"); + } + + @Override + protected List getExportScript() { + throw new RuntimeException("NOT IMPLEMENTED"); + } + + @Override + protected List getLinuxQueueLauncher() { + InputStream inputStream = DefaultScriptFactory.class.getClassLoader().getResourceAsStream("eu/engys/resources/pbs.run"); + String driverString = ""; + try { + driverString = IOUtils.readStringFromStream(inputStream); + } catch (IOException e) { + e.printStackTrace(); + } + + return Arrays.asList(driverString.split(IOUtils.EOL)); + } + + @Override + protected List getWindowsQueueLauncher() { + throw new RuntimeException("NOT IMPLEMENTED"); + } + + /* + * UTILS + */ + + protected boolean performBlockMesh() { + return !model.getGeometry().isAutoBoundingBox(); + } +} diff --git a/src/eu/engys/core/controller/GeometryToMesh.java b/src/eu/engys/core/controller/GeometryToMesh.java new file mode 100644 index 0000000..be0d799 --- /dev/null +++ b/src/eu/engys/core/controller/GeometryToMesh.java @@ -0,0 +1,251 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import static eu.engys.core.project.system.SnappyHexMeshDict.BAFFLE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.BOUNDARY_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_TYPE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_ZONE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.INSIDE; +import static eu.engys.core.project.system.SnappyHexMeshDict.LEVELS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MODE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.NONE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.OUTSIDE_KEY; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.actions.NamingConvention; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.Region; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.core.project.zero.patches.Patch; + +public class GeometryToMesh { + + private static final Logger logger = LoggerFactory.getLogger(GeometryToMesh.class); + + private Model model; + private List patches = new ArrayList<>(); + private List cellZones = new ArrayList<>(); + + private List willBePatches = new ArrayList<>(); + private List willBeCellZones = new ArrayList<>(); + + private NamingConvention naming; + + public GeometryToMesh(Model model) { + this.model = model; + this.naming = new DefaultNamingConvention(); + } + + public String[] listPatches() { + extractPatchesFromGeometry(); + + String[] names = new String[patches.size()]; + for (int i = 0; i < names.length; i++) { + names[i] = patches.get(i).getName(); + } + + return names; + } + + public void execute() { + model.getPatches().clear(); + model.getCellZones().clear(); + + extractPatchesFromGeometry(); + + model.getPatches().addPatches(patches); + model.getCellZones().addZones(cellZones); + } + + public List getWillBePatches() { + return willBePatches; + } + + public List getWillBeCellZones() { + return willBeCellZones; + } + + private void extractPatchesFromGeometry() { + for (Surface surface : model.getGeometry().getSurfaces()) { + logger.debug("Surface {}: {} {} {}", surface.getName(), surface.getSurfaceDictionary(), surface.getVolumeDictionary(), surface.getZoneDictionary()); + surfaceToPatch(surface); + surfaceToCellZone(surface); + } + + if (model.getGeometry().hasBlock()) { + surfaceToPatch(model.getGeometry().getBlock()); + } + } + + private void surfaceToCellZone(Surface surface) { + if (willBeACellZone(surface)) { + if (willCreatePatches(surface)) { + zoneToPatches(surface); + } else { + logger.debug("'{}' does NOT become a PATCH+SLAVE", surface.getName()); + } + String zoneName = naming.getCellZoneName(surface); + CellZone zone = new CellZone(zoneName); + zone.setName(zoneName); + zone.setVisible(true); + zone.setLoaded(true); + + logger.debug("'{}' becomes a ZONE with name {}", surface.getName(), zoneName); + + cellZones.add(zone); + willBeCellZones.add(surface); + } else { + logger.debug("'{}' does NOT become a ZONE", surface.getName()); + } + } + + private void zoneToPatches(Surface surface) { + if (surface.hasRegions()) { + if (surface.isSingleton()) { + addPatchAndSlave(surface.getRegions()[0]); + } else if (isBaffle(surface)) { + addPatchAndSlave(surface.getRegions()[0]); + } else if (isBoundary(surface)) { + for (Region region : surface.getRegions()) { + addPatchAndSlave(region); + } + } + } else { + addPatchAndSlave(surface); + } + } + + private boolean willBeACellZone(Surface surface) { + Dictionary zoneDictionary = surface.getZoneDictionary(); + return zoneDictionary != null && !zoneDictionary.isEmpty() && zoneDictionary.isField(FACE_ZONE_KEY) && zoneDictionary.found(FACE_TYPE_KEY) && !zoneDictionary.lookup(FACE_TYPE_KEY).equals(NONE_KEY); + } + + private boolean willCreatePatches(Surface surface) { + Dictionary zoneDictionary = surface.getZoneDictionary(); + return zoneDictionary.found(FACE_TYPE_KEY) && (zoneDictionary.lookup(FACE_TYPE_KEY).equals(BOUNDARY_KEY) || zoneDictionary.lookup(FACE_TYPE_KEY).equals(BAFFLE_KEY)); + } + + private boolean isBoundary(Surface surface) { + Dictionary zoneDictionary = surface.getZoneDictionary(); + return zoneDictionary.lookup(FACE_TYPE_KEY).equals(BOUNDARY_KEY); + } + + private boolean isBaffle(Surface surface) { + Dictionary zoneDictionary = surface.getZoneDictionary(); + return zoneDictionary.lookup(FACE_TYPE_KEY).equals(BAFFLE_KEY); + } + + private void surfaceToPatch(Surface surface) { + if (surface.isSingleton()) { + addPatch(surface); + } else if (surface.hasRegions()) { + for (Region region : surface.getRegions()) { + addPatch(region); + } + } else { + addPatch(surface); + } + } + + private void addPatch(Surface surface) { + if (willBeAPatch(surface)) { + String patchName = naming.getPatchName(surface); + logger.debug("'{}' becomes a PATCH with name {}, {}", surface.getName(), patchName, surface.getSurfaceDictionary()); + patches.add(newPatch(patchName)); + willBePatches.add(surface); + } else { + logger.debug("'{}' does NOT become a PATCH", surface.getName()); + } + } + + private void addPatchAndSlave(Surface surface) { + String patchName = naming.getPatchName(surface); + String slaveName = patchName + "_slave"; + logger.debug("'{}' becomes 2 PATCHES with name {} and {}", surface.getName(), patchName, slaveName); + patches.add(newPatch(patchName)); + willBePatches.add(surface); + patches.add(newPatch(slaveName)); + willBePatches.add(surface); + } + + private Patch newPatch(String name) { + Patch patch = new Patch(name); + patch.setName(name); + patch.setDictionary(new Dictionary(name)); + patch.setVisible(true); + patch.setLoaded(true); + patch.setEmpty(false); + patch.setPhisicalType(BoundaryType.getDefaultType()); + patch.setBoundaryConditions(new BoundaryConditions()); + return patch; + } + + private boolean willBeAPatch(Surface surface) { + return surface.getType().isPlane() + || (surface.getType().isStl() && surface.isSingleton() && isSurfaceRefinementOnly(surface)) + || (surface.getType().isSolid() && willBeAPatch(((Solid)surface).getParent()) ) + || (!surface.getType().isSolid() && isSurfaceRefinementOnly(surface)); + } + + private boolean isSurfaceRefinementOnly(Surface surface) { + boolean surfaceRefinement = isSurfaceRefinement(surface); + boolean volumeRefinement = isVolumeRefinement(surface); + boolean willBeACellZone = willBeACellZone(surface); + + // System.err.println("GeometryToMesh.isSurfaceRefinementOnly() surfaceRefinement: "+surfaceRefinement+", volumeRefinement: "+volumeRefinement+", willBeACellZone: "+willBeACellZone); + return surfaceRefinement && !volumeRefinement && !willBeACellZone; + } + + private boolean isVolumeRefinement(Surface surface) { + Dictionary volumeDictionary = surface.getVolumeDictionary(); + return volumeDictionary != null && !volumeDictionary.isEmpty() && volumeDictionary.isField(LEVELS_KEY) && volumeDictionary.isField(MODE_KEY) && (volumeDictionary.lookup(MODE_KEY).equals(INSIDE) || volumeDictionary.lookup(MODE_KEY).equals(OUTSIDE_KEY)); + } + + private boolean isSurfaceRefinement(Surface surface) { + Dictionary surfaceDictionary = surface.getSurfaceDictionary(); + return surfaceDictionary != null && !surfaceDictionary.isEmpty() && surfaceDictionary.isField("level"); + } + + public String getPatchName(Surface surface) { + return naming.getPatchName(surface); + } + + public String getCellZoneName(Surface surface) { + return naming.getCellZoneName(surface); + } + +} diff --git a/src/eu/engys/core/controller/HelyxOSController.java b/src/eu/engys/core/controller/HelyxOSController.java new file mode 100644 index 0000000..26c3443 --- /dev/null +++ b/src/eu/engys/core/controller/HelyxOSController.java @@ -0,0 +1,428 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import static eu.engys.core.project.system.SetFieldsDict.CELL_SET_KEY; + +import java.io.File; +import java.util.List; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ThreadPoolExecutor; + +import javax.swing.JOptionPane; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.inject.Inject; + +import eu.engys.core.controller.actions.CheckMesh; +import eu.engys.core.controller.actions.InitialiseFields; +import eu.engys.core.controller.actions.RunCommand; +import eu.engys.core.controller.actions.StandardInitialiseFields; +import eu.engys.core.controller.actions.StandardRunCase; +import eu.engys.core.controller.actions.StandardRunMesh; +import eu.engys.core.controller.actions.TimeoutException; +import eu.engys.core.executor.Executor; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.presentation.Action; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.core.project.ProjectReader; +import eu.engys.core.project.ProjectWriter; +import eu.engys.core.project.state.ServerState; +import eu.engys.core.project.system.monitoringfunctionobjects.ParserView; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.core.project.zero.cellzones.CellZonesBuilder; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.gui.casesetup.fields.StandardInitialisations; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.EventManager.Event; +import eu.engys.gui.events.EventManager.GenericEventListener; +import eu.engys.gui.events.application.ApplicationEvent; +import eu.engys.gui.events.application.BaseMeshTypeChangedEvent; +import eu.engys.gui.events.application.OpenMonitorEvent; +import eu.engys.gui.solver.postprocessing.ParsersHandler; +import eu.engys.gui.solver.postprocessing.ParsersViewHandler; +import eu.engys.gui.solver.postprocessing.panels.residuals.ResidualsView; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ScriptEditor; +import eu.engys.util.ui.UiUtil; + +public class HelyxOSController extends AbstractController implements GenericEventListener, ParsersManager { + + private static final long TIMER_INITIAL_DELAY = 500L; + private static final long TIMER_REFRESH_RATE = 1000L; + + private static final Logger logger = LoggerFactory.getLogger(HelyxOSController.class); + private ResidualsView residualsView; + private RunCommand command; + + private Timer timer; + private ParsersHandler parsersHandler; + private ParsersViewHandler viewHandler; + private ThreadPoolExecutor executor; + + @Inject + public HelyxOSController(Model model, CellZonesBuilder cellZonesBuilder, Set modules, ProjectReader reader, ProjectWriter writer, CellZonesBuilder zonesBuilder, ProgressMonitor monitor, ScriptFactory scriptFactory) { + super(model, modules, reader, writer, zonesBuilder, monitor, scriptFactory); + this.residualsView = new ResidualsView(model, monitor); + EventManager.registerEventListener(this, ApplicationEvent.class); + ActionManager.getInstance().parseActions(this); + } + + @Override + public void eventTriggered(Object obj, Event e) { + logger.info("Event triggered {}", e.getClass().getName()); + if (e instanceof OpenMonitorEvent) { + monitor.start(null); + } else if (e instanceof BaseMeshTypeChangedEvent) { + scriptFactory.getMeshScript(model).delete(); + } + } + + /* + * MESH + */ + + @Action(key = "mesh.create", checkEnv = true) + public void runMesh() { + save(model.getProject().getBaseDir()); + + command = new StandardRunMesh(model, this, scriptFactory); + command.beforeExecute(); + command.executeClient(); + } + + @Action(key = "mesh.check", checkEnv = true) + public void checkMesh() { + model.getProject().getSystemFolder().write(model, null); + RunCommand checkMesh = new CheckMesh(model, this, scriptFactory); + checkMesh.beforeExecute(); + checkMesh.executeClient(); + } + + /* + * CASE SETUP + */ + @Override + public void setupCase() { + /* JUST REOPEN IN THIS CASE */ + monitor.start("Open " + model.getProject().getBaseDir(), false, new Runnable() { + @Override + public void run() { + reopen(OpenOptions.CURRENT_SETTINGS); + monitor.end(); + } + }); + } + + @Action(key = "initialise.fields", checkEnv = true) + public void initialiseFields() { + if (model.getProject().getZeroFolder().hasNonZeroTimeFolders()) { + int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "This action will DELETE all the time folders. Continue?", "Initialise Fields", JOptionPane.YES_NO_OPTION); + if (retVal == JOptionPane.YES_OPTION) { + model.getProject().getSystemFolder().getControlDict().startFromZero(); + model.projectChanged(); + } else { + return; + } + } + monitor.start(InitialiseFields.ACTION_NAME, false, new Runnable() { + @Override + public void run() { + save(null); + monitor.end(); + } + }); + + new StandardInitialisations(model, cellZonesBuilder, modules).initializeFields(); + if (cellSetFieldPresent()) { + save(model.getProject().getBaseDir()); + + command = new StandardInitialiseFields(model, this, scriptFactory); + command.beforeExecute(); + command.executeClient(); + } + } + + public boolean cellSetFieldPresent() { + for (Field f : model.getFields().values()) { + if (f.getInitialisationType().equals(CELL_SET_KEY)) { + return true; + } + } + return false; + } + + /* + * SOLVER + */ + + private void startTimer() { + startParsers(); + viewHandler = new ParsersViewHandler(model, this, residualsView); + + executor = Executor.newExecutor("ServerStateMonitor"); + if (timer == null) { + timer = new Timer("- Client Monitor -", true); + } + timer.schedule(new TimerTask() { + @Override + public void run() { + if (executor.getQueue().isEmpty()) { + executor.submit(new Runnable() { + @Override + public void run() { + runTimer(); + } + + }); + } else { + logger.debug("Timer running..."); + } + } + }, TIMER_INITIAL_DELAY, TIMER_REFRESH_RATE); + } + + private void runTimer() { + ServerState state = model.getSolverModel().getServerState(); + Command c = state.getCommand(); + logger.debug("RUN TIMER, STATE IS {}", state.getSolverState()); + if (c.isRunCase()) { + viewHandler.serverChanged(state); + if (state.getSolverState().isFinished() || state.getSolverState().isError()) { + stopTimer(); + } + } + } + + private void stopTimer() { + logger.debug("STOP TIMER"); + if (viewHandler != null) { + viewHandler = null; + } + if (executor != null) { + executor.shutdown(); + executor = null; + } + if (timer != null) { + timer.cancel(); + timer.purge(); + timer = null; + } + } + + @Action(key = "solver.run", checkEnv = true) + public void runCase() { + save(model.getProject().getBaseDir()); + + listener.beforeRunCase(); + command = new StandardRunCase(model, this, scriptFactory); + command.beforeExecute(); + command.executeClient(); + + startTimer(); + } + + @Action(key = "solver.refresh.once") + public void refreshOnce() { + ParsersViewHandler viewHandler = new ParsersViewHandler(model, this, residualsView); + viewHandler.refreshOnce(); + } + + @Override + @Action(key = "solver.stop") + public void stopCase() { + monitor.setIndeterminate(true); + monitor.start("Stop Solver", false, new Runnable() { + @Override + public void run() { + _stopCase(); + monitor.info("DONE"); + monitor.end(); + } + + }); + } + + private void _stopCase() { + try { + command.stop(); + } catch (TimeoutException e) { + Object[] options = new Object[] { "Wait", "Kill Process" }; + int option = JOptionPane.showOptionDialog(monitor.getDialog(), "Solver has not finished yet.\nSelect an action to perform.", "Stop Execution", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); + if (timer != null) { + if (option == JOptionPane.YES_OPTION) { + _stopCase(); + } else { + _kill(); + } + + } + } + } + + @Override + public void kill() { + monitor.setIndeterminate(true); + monitor.start("Killing Command", false, new Runnable() { + @Override + public void run() { + _kill(); + monitor.info("DONE"); + monitor.end(); + } + + }); + } + + private void _kill() { + command.kill(); + } + + /* + * EDIT SCRIPTS + */ + + @Action(key = "solver.run.edit") + public void editRunCaseScript() { + ScriptEditor.getInstance().show(scriptFactory.getSolverScript(model).toPath(), scriptFactory.getDefaultSolverScript(model)); + } + + @Action(key = "mesh.create.edit") + public void editRunMeshScript() { + ScriptEditor.getInstance().show(scriptFactory.getMeshScript(model).toPath(), scriptFactory.getDefaultMeshScript(model)); + } + + @Action(key = "mesh.check.edit") + public void editCheckMeshScript() { + ScriptEditor.getInstance().show(scriptFactory.getCheckMeshScript(model).toPath(), scriptFactory.getDefaultCheckMeshScript(model)); + } + + @Action(key = "initialise.fields.edit") + public void editInitialiseScript() { + ScriptEditor.getInstance().show(scriptFactory.getInitialiseScript(model).toPath(), scriptFactory.getDefaultInitialiseScript(model)); + } + + /* + * Parsers + */ + @Override + public void startParsers() { + logger.info("[SERVER] START PARSERS"); + parsersHandler = new ParsersHandler(model); + parsersHandler.deleteUselessLogFiles(); + } + + @Override + public void endParsers() { + logger.info("[SERVER] END PARSERS"); + if (parsersHandler != null) { + parsersHandler.endParsers(); + parsersHandler = null; + } + } + + @Override + public List updateParser(String foName) { + logger.info("[SERVER] UPDATE PARSERS"); + return parsersHandler.refreshParsersForFunctionObject(foName); + } + + @Override + public List updateParserOnce(String foName) { + logger.info("[SERVER] UPDATE PARSERS ONCE"); + ParsersHandler ph = new ParsersHandler(model); + return ph.refreshOnceForFunctionObject(foName); + } + + /* + * OTHER + */ + + @Override + public ParserView getResidualView() { + return residualsView; + } + + @Override + public void open(File baseDir) { + super.open(baseDir); + if (listener != null) { + // client.loadState(); + listener.selectDestinationAndGo(); + } + } + + @Override + public void reopen(OpenOptions options) { + if (listener != null) { + listener.saveLocation(); + } + + super.reopen(options); + + if (listener != null) { + // client.loadState(); + listener.goToLocation(); + } + + } + + @Override + public Client getClient() { + return null; + } + + @Override + public Server getServer() { + return null; + } + + @Override + public boolean isDemo() { + return false; + } + + @Override + protected boolean handleExitOnSolverRunning() { + Object[] options = new Object[] { STOP_SOLVER, KILL_SOLVER, CANCEL }; + int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Solver is Running. Select an action to perform.", STOP_SOLVER, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); + + if (option == JOptionPane.YES_OPTION) { + stopCase(); + return true; + } else if (option == JOptionPane.NO_OPTION) { + kill(); + return true; + } else { + return false; + } + } +} diff --git a/src/eu/engys/core/controller/ILogServer.java b/src/eu/engys/core/controller/ILogServer.java new file mode 100644 index 0000000..0f5708d --- /dev/null +++ b/src/eu/engys/core/controller/ILogServer.java @@ -0,0 +1,40 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.io.Serializable; + +public interface ILogServer extends Serializable { + + void start(String key); + + void pump(String key, String lines); + + void close(); + + void stop(String key); + +} diff --git a/src/eu/engys/core/controller/LogClient.java b/src/eu/engys/core/controller/LogClient.java new file mode 100644 index 0000000..97ea61f --- /dev/null +++ b/src/eu/engys/core/controller/LogClient.java @@ -0,0 +1,41 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.io.OutputStream; +import java.io.Serializable; + +public interface LogClient extends Serializable { + + void start(String key, OutputStream out, OutputStream err); + + void pump(String key, String lines); + + void close(); + + void stop(String key); + +} diff --git a/src/eu/engys/core/controller/ParsersManager.java b/src/eu/engys/core/controller/ParsersManager.java new file mode 100644 index 0000000..eaefad8 --- /dev/null +++ b/src/eu/engys/core/controller/ParsersManager.java @@ -0,0 +1,43 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.rmi.RemoteException; +import java.util.List; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; + +public interface ParsersManager { + + void startParsers() throws RemoteException; + + List updateParser(String functionObjectName) throws RemoteException; + + List updateParserOnce(String functionObjectName) throws RemoteException; + + void endParsers() throws RemoteException; + +} diff --git a/src/eu/engys/core/controller/QueueConnector.java b/src/eu/engys/core/controller/QueueConnector.java new file mode 100644 index 0000000..0ecf225 --- /dev/null +++ b/src/eu/engys/core/controller/QueueConnector.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.util.Map; + +public interface QueueConnector { + + String submit(Map env); + + void kill(); + +} diff --git a/src/eu/engys/core/controller/QueueInfo.java b/src/eu/engys/core/controller/QueueInfo.java new file mode 100644 index 0000000..c18d168 --- /dev/null +++ b/src/eu/engys/core/controller/QueueInfo.java @@ -0,0 +1,41 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.io.Serializable; +import java.util.List; + +import com.tupilabs.pbs.model.Job; +import com.tupilabs.pbs.model.Node; +import com.tupilabs.pbs.model.Queue; + +public class QueueInfo implements Serializable { + + public List nodes; + public List queues; + public List jobs; + +} diff --git a/src/eu/engys/core/controller/ScriptBuilder.java b/src/eu/engys/core/controller/ScriptBuilder.java new file mode 100644 index 0000000..4195303 --- /dev/null +++ b/src/eu/engys/core/controller/ScriptBuilder.java @@ -0,0 +1,65 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.util.LinkedList; +import java.util.List; + +public class ScriptBuilder { + + private List lines; + + public ScriptBuilder() { + lines = new LinkedList(); + } + + public void append(String s) { + lines.add(s); + } + + public void appendIf(boolean b, String s) { + if (b) { + lines.add(s); + } + } + + public void appendIf(boolean b, String s1, String s2) { + if (b) { + lines.add(s1); + } else { + lines.add(s2); + } + } + + public void newLine() { + lines.add(""); + } + + public List getLines() { + return lines; + } + +} diff --git a/src/eu/engys/core/controller/ScriptFactory.java b/src/eu/engys/core/controller/ScriptFactory.java new file mode 100644 index 0000000..511cf80 --- /dev/null +++ b/src/eu/engys/core/controller/ScriptFactory.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.controller; + +import java.io.File; +import java.util.List; + +import eu.engys.core.project.Model; + +public interface ScriptFactory { + + File getMeshScript(Model model); + List getDefaultMeshScript(Model model); + + File getCheckMeshScript(Model model); + List getDefaultCheckMeshScript(Model model); + + File getSolverScript(Model model); + List getDefaultSolverScript(Model model); + + File getInitialiseScript(Model model); + List getDefaultInitialiseScript(Model model); + + File getExtrudeScript(Model model); + List getDefaultExtrudeScript(Model model); + + void deleteMeshScripts(Model model); + + File getQueueDriver(Model model); + List getDefaultQueueDriver(Model model); + + File getQueueLauncher(Model model); + List getDefaultQueueLauncher(Model model); + + File getExportScript(Model model); + List getDefaultExportScript(Model model); + +} diff --git a/src/eu/engys/core/controller/Server.java b/src/eu/engys/core/controller/Server.java new file mode 100644 index 0000000..8dfbff2 --- /dev/null +++ b/src/eu/engys/core/controller/Server.java @@ -0,0 +1,69 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.util.List; + +import eu.engys.core.controller.actions.StopCommandInfo; +import eu.engys.core.project.state.ServerState; + +public interface Server extends Remote, ParsersManager { + + void heartBeat() throws RemoteException; + + CommandInfo executeCommand(ClientServerCommand command) throws RemoteException; + + StopCommandInfo stopCommand(Command command) throws RemoteException; + + CommandInfo killCommand(Command command) throws RemoteException; + + StateConnector getStateConnector() throws RemoteException; + + ILogServer getLogConnector() throws RemoteException; + + QueueConnector getQueueConnector() throws RemoteException; + + List getStates() throws RemoteException; + + ServerInfo start() throws Exception; + + void stop() throws RemoteException; + + void shutdown() throws RemoteException; + + String test() throws RemoteException; + + void disconnect() throws RemoteException; + + QueueInfo getQueueInfo() throws RemoteException; + + void goToBatch() throws RemoteException; + + void connect(ClientInfo clientInfo) throws RemoteException; + +} diff --git a/src/eu/engys/core/controller/ServerInfo.java b/src/eu/engys/core/controller/ServerInfo.java new file mode 100644 index 0000000..f5ffb23 --- /dev/null +++ b/src/eu/engys/core/controller/ServerInfo.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.util.Scanner; + +public class ServerInfo { + + public boolean success; + public String message; + public int port1; + public int port2; + public String date; + public String id; + + public void decodePorts(String payload) { + if (payload != null && !payload.isEmpty()) { + Scanner scanner = new Scanner(payload); + String date = scanner.hasNextLine() ? scanner.nextLine() : ""; + this.port1 = scanner.hasNextInt() ? scanner.nextInt() : 0; + this.port2 = scanner.hasNextInt() ? scanner.nextInt() : 0; + scanner.close(); + } + } + + @Override + public String toString() { + return "ServerInfo - ID: " + id + ", msg: " + message + ", port1: " + port1 + ", port2: " + port2 + ", succes: " + success + "date: " + date; + } +} diff --git a/src/eu/engys/core/controller/StateConnector.java b/src/eu/engys/core/controller/StateConnector.java new file mode 100644 index 0000000..59d1d29 --- /dev/null +++ b/src/eu/engys/core/controller/StateConnector.java @@ -0,0 +1,38 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import java.io.Serializable; + +import eu.engys.core.project.state.ServerState; + +public interface StateConnector extends Serializable { + + void offer(ServerState serverState); + ServerState take(); + ServerState peek(); + +} diff --git a/src/eu/engys/core/controller/StopOrKillCommandOS.java b/src/eu/engys/core/controller/StopOrKillCommandOS.java new file mode 100644 index 0000000..7110cdb --- /dev/null +++ b/src/eu/engys/core/controller/StopOrKillCommandOS.java @@ -0,0 +1,59 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import static eu.engys.core.controller.AbstractController.CANCEL; +import static eu.engys.core.controller.AbstractController.KILL_SOLVER; +import static eu.engys.core.controller.AbstractController.STOP_SOLVER; + +import javax.swing.JOptionPane; + +import eu.engys.core.controller.actions.TimeoutException; +import eu.engys.util.ui.UiUtil; + +public class StopOrKillCommandOS implements Runnable { + + private Controller controller; + + public StopOrKillCommandOS(Controller controller) { + this.controller = controller; + } + + @Override + public void run() { + Object[] options = new Object[] { STOP_SOLVER, KILL_SOLVER, CANCEL }; + int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Select an action to perform.", STOP_SOLVER, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); + if (option == JOptionPane.YES_OPTION) { + try { + controller.stopCase(); + } catch (TimeoutException e) { + // should never pass here + } + } else if (option == JOptionPane.NO_OPTION) { + controller.kill(); + } + } +} diff --git a/src/eu/engys/core/controller/View3DOptions.java b/src/eu/engys/core/controller/View3DOptions.java new file mode 100644 index 0000000..f1e380a --- /dev/null +++ b/src/eu/engys/core/controller/View3DOptions.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller; + +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JPanel; + +import eu.engys.util.filechooser.gui.Options; +import eu.engys.util.ui.builder.PanelBuilder; + +public class View3DOptions implements Options { + + private JCheckBox loadMesh = new JCheckBox("Display Mesh After Reading", true); + + @Override + public void onSelectionChanged() { + } + + @Override + public JPanel getPanel() { + PanelBuilder builder = new PanelBuilder(); + builder.addLeft(loadMesh); + builder.getPanel().setBorder(BorderFactory.createTitledBorder("Display Options")); + return builder.getPanel(); + } + + public boolean loadMesh() { + return loadMesh.isSelected(); + } + +} diff --git a/src/eu/engys/core/controller/actions/AbstractRunCommand.java b/src/eu/engys/core/controller/actions/AbstractRunCommand.java new file mode 100644 index 0000000..7f7e23f --- /dev/null +++ b/src/eu/engys/core/controller/actions/AbstractRunCommand.java @@ -0,0 +1,94 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import java.util.concurrent.ExecutorService; + +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.Server; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.ExecutorTerminal; +import eu.engys.core.project.Model; + +public abstract class AbstractRunCommand implements RunCommand { + + protected Model model; + protected Executor executor; + protected Controller controller; + protected ExecutorService service; + protected ExecutorTerminal terminal; + + public AbstractRunCommand(Model model, Controller controller) { + this.model = model; + this.controller = controller; + } + + @Override + public void inService(ExecutorService service) { + this.service = service; + } + + @Override + public void inTerminal(ExecutorTerminal terminal) { + this.terminal = terminal; + } + + @Override + public boolean isRunning() { + return executor != null && executor.getState().isDoingSomething(); + } + + @Override + public void kill() { + executor.getService().shutdownNow(); + } + + @Override + public void beforeExecute() { + } + + @Override + public void stop() throws TimeoutException { + } + + @Override + public void executeClient() { + } + + @Override + public void executeServer(Server server) throws CommandException { + } + + @Override + public String executeQueue(Server server) throws CommandException { + return null; + } + + @Override + public void executeBatch() { + } + +} diff --git a/src/eu/engys/core/controller/actions/CheckMesh.java b/src/eu/engys/core/controller/actions/CheckMesh.java new file mode 100644 index 0000000..c844f55 --- /dev/null +++ b/src/eu/engys/core/controller/actions/CheckMesh.java @@ -0,0 +1,88 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; +import static eu.engys.core.project.openFOAMProject.LOG; + +import java.io.File; +import java.nio.file.Paths; + +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.Controller.OpenOptions; +import eu.engys.core.controller.ScriptFactory; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.ExecutorHook; +import eu.engys.core.executor.ExecutorListener.ExecutorState; +import eu.engys.core.executor.ExecutorMonitor; +import eu.engys.core.executor.ExecutorTerminal; +import eu.engys.core.executor.TerminalExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.util.IOUtils; + +public class CheckMesh extends AbstractRunCommand { + + public static final String ACTION_NAME = "Check Mesh"; + public static final String LOG_NAME = "checkMesh.log"; + + private File logFile; + private ScriptFactory scriptFactory; + + public CheckMesh(Model model, Controller controller, ScriptFactory scriptFactory) { + super(model, controller); + this.scriptFactory = scriptFactory; + this.logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, LOG_NAME).toFile(); + } + + @Override + public void beforeExecute() { + IOUtils.clearFile(logFile); + if (controller.getListener() != null) { + controller.getListener().beforeCheckMesh(); + } + } + + @Override + public void executeClient() { + ExecutorTerminal terminal = new TerminalExecutorMonitor(logFile); + ExecutorMonitor monitor = new ExecutorMonitor(); + monitor.addHook(ExecutorState.FINISH, new FinishHook()); + + this.executor = Executor.script(scriptFactory.getCheckMeshScript(model)).description(ACTION_NAME).inFolder(model.getProject().getBaseDir()).inTerminal(terminal).withMonitors(monitor).env(getEnvironment(model, LOG_NAME)).keepFileOnEnd(); + executor.exec(); + } + + private class FinishHook implements ExecutorHook { + + @Override + public void run(ExecutorMonitor monitor) { + if (controller.getListener() != null) { + controller.reopenCase(OpenOptions.MESH_ONLY); + controller.getListener().afterCheckMesh(); + } + } + } +} diff --git a/src/eu/engys/core/controller/actions/CommandException.java b/src/eu/engys/core/controller/actions/CommandException.java new file mode 100644 index 0000000..707ea9b --- /dev/null +++ b/src/eu/engys/core/controller/actions/CommandException.java @@ -0,0 +1,34 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +public class CommandException extends Exception { + + public CommandException(String message) { + super(message); + } + +} diff --git a/src/eu/engys/core/controller/actions/DeleteMesh.java b/src/eu/engys/core/controller/actions/DeleteMesh.java new file mode 100644 index 0000000..e2b0c31 --- /dev/null +++ b/src/eu/engys/core/controller/actions/DeleteMesh.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; + +public class DeleteMesh extends AbstractRunCommand { + + public DeleteMesh(Model model, Controller controller) { + super(model, controller); + } + + @Override + public void executeClient() { + model.getProject().getZeroFolder().deleteMesh(); + } + +} diff --git a/src/eu/engys/core/controller/actions/InitialiseFields.java b/src/eu/engys/core/controller/actions/InitialiseFields.java new file mode 100644 index 0000000..94f32cf --- /dev/null +++ b/src/eu/engys/core/controller/actions/InitialiseFields.java @@ -0,0 +1,69 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import static eu.engys.core.project.openFOAMProject.LOG; + +import java.io.File; +import java.nio.file.Paths; + +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.ScriptFactory; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.zero.ZeroFileManager; +import eu.engys.util.IOUtils; + +public class InitialiseFields extends AbstractRunCommand { + + public static final String ACTION_NAME = "Initialise Fields"; + public static final String LOG_NAME = "initialise.log"; + + protected ScriptFactory scriptFactory; + + public InitialiseFields(Model model, Controller controller, ScriptFactory scriptFactory) { + super(model, controller); + this.scriptFactory = scriptFactory; + } + + @Override + public void beforeExecute() { + IOUtils.clearFile(Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, LOG_NAME).toFile()); + clearLogFolder(); + clearPolyMesh(); + } + + private void clearLogFolder() { + File log = new File(model.getProject().getBaseDir(), openFOAMProject.LOG); + if (!log.exists()) + log.mkdir(); + } + + private void clearPolyMesh() { + ((ZeroFileManager) model.getProject().getZeroFolder().getFileManager()).removeNonZeroDirs("0"); + } + +} diff --git a/src/eu/engys/core/controller/actions/NamingConvention.java b/src/eu/engys/core/controller/actions/NamingConvention.java new file mode 100644 index 0000000..baf8d0d --- /dev/null +++ b/src/eu/engys/core/controller/actions/NamingConvention.java @@ -0,0 +1,35 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import eu.engys.core.project.geometry.Surface; + +public interface NamingConvention { + + String getPatchName(Surface surface); + + String getCellZoneName(Surface surface); +} diff --git a/src/eu/engys/core/controller/actions/RunCase.java b/src/eu/engys/core/controller/actions/RunCase.java new file mode 100644 index 0000000..05bbd68 --- /dev/null +++ b/src/eu/engys/core/controller/actions/RunCase.java @@ -0,0 +1,134 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import static eu.engys.core.project.system.ControlDict.CONTROL_DICT; +import static eu.engys.core.project.system.ControlDict.END_TIME_KEY; +import static eu.engys.core.project.system.ControlDict.STOP_AT_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_NOW_KEY; + +import java.io.File; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.Command; +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.ScriptFactory; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.executor.ExecutorHook; +import eu.engys.core.executor.ExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.core.project.SolverState; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.state.ServerState; +import eu.engys.core.project.system.ControlDict; +import eu.engys.util.PrefUtil; + +public class RunCase extends AbstractRunCommand { + + private static final Logger logger = LoggerFactory.getLogger(RunCase.class); + + public static final String ACTION_NAME = "Run Case"; + public static final String RUNNING_LABEL = "Running: "; + + protected final ScriptFactory scriptFactory; + + public RunCase(Model model, Controller controller, ScriptFactory scriptFactory) { + super(model, controller); + this.scriptFactory = scriptFactory; + } + + @Override + public void beforeExecute() { + setupLogFolder(); + setupPostProcFolder(); + clearPolyMesh(); + setStopAtVariableToEndTime(); + } + + private void setupLogFolder() { + File log = new File(model.getProject().getBaseDir(), openFOAMProject.LOG); + if (!log.exists()) + log.mkdir(); + } + + private void setupPostProcFolder() { + File log = new File(model.getProject().getBaseDir(), openFOAMProject.POST_PROC); + if (!log.exists()) + log.mkdir(); + } + + private void clearPolyMesh() { + model.getProject().getZeroFolder().removeNonZeroTimeFolders_GreaterThanActualTimeStep(); + } + + @Override + public void stop() throws TimeoutException { + int stop_refresh_time = PrefUtil.getInt(PrefUtil.SERVER_CONNECTION_REFRESH_TIME, 1000); + int stop_max_tries = PrefUtil.getInt(PrefUtil.SERVER_CONNECTION_MAX_TRIES, 60); + + int tryIndex = 0; + while (this.executor.getState().isDoingSomething() && (tryIndex < stop_max_tries)) { + try { + Thread.sleep(stop_refresh_time); + } catch (Exception e) { + } + setStopAtVariableToWriteNow(); + tryIndex++; + } + if (tryIndex >= stop_max_tries) { + throw new TimeoutException("Timeout stopping solver"); + } + setStopAtVariableToEndTime(); + } + + private void setStopAtVariableToWriteNow() { + File systemFolder = model.getProject().getSystemFolder().getFileManager().getFile(); + ControlDict controlDict = new ControlDict(new File(systemFolder, CONTROL_DICT)); + controlDict.add(STOP_AT_KEY, WRITE_NOW_KEY); + controlDict.functionObjectsToList(); + DictionaryUtils.writeDictionary(systemFolder, controlDict, null); + } + + private void setStopAtVariableToEndTime() { + File systemFolder = model.getProject().getSystemFolder().getFileManager().getFile(); + ControlDict controlDict = new ControlDict(new File(systemFolder, CONTROL_DICT)); + if (controlDict.found(STOP_AT_KEY) && controlDict.lookup(STOP_AT_KEY).equals(WRITE_NOW_KEY)) { + controlDict.add(STOP_AT_KEY, END_TIME_KEY); + controlDict.functionObjectsToList(); + DictionaryUtils.writeDictionary(systemFolder, controlDict, null); + } + } + + protected class StartHook implements ExecutorHook { + @Override + public void run(ExecutorMonitor m) { + model.getSolverModel().writeState(new ServerState(Command.RUN_CASE, SolverState.RUNNING), model); + } + } + +} diff --git a/src/eu/engys/core/controller/actions/RunCommand.java b/src/eu/engys/core/controller/actions/RunCommand.java new file mode 100644 index 0000000..7e45ed2 --- /dev/null +++ b/src/eu/engys/core/controller/actions/RunCommand.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import java.util.concurrent.ExecutorService; + +import eu.engys.core.controller.Server; +import eu.engys.core.executor.ExecutorTerminal; + +public interface RunCommand { + + public void beforeExecute(); + + public void executeClient(); + + public void executeBatch(); + + public void executeServer(Server server) throws CommandException; + + public String executeQueue(Server server) throws CommandException; + + public void stop() throws TimeoutException; + + public void kill(); + + public void inService(ExecutorService service); + + public void inTerminal(ExecutorTerminal terminal); + + public boolean isRunning(); + +} diff --git a/src/eu/engys/core/controller/actions/RunMesh.java b/src/eu/engys/core/controller/actions/RunMesh.java new file mode 100644 index 0000000..cbfebd9 --- /dev/null +++ b/src/eu/engys/core/controller/actions/RunMesh.java @@ -0,0 +1,74 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import static eu.engys.core.project.openFOAMProject.LOG; + +import java.io.File; +import java.nio.file.Paths; + +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.ScriptFactory; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.util.IOUtils; + +public class RunMesh extends AbstractRunCommand { + + public static final String ACTION_NAME = "Create Mesh"; + public static final String LOG_NAME = "snappyHexMesh.log"; + + protected final ScriptFactory scriptFactory; + + public RunMesh(Model model, Controller controller, ScriptFactory scriptFactory) { + super(model, controller); + this.scriptFactory = scriptFactory; + } + + @Override + public void beforeExecute() { + IOUtils.clearFile(Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, LOG_NAME).toFile()); + clearPolyMesh(); + setupLogFolder(); + fixDecomposeParDict(model); + } + + private void fixDecomposeParDict(Model model) { + model.getProject().getSystemFolder().getDecomposeParDict().toHierarchical(model); + } + + private void clearPolyMesh() { + model.getProject().getZeroFolder().deleteMesh(); + } + + private void setupLogFolder() { + File log = new File(model.getProject().getBaseDir(), openFOAMProject.LOG); + if (!log.exists()) { + log.mkdir(); + } + } + +} diff --git a/src/eu/engys/core/controller/actions/StandardInitialiseFields.java b/src/eu/engys/core/controller/actions/StandardInitialiseFields.java new file mode 100644 index 0000000..0cb18c8 --- /dev/null +++ b/src/eu/engys/core/controller/actions/StandardInitialiseFields.java @@ -0,0 +1,80 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; + +import java.io.File; +import java.nio.file.Paths; +import java.util.concurrent.ExecutorService; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.Controller.OpenOptions; +import eu.engys.core.controller.ScriptFactory; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.ExecutorHook; +import eu.engys.core.executor.ExecutorListener.ExecutorState; +import eu.engys.core.executor.ExecutorMonitor; +import eu.engys.core.executor.ExecutorTerminal; +import eu.engys.core.executor.TerminalExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; + +public class StandardInitialiseFields extends InitialiseFields { + + private static final Logger logger = LoggerFactory.getLogger(StandardInitialiseFields.class); + + public StandardInitialiseFields(Model model, Controller controller, ScriptFactory scriptFactory) { + super(model, controller, scriptFactory); + } + + @Override + public void executeClient() { + logger.debug("EXECUTE IN CLIENT"); + File script = scriptFactory.getInitialiseScript(model); + File baseDir = model.getProject().getBaseDir(); + File logFile = Paths.get(baseDir.getAbsolutePath(), openFOAMProject.LOG, LOG_NAME).toFile(); + + ExecutorTerminal terminal = new TerminalExecutorMonitor(logFile); + ExecutorMonitor monitor = new ExecutorMonitor(); + ExecutorService service = Executor.newExecutor(ACTION_NAME); + monitor.addHook(ExecutorState.FINISH, new FinishHook()); + + this.executor = Executor.script(script).description(ACTION_NAME).inFolder(baseDir).inTerminal(terminal).withMonitors(monitor).inService(service).env(getEnvironment(model, LOG_NAME)).keepFileOnEnd(); + executor.exec(); + } + + private class FinishHook implements ExecutorHook { + @Override + public void run(ExecutorMonitor m) { + controller.reopenCase(OpenOptions.CURRENT_SETTINGS); + } + } + +} diff --git a/src/eu/engys/core/controller/actions/StandardRunCase.java b/src/eu/engys/core/controller/actions/StandardRunCase.java new file mode 100644 index 0000000..fb18cca --- /dev/null +++ b/src/eu/engys/core/controller/actions/StandardRunCase.java @@ -0,0 +1,108 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; + +import java.io.File; +import java.nio.file.Paths; +import java.util.concurrent.ExecutorService; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.Command; +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.ScriptFactory; +import eu.engys.core.controller.StopOrKillCommandOS; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.ExecutorHook; +import eu.engys.core.executor.ExecutorListener.ExecutorState; +import eu.engys.core.executor.ExecutorMonitor; +import eu.engys.core.executor.TerminalExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.core.project.SolverState; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.state.ServerState; + +public class StandardRunCase extends RunCase { + + private static final Logger logger = LoggerFactory.getLogger(StandardRunCase.class); + + public StandardRunCase(Model model, Controller controller, ScriptFactory scriptFactory) { + super(model, controller, scriptFactory); + } + + @Override + public void executeClient() { + logger.debug("EXECUTE IN CLIENT"); + File logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), openFOAMProject.LOG, model.getSolverModel().getLogFile()).toFile(); + TerminalExecutorMonitor terminal = new TerminalExecutorMonitor(logFile); + terminal.setStopCommand(new StopOrKillCommandOS(controller)); + + ExecutorMonitor monitor = new ExecutorMonitor(); + monitor.addHook(ExecutorState.START, new StartHook()); + monitor.addHook(ExecutorState.RUNNING, new RunningHook()); + monitor.addHook(ExecutorState.FINISH, new FinishHook()); + monitor.addHook(ExecutorState.ERROR, new ErrorHook()); + + ExecutorService service = Executor.newExecutor(ACTION_NAME); + + File baseDir = model.getProject().getBaseDir(); + + this.executor = Executor.script(scriptFactory.getSolverScript(model)).description(ACTION_NAME).inFolder(baseDir).inTerminal(terminal).withMonitors(monitor).inService(service).env(getEnvironment(model, model.getSolverModel().getLogFile())).keepFileOnEnd(); + executor.exec(); + } + + private class StartHook implements ExecutorHook { + @Override + public void run(ExecutorMonitor m) { + model.getSolverModel().setServerState(new ServerState(Command.RUN_CASE, SolverState.STARTED)); + } + } + + private class RunningHook implements ExecutorHook { + @Override + public void run(ExecutorMonitor m) { + model.getSolverModel().setServerState(new ServerState(Command.RUN_CASE, SolverState.RUNNING)); + } + } + + protected class FinishHook implements ExecutorHook { + @Override + public void run(ExecutorMonitor m) { + model.getSolverModel().setServerState(new ServerState(Command.RUN_CASE, SolverState.FINISHED)); + } + } + + protected class ErrorHook implements ExecutorHook { + @Override + public void run(ExecutorMonitor m) { + model.getSolverModel().setServerState(new ServerState(Command.RUN_CASE, SolverState.ERROR)); + } + } + +} diff --git a/src/eu/engys/core/controller/actions/StandardRunMesh.java b/src/eu/engys/core/controller/actions/StandardRunMesh.java new file mode 100644 index 0000000..498ce38 --- /dev/null +++ b/src/eu/engys/core/controller/actions/StandardRunMesh.java @@ -0,0 +1,77 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; + +import java.io.File; +import java.nio.file.Paths; +import java.util.concurrent.ExecutorService; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.ScriptFactory; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.ExecutorHook; +import eu.engys.core.executor.ExecutorListener.ExecutorState; +import eu.engys.core.executor.ExecutorMonitor; +import eu.engys.core.executor.TerminalExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; + +public class StandardRunMesh extends RunMesh { + + private static final Logger logger = LoggerFactory.getLogger(StandardRunMesh.class); + + public StandardRunMesh(Model model, Controller controller, ScriptFactory scriptFactory) { + super(model, controller, scriptFactory); + } + + @Override + public void executeClient() { + logger.debug("EXECUTE IN CLIENT"); + File baseDir = model.getProject().getBaseDir(); + File logFile = Paths.get(baseDir.getAbsolutePath(), openFOAMProject.LOG, LOG_NAME).toFile(); + + ExecutorMonitor monitor = new ExecutorMonitor(); + monitor.addHook(ExecutorState.FINISH, new FinishHook()); + + ExecutorService service = Executor.newExecutor(ACTION_NAME); + + this.executor = Executor.script(scriptFactory.getMeshScript(model)).description(ACTION_NAME).inFolder(baseDir).inService(service).inTerminal(new TerminalExecutorMonitor(logFile)).withMonitors(monitor).env(getEnvironment(model, LOG_NAME)).keepFileOnEnd(); + executor.exec(); + } + + private class FinishHook implements ExecutorHook { + @Override + public void run(ExecutorMonitor m) { + controller.setupCase(); + } + } + +} diff --git a/src/eu/engys/core/controller/actions/StopCommandInfo.java b/src/eu/engys/core/controller/actions/StopCommandInfo.java new file mode 100644 index 0000000..76a1664 --- /dev/null +++ b/src/eu/engys/core/controller/actions/StopCommandInfo.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.CommandInfo; + +public class StopCommandInfo extends CommandInfo { + + private static final Logger logger = LoggerFactory.getLogger(StopCommandInfo.class); + + public boolean timeout; + + public static StopCommandInfo wrap(CommandInfo info) { + StopCommandInfo ci = new StopCommandInfo(); + ci.message = info.message; + ci.exception = info.exception; + ci.success = info.success; + ci.timeout = false; + return ci; + } + + public static StopCommandInfo timeoutException(Exception e) { + logger.error(">>> SERVER STOP ERROR", e); + StopCommandInfo ci = new StopCommandInfo(); + ci.message = "Timeout"; + ci.exception = e; + ci.success = false; + ci.timeout = true; + return ci; + } + + @Override + public String toString() { + return "Stop Command [success: " + success + "] - [timeout: " + timeout + "] - [message: " + message + "] - [exception: " + exception.getMessage() + "]"; + } + +} diff --git a/src/eu/engys/core/controller/actions/TimeoutException.java b/src/eu/engys/core/controller/actions/TimeoutException.java new file mode 100644 index 0000000..66a8ae3 --- /dev/null +++ b/src/eu/engys/core/controller/actions/TimeoutException.java @@ -0,0 +1,34 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.controller.actions; + +public class TimeoutException extends Exception { + + public TimeoutException(String message) { + super(message); + } + +} diff --git a/src/eu/engys/core/dictionary/BeanToDict.java b/src/eu/engys/core/dictionary/BeanToDict.java new file mode 100644 index 0000000..c27988a --- /dev/null +++ b/src/eu/engys/core/dictionary/BeanToDict.java @@ -0,0 +1,274 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary; + +import java.io.File; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BeanToDict { + + private static final Logger logger = LoggerFactory.getLogger(BeanToDict.class); + + public static B dictToBean(Dictionary dictionary, Class klass) { + try { + B bean = klass.newInstance(); + + dictToBean(dictionary, bean); + + return bean; + } catch (Exception ex) { + ex.printStackTrace(); + return null; + } + } + + @SuppressWarnings("unchecked") + public static void dictToBean(Dictionary dictionary, B bean) { + Method[] methods = bean.getClass().getMethods(); + for (Method m : methods) { + if (m.getName().startsWith("set")) { + String fieldName = getFieldNameFromSetter(m); + if (dictionary.found(fieldName)) { + if (dictionary.isField(fieldName)) { + String value = dictionary.lookup(fieldName); + Class param = m.getParameterTypes()[0]; + if (param.equals(double.class)) { + setValue(bean, m, Double.valueOf(value)); + } else if (param.equals(long.class)) { + setValue(bean, m, Long.valueOf(value)); + } else if (param.equals(int.class)) { + setValue(bean, m, Integer.valueOf(value)); + } else if (param.equals(boolean.class)) { + setValue(bean, m, Boolean.valueOf(value)); + } else if (param.equals(String.class)) { + setValue(bean, m, value); + } else if (param.isEnum()) { + try { + setValue(bean, m, Enum.valueOf((Class) param, value)); + } catch (Exception e) { + setValue(bean, m, ((Class) param).getEnumConstants()[0]); + } + } else { + System.err.println("ERROR: " + param); + logger.error(""); + } + } else if (dictionary.isDictionary(fieldName)) { + Class class1 = m.getParameterTypes()[0]; + Object bean1 = dictToBean(dictionary.subDict(fieldName), class1); + setValue(bean, m, bean1); + } + + } + } + } + } + + private static void setValue(B bean, Method m, Object value) { + try { + m.invoke(bean, value); + } catch (Exception e) { + logger.error("ERROR: double parameter", e); + } + } + + // public static void dictToBean(Dictionary dictionary, Object bean) { + // Method[] methods = bean.getClass().getMethods(); + // try { + // for (Method m : methods) { + // if (m.getName().startsWith("set")) { + // String fieldName = getFieldNameFromSetter(m); + // if (dictionary.isField(fieldName)) { + // String value = dictionary.lookup(fieldName); + // m.invoke(bean, Double.valueOf(value)); + // } + // } + // } + // } catch(Exception ex) { + // ex.printStackTrace(); + // } + // } + + public static Dictionary beanToDict(Object obj) { + return beanToDict(null, obj); + } + + public static Dictionary beanToDict(String name, Object obj) { + Class klass = obj.getClass(); + Method[] methods = klass.getMethods(); + Dictionary dictionary = new Dictionary(name != null ? name : getFieldNameFromClass(klass)); + // dictionary.add("class", obj.getClass().getName()); + + for (Method m : methods) { + String fieldName = ""; + if (m.getName().startsWith("get") && !m.getName().startsWith("getClass")) { + fieldName = getFieldNameFromGetter(m); + } else if (m.getName().startsWith("is")) { + fieldName = getFieldNameFromBooleanGetter(m); + } else { + continue; + } + try { + Object value = m.invoke(obj); + if (value != null) { + addToDictionary(dictionary, fieldName, value); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return dictionary; + } + + private static void addToDictionary(Dictionary dictionary, String fieldName, Object value) throws Exception { + if (isSimple(value.getClass())) { + dictionary.add(fieldName, value.toString()); + } else if (isList(value)) { + dictionary.add(toList(fieldName, value)); + } else if (isArray(value)) { + dictionary.add(fieldName, toArray(value)); + } else if (isMap(value)) { + dictionary.add(mapToDict(fieldName, value)); + } else if (isFile(value)) { + dictionary.add(fieldName, ((File) value).getAbsolutePath()); + } else if (isDictionary(value)) { + Dictionary d = new Dictionary((Dictionary) value); + d.setName(fieldName); + dictionary.add(d); + } else { + dictionary.add(beanToDict(fieldName, value)); + } + } + + private static boolean isSimple(Class klass) { + boolean isString = String.class.isAssignableFrom(klass); + boolean isNumber = Number.class.isAssignableFrom(klass); + boolean isBoolean = Boolean.class.isAssignableFrom(klass); + boolean isEnum = Enum.class.isAssignableFrom(klass); + boolean isPrimitive = klass.isPrimitive(); + return isString || isNumber || isBoolean || isEnum || isPrimitive; + } + + private static boolean isList(Object value) { + return List.class.isAssignableFrom(value.getClass()) || (value.getClass().isArray() && !isSimple(value.getClass().getComponentType())); + } + + private static boolean isMap(Object value) { + return Map.class.isAssignableFrom(value.getClass()); + } + + private static boolean isFile(Object value) { + return File.class.isAssignableFrom(value.getClass()); + } + + private static boolean isDictionary(Object value) { + return Dictionary.class.isAssignableFrom(value.getClass()); + } + + private static boolean isArray(Object value) { + return value.getClass().isArray(); + } + + private static ListField toList(String name, Object value) throws Exception { + ListField listField = new ListField(name); + List list = null; + if (value.getClass().isArray()) { + list = Arrays.asList((Object[]) value); + } else { + list = (List) value; + } + for (Object obj : list) { + listField.add(beanToDict(obj)); + } + return listField; + } + + public static Dictionary mapToDict(String name, Object value) { + Map map = (Map) value; + Dictionary dict = new Dictionary(name); + try { + for (Object key : map.keySet()) { + addToDictionary(dict, key.toString(), map.get(key)); + } + } catch (Exception ex) { + + } + return dict; + } + + private static String toArray(Object array) throws Exception { + return toBracketedArrayOfStrings(array); + } + + private static String toBracketedArrayOfStrings(Object array) { + StringBuilder sb = new StringBuilder(); + sb.append("("); + for (int i = 0; i < Array.getLength(array); i++) { + sb.append(" "); + sb.append(Array.get(array, i).toString()); + } + sb.append(")"); + + return sb.toString(); + } + + private static String getFieldNameFromGetter(Method m) { + String name = m.getName().substring(3); + return name.substring(0, 1).toLowerCase() + name.substring(1); + } + + private static String getFieldNameFromBooleanGetter(Method m) { + String name = m.getName().substring(2); + return name.substring(0, 1).toLowerCase() + name.substring(1); + } + + private static String getFieldNameFromSetter(Method m) { + String name = m.getName().substring(3); + return name.substring(0, 1).toLowerCase() + name.substring(1); + } + + static private String getFieldNameFromClass(Class klass) { + String name = klass.getSimpleName(); + return name.substring(0, 1).toLowerCase() + name.substring(1); + } + + // private Method getSetterFromFieldName(String name, Class klass) throws Exception { + // String methodName = name.substring(0,1).toUpperCase()+name.substring(1); + // methodName = "set"+methodName; + // return klass.getMethod(methodName); + // } + // + // private static Class getClassFromFieldName(String name) throws ClassNotFoundException{ + // String className = name.substring(0,1).toUpperCase()+name.substring(1); + // return Class.forName(className); + // } +} diff --git a/src/eu/engys/core/dictionary/BlockMeshWriter.java b/src/eu/engys/core/dictionary/BlockMeshWriter.java new file mode 100644 index 0000000..6670671 --- /dev/null +++ b/src/eu/engys/core/dictionary/BlockMeshWriter.java @@ -0,0 +1,120 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import static eu.engys.core.dictionary.Dictionary.SPACER; +import static eu.engys.core.dictionary.Dictionary.TAB; +import static eu.engys.core.dictionary.Dictionary.VERBOSE; +import eu.engys.core.dictionary.parser.ListField2; + +public class BlockMeshWriter extends DictionaryWriter { + + + public BlockMeshWriter(Dictionary dictionary) { + super(dictionary); + } + + public String write() { + StringBuffer sb = new StringBuffer(); + writeDictionary(sb, ""); + return sb.toString(); + } + + public void writeDictionary(StringBuffer sb, String rowHeader) { + if (dictionary.getFoamFile() != null) { + sb.append(FoamFile.HEADER); + BlockMeshWriter writer = new BlockMeshWriter(dictionary.getFoamFile()); + writer.writeDictionary(sb, ""); + +// if (dictionary.isList("")) { +// ListField.class.cast(dictionary.getList()).writeListDict(sb, rowHeader); +// return; +// } + } else { + sb.append("\n"); + sb.append(rowHeader); + sb.append(dictionary.getName()); + sb.append("\n"); + sb.append(rowHeader); + sb.append(START); + } + for (String key : dictionary.getKeys()) { + DefaultElement ele = dictionary.getElement(key); + write(sb, rowHeader, ele); + } + + for (String includeFile : dictionary.getIncludeFiles()) { + writeInclude(sb, includeFile, rowHeader); + } + + if (dictionary.getFoamFile() == null) + sb.append("\n" + rowHeader + END); + } + + private void write(StringBuffer sb, String rowHeader, DefaultElement ele) { + if (ele instanceof Dictionary) { + BlockMeshWriter writer = new BlockMeshWriter((Dictionary) ele); + writer.writeDictionary(sb, rowHeader + TAB); + } else if (ele instanceof DimensionedScalar) { + writeDimensionedScalar(sb, (DimensionedScalar) ele, rowHeader); + } else if (ele instanceof ListField2) { + ListField2.class.cast(ele).writeListField(sb, rowHeader); + } else if (ele instanceof ListField) { + ListField.class.cast(ele).writeListField(sb, rowHeader); + } else { + super.writeField(sb, (FieldElement) ele, rowHeader); + } + } + + @Override + protected void writeInclude(StringBuffer sb, String includeFile, String rowHeader) { + if (VERBOSE) + System.out.println("Dictionary.writeInclude() " + includeFile); + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append("#include"); + sb.append(SPACER); + sb.append(includeFile); + } + + private static void writeDimensionedScalar(StringBuffer sb, DimensionedScalar ds, String rowHeader) { + if (VERBOSE) + System.out.println("Dictionary.writeDimensionedScalar() " + (ds != null ? ds.getName() : "NULL!!!")); + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(ds.getName()); + sb.append(SPACER); + sb.append(ds.getName()); + sb.append(SPACER); + sb.append(ds.getDimensions()); + sb.append(SPACER); + sb.append(ds.getValue()); + sb.append(";"); + } +} diff --git a/src/eu/engys/core/dictionary/DefaultElement.java b/src/eu/engys/core/dictionary/DefaultElement.java new file mode 100644 index 0000000..0fb3d97 --- /dev/null +++ b/src/eu/engys/core/dictionary/DefaultElement.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +public class DefaultElement { + + private String name; + + public DefaultElement(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof DefaultElement) { + return ((DefaultElement) obj).name.equals(name); + } + return super.equals(obj); + } +} diff --git a/src/eu/engys/core/dictionary/Dictionary.java b/src/eu/engys/core/dictionary/Dictionary.java new file mode 100644 index 0000000..3511d55 --- /dev/null +++ b/src/eu/engys/core/dictionary/Dictionary.java @@ -0,0 +1,807 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.ArrayUtils; + +import eu.engys.core.dictionary.parser.ListField2; +import eu.engys.core.dictionary.parser.ThetaListField2; + +public class Dictionary extends DefaultElement { + + public static boolean VERBOSE = false; + + public static final String SPACER = " "; + public static final String TAB = " "; + + public static final String DICTIONARY_LINK = "DICTIONARY_LINK"; + public static final String VALUE_LINK = "VALUE_LINK"; + public static final String VALUE_UNIFORM_LINK = "VALUE_UNIFORM_LINK"; + + public static final String TYPE = "type"; + public static final String VALUE = "value"; + + private FoamFile foamFile; + + private Map elements = new LinkedHashMap(); + private List keys = new ArrayList(); + private List genericKeys = new ArrayList(); + private List includeFiles = new ArrayList(); + + public Dictionary(String name, File file) { + super(name); + readDictionary(file); + } + + public Dictionary(File file) { + this(file.getName(), file); + } + + + public Dictionary(String name, InputStream input, DictionaryLinkResolver resolver) { + super(name); + readDictionary(input, resolver); + } + + public Dictionary(String name, InputStream input) { + super(name); + readDictionary(input); + } + + public Dictionary(String name) { + super(name); + } + + public Dictionary(Dictionary d) { + this(d.getName(), d); + } + + public Dictionary(String name, Dictionary d) { + super(name); + setFoamFile(d.getFoamFile()); + for (String key : d.keys) { + DefaultElement el = d.elements.get(key); + if (el instanceof Dictionary) { + add(new Dictionary((Dictionary) el)); + } else if (el instanceof DimensionedScalar) { + DimensionedScalar ds = (DimensionedScalar) el; + add(new DimensionedScalar(ds)); + } else if (el instanceof FieldElement) { + FieldElement f = (FieldElement) el; + add(f.getName(), f.getValue()); + } else if (el instanceof ListField) { + ListField lf = (ListField) el; + add(lf.getName(), new ListField(lf)); + } else if (el instanceof ThetaListField2) { + ThetaListField2 tf = (ThetaListField2) el; + add(tf.getName(), new ThetaListField2(tf)); + } else if (el instanceof ListField2) { + ListField2 lf = (ListField2) el; + add(lf.getName(), new ListField2(lf)); + } + } + genericKeys.addAll(d.genericKeys); + } + + public void setFoamFile(FoamFile file) { + if (found("FoamFile")) + remove("FoamFile"); + this.foamFile = file; + } + + public FoamFile getFoamFile() { + return foamFile; + } + + public void check() throws DictionaryException { + } + + public void include(String includeFile) { + includeFiles.add(includeFile); + } + + private void put(String key, DefaultElement value) { + elements.put(key, value); + if (!keys.contains(key)) + keys.add(key); + } + + public void add(DefaultElement el) { + put(el.getName(), el); + } + + public void addGeneric(DefaultElement el) { + String name = el.getName(); + if (!genericKeys.contains(name)) { + genericKeys.add(name); + } + put(name, el); + } + + public void add(Dictionary dictionary) { + put(dictionary.getName(), dictionary); + } + + public void addToList(Dictionary dictionary) { + addToList("", dictionary); + } + + public void addToList(String listName, Dictionary dictionary) { + ListField list = getList(listName); + if (list == null) { + list = new ListField(listName); + add(list); + } + list.add(dictionary); + } + + public void addToList(String listName, FieldElement fe) { + ListField list = getList(listName); + if (list == null) { + list = new ListField(listName); + add(list); + } + list.add(fe); + } + + public void add(String name, String value) { + put(name, new FieldElement(name, value)); + } + +// public void add(Finder finder, String value) { +// String key = findKey(finder); +// put(key, new FieldElement(key, value)); +// } + + public void addGeneric(String name, String value) { + if (!genericKeys.contains(name)) { + genericKeys.add(name); + } + put(name, new FieldElement(name, value)); + } + + public void add(String name, double[] values) { + StringBuffer sb = new StringBuffer("("); + for (double d : values) { + sb.append(String.valueOf(d) + " "); + } + sb.append(")"); + this.add(name, sb.toString()); + } + + public void add(String name, int[] values) { + StringBuffer sb = new StringBuffer("("); + for (int d : values) { + sb.append(String.valueOf(d) + " "); + } + sb.append(")"); + this.add(name, sb.toString()); + } + + public void add(String name, String[] values) { + StringBuffer sb = new StringBuffer("("); + for (String p : values) { + sb.append(p + " "); + } + sb.append(")"); + this.add(name, sb.toString()); + } + + public void add(String name, List values) { + this.add(name, values.toArray(new String[0])); + } + + public void add(DimensionedScalar ds) { + put(ds.getName(), ds); + } + + public void add(String name, ListField list) { + put(name, list); + } + + public void add(String name, ListField2 list) { + put(name, list); + } + + public void add(ListField list) { + put(list.getName(), list); + } + + private String findKey(Finder finder) { + for (String key : keys) { + if (finder.accept(key)) { + return key; + } + } + return null; + } + + public boolean found(Finder finder) { + String key = findKey(finder); + return key != null; + } + + public boolean found(String name) { + if (foundGeneric(name)) + return true; + else + return keys.contains(name); + } + + private boolean foundGeneric(String name) { + if (!genericKeys.isEmpty()) { + for (String genericKey : genericKeys) { + if (("\"" + name + "\"").matches(genericKey)) { + return true; + } + } + } + return false; + } + + DefaultElement getElement(String name) { + if (elements.containsKey(name)) + return elements.get(name); + + if (!genericKeys.isEmpty()) { + for (String genericKey : genericKeys) { + if (("\"" + name + "\"").matches(genericKey)) { + return elements.get(genericKey); + } + } + } + return null; + } + + public boolean isDictionary(String name) { + DefaultElement el = getElement(name); + return (el != null && el instanceof Dictionary); + } + + public boolean isField(String name) { + DefaultElement el = getElement(name); + return (el != null && el instanceof FieldElement); + } + + public boolean isList(String name) { + DefaultElement el = getElement(name); + return (el != null && el instanceof ListField); + } + + public boolean isList2(String name) { + DefaultElement el = getElement(name); + return (el != null && el instanceof ListField2); + } + + public boolean isThetaList2(String name) { + DefaultElement el = getElement(name); + return (el != null && el instanceof ThetaListField2); + } + + public Dictionary subDict(String name) { + DefaultElement el = getElement(name); + if (isDictionary(name)) { + return (Dictionary) el; + } else if (el != null) + throw new DictionaryException(name + " not a dictionary"); + else + return null; + } + +// public ListField getList() { +// return getList(""); +// } +// +// public ListField2 getList2() { +// return getList2(""); +// } + + public ListField getList(String name) { + DefaultElement el = getElement(name); + if (isList(name)) { + return (ListField) el; + } else if (el != null) + throw new DictionaryException(name + " not a list"); + else + return null; + } + + public ListField2 getList2(String name) { + DefaultElement el = getElement(name); + if (isList2(name)) { + return (ListField2) el; + } else if (el != null) + throw new DictionaryException(name + " not a list"); + else + return null; + } + + public ThetaListField2 getThetaList2(String name) { + DefaultElement el = getElement(name); + if (isThetaList2(name)) { + return (ThetaListField2) el; + } else if (el != null) + throw new DictionaryException(name + " not a theta list"); + else + return null; + } + + public DefaultElement lookup(Finder finder) { + String key = findKey(finder); + if (key == null) { + throw new DictionaryException("Key " + key + " is NULL"); + } + + return getElement(key); + } + + public String lookup(String key) { + return lookupString(key); + } + + public String lookupString(String key) { + if (key == null) { + throw new DictionaryException("Key " + key + " is NULL"); + } + DefaultElement el = getElement(key); + if (isField(key)) { + return ((FieldElement) el).getValue(); + } else if (el != null) + throw new DictionaryException(key + " not a field"); + else + return null; + } + + public int lookupInt(String name) { + String value = lookupString(name); + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return -1; + } + } + + public double lookupDouble(String name) { + String value = lookupString(name); + try { + return Double.parseDouble(value); + } catch (NumberFormatException e) { + return Double.NaN; + } + } + + public DimensionedScalar lookupScalar(String name) { + DefaultElement el = getElement(name); + if (el != null && el instanceof DimensionedScalar) { + return (DimensionedScalar) el; + } else if (el != null) + throw new DictionaryException(name + " not a dimensioned scalar"); + else + return null; + } + + public String[] lookupArray(String name) { + DefaultElement el = getElement(name); + if (el != null && el instanceof FieldElement) { + String value = ((FieldElement) el).getValue(); + if (value.startsWith("uniform")) { + value = value.replace("uniform", "").trim(); + } + if (value.startsWith("nonuniform")) { + return new String[] { "Infinity", "Infinity", "Infinity" }; + } + if (value.startsWith("(") && value.endsWith(")")) { + value = value.replace("(", "").replace(")", "").trim(); + // value = value.substring(1, value.length()-1); + if (value.isEmpty()) { + return new String[0]; + } + String[] values = value.split(SPACER); + // System.out.println("Dictionary.lookupArray() "+Arrays.toString(values)); + return values; + } else + throw new DictionaryException(name + " not an array"); + } else if (el != null) + throw new DictionaryException(name + " not a field"); + else + return null; + } + + public String[][] lookupMatrix(String name) { + DefaultElement el = getElement(name); + if (el != null && el instanceof FieldElement) { + String value = ((FieldElement) el).getValue(); + if (value.startsWith("uniform")) { + value = value.replace("uniform", "").trim(); + } + if (value.startsWith("(") && value.endsWith(")")) { + value = value.replaceAll("\\(\\s*\\(", ""); + value = value.replaceAll("\\)\\s*\\)", ""); + + String[] values = value.split("\\)\\s*\\("); + String[][] matrix = new String[values.length][]; + for (int r = 0; r < values.length; r++) { + String[] row = values[r].trim().split("\\s+"); + matrix[r] = row; + } + return matrix; + } else + throw new DictionaryException(name + " not an array"); + } else if (el != null) + throw new DictionaryException(name + " not a field"); + else + return null; + } + + public String[] lookupArray2(String name) { + DefaultElement el = getElement(name); + if (el != null && el instanceof ListField2) { + ListField2 list = (ListField2) el; + return listToArray(list); + } else if (el != null) + throw new DictionaryException(name + " not a field"); + else + return null; + } + + private String[] listToArray(ListField2 list) { + List elements = list.getListElements(); + + String[] values = new String[elements.size()]; + + for (int i = 0; i < elements.size(); i++) { + DefaultElement element = elements.get(i); + if (element instanceof FieldElement) { + String value = ((FieldElement) element).getValue(); + values[i] = value; + } else if (element instanceof ListField2) { + String[] listField = listToArray((ListField2) element); + values[i] = "("; + for (int j = 0; j < listField.length; j++) { + values[i] += listField[j] + " "; + } + values[i] += ")"; + } + } + return values; + } + + public String[][] lookupMatrix2(String name) { + DefaultElement el = getElement(name); + if (el != null && el instanceof ListField2) { + ListField2 list = (ListField2) el; + return listToMatrix(list); + } else if (el != null) { + throw new DictionaryException(name + " not a field"); + } else { + return null; + } + } + + private String[][] listToMatrix(ListField2 list) { + List rows = list.getListElements(); + if (rows.size() > 0 && rows.get(0) instanceof ListField2) { + ListField2 firstRow = (ListField2) rows.get(0); + String[][] values = new String[rows.size()][firstRow.getListElements().size()]; + + for (int i = 0; i < rows.size(); i++) { + if (rows.get(i) instanceof ListField2) { + ListField2 row = (ListField2) rows.get(i); + values[i] = listToArray(row); + } + } + return values; + } else { + return new String[0][0]; + } + } + + public double[] lookupDoubleArray(String name) { + String[] array = lookupArray(name); + double[] doubleArray = new double[array.length]; + for (int i = 0; i < doubleArray.length; i++) { + try { + doubleArray[i] = Double.valueOf(array[i]); + } catch (NumberFormatException e) { + } + } + return doubleArray; + } + + public double[] lookupDoubleArray2(String name) { + String[] array = lookupArray2(name); + double[] doubleArray = new double[array.length]; + for (int i = 0; i < doubleArray.length; i++) { + try { + doubleArray[i] = Double.valueOf(array[i]); + } catch (NumberFormatException e) { + } + } + return doubleArray; + } + + public double[][] lookupDoubleMatrix(String name) { + String[][] matrix = lookupMatrix(name); + double[][] doubleMatrix = new double[matrix.length][matrix[0].length]; + for (int i = 0; i < doubleMatrix.length; i++) { + for (int j = 0; j < doubleMatrix[i].length; j++) { + try { + doubleMatrix[i][j] = Double.valueOf(matrix[i][j]); + } catch (NumberFormatException e) { + } + } + } + return doubleMatrix; + } + + public double[][] lookupDoubleMatrix2(String name) { + String[][] matrix = lookupMatrix2(name); + double[][] doubleMatrix = new double[matrix.length][matrix[0].length]; + for (int i = 0; i < doubleMatrix.length; i++) { + for (int j = 0; j < doubleMatrix[i].length; j++) { + try { + doubleMatrix[i][j] = Double.valueOf(matrix[i][j]); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + } + return doubleMatrix; + } + + public int[] lookupIntArray(String name) { + String[] array = lookupArray(name); + int[] intArray = new int[array.length]; + for (int i = 0; i < intArray.length; i++) { + try { + intArray[i] = Integer.valueOf(array[i]); + } catch (NumberFormatException e) { + } + } + return intArray; + } + + public Dictionary removeDict(String name) { + keys.remove(name); + return (Dictionary) elements.remove(name); + } + + public DefaultElement remove(String name) { + keys.remove(name); + return elements.remove(name); + } + + public DefaultElement remove(Finder finder) { + String key = findKey(finder); + return remove(key); + } + + List getGenericKeys() { + return genericKeys; + } + + List getKeys() { + return keys; + } + + List getIncludeFiles() { + return includeFiles; + } + + public boolean isEmpty() { + return keys.isEmpty(); + } + + @Override + public String toString() { + return new DictionaryWriter(this).write(); + } + + public List getDictionaries() { + List list = new ArrayList(); + for (String key : keys) { + DefaultElement el = elements.get(key); + if (el instanceof Dictionary) { + list.add((Dictionary) el); + } + } + return list; + } + + public Map getDictionariesMap() { + Map map = new LinkedHashMap(); + for (String key : keys) { + DefaultElement el = elements.get(key); + if (el instanceof Dictionary) { + map.put(el.getName(), (Dictionary) el); + } + } + return map; + } + + public List getFields() { + List list = new ArrayList(); + for (DefaultElement el : elements.values()) { + if (el instanceof FieldElement) { + list.add((FieldElement) el); + } + } + return list; + } + + public List getListFields() { + List list = new ArrayList<>(); + for (DefaultElement el : elements.values()) { + if (el instanceof ListField) { + list.add((ListField) el); + } + } + return list; + } + + public boolean hasOnlyList(){ + return !getListFields().isEmpty() && getDictionaries().isEmpty() && getFieldsMap().isEmpty(); + } + + public boolean hasOnlyList2(){ + return !getListFields2().isEmpty() && getDictionaries().isEmpty() && getFieldsMap().isEmpty(); + } + + public List getListFields2() { + List list = new ArrayList<>(); + for (DefaultElement el : elements.values()) { + if (el instanceof ListField2) { + list.add((ListField2) el); + } + } + return list; + } + + public Map getFieldsMap() { + Map map = new LinkedHashMap(); + for (DefaultElement el : elements.values()) { + if (el instanceof FieldElement) { + FieldElement field = (FieldElement) el; + map.put(field.getName(), field.getValue()); + } + } + return map; + } + + public void merge(Dictionary dict) { + merge(dict, new String[0]); + } + + public void merge(Dictionary dict, String[] keysToExclude) { + if (dict == null) + return; + // System.out.println("Dictionary.merge(): "+dict); + for (String key : dict.getKeys()) { + if(ArrayUtils.contains(keysToExclude, key)){ + continue; + } + + DefaultElement ele = dict.getElement(key); + if (ele instanceof Dictionary) { + Dictionary d = (Dictionary) ele; + if (found(d.getName()) && isDictionary(d.getName())) { + subDict(d.getName()).merge(d); + } else { + add(new Dictionary(d.getName())); + subDict(d.getName()).merge(d); + } + } else if (ele instanceof ListField) { + ListField l = (ListField) ele; + if (found(l.getName()) && isList(l.getName())) { + getList(l.getName()).merge(l); + } else { + add(new ListField(l.getName())); + getList(l.getName()).merge(l); + } + } else if (ele instanceof ThetaListField2) { + ThetaListField2 t = (ThetaListField2) ele; + if (found(t.getName()) && isThetaList2(t.getName())) { + getThetaList2(t.getName()).merge(t); + } else { + add(new ThetaListField2(t)); + } + } else if (ele instanceof ListField2) { + ListField2 l = (ListField2) ele; + if (found(l.getName()) && isList2(l.getName())) { + getList2(l.getName()).merge(l); + } else { + add(new ListField2(l)); + } + } else if (ele instanceof FieldElement) { + FieldElement f = (FieldElement) ele; + if (f instanceof DimensionedScalar) { + add(new DimensionedScalar((DimensionedScalar) f)); + } else { + add(f.getName(), f.getValue()); + } + } + } + genericKeys.addAll(dict.genericKeys); + } + + public void clear() { + elements.clear(); + keys.clear(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Dictionary) { + Dictionary d = (Dictionary) obj; + if (elements.size() != d.elements.size()) + return false; + for (String key : elements.keySet()) { + if (!elements.get(key).equals(d.elements.get(key))) + return false; + } + return true; + } + return false; + } + + /* * * * * * * * * * * * * + * READ/WRITE STUFF * * * * * * * * * * * * + */ + + public void readDictionary(File file) { + DictionaryReader reader = new DictionaryReader(this); + reader.read(file); + } + + protected void readDictionary(InputStream input, DictionaryLinkResolver resolver) { + DictionaryReader reader = new DictionaryReader(this, resolver); + reader.read(input); + } + + protected void readDictionary(InputStream input) { + DictionaryReader reader = new DictionaryReader(this); + reader.read(input); + } + + protected void readDictionaryFromString(String text) { + DictionaryReader reader = new DictionaryReader(this); + reader.read(text); + } + + protected String write() { + DictionaryWriter writer = new DictionaryWriter(this); + return writer.write(); + } + +} diff --git a/src/eu/engys/core/dictionary/DictionaryBuilder.java b/src/eu/engys/core/dictionary/DictionaryBuilder.java new file mode 100644 index 0000000..1bce27d --- /dev/null +++ b/src/eu/engys/core/dictionary/DictionaryBuilder.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import eu.engys.core.dictionary.parser.ListField2; + +public class DictionaryBuilder { + + + private Dictionary dictionary; + + private DictionaryBuilder(String name) { + this.dictionary = new Dictionary(name); + } + + public static DictionaryBuilder newDictionary(String name) { + return new DictionaryBuilder(name); + } + + public DictionaryBuilder field(String k, String v) { + dictionary.add(k, v); + return this; + } + + public DictionaryBuilder dimensionedScalar(String k, String v, String d) { + dictionary.add(new DimensionedScalar(k, v, d)); + return this; + } + + public DictionaryBuilder array(String k, String... v) { + dictionary.add(k, v); + return this; + } + + public DictionaryBuilder dict(Dictionary d) { + dictionary.add(d); + return this; + } + + public Dictionary done() { + return dictionary; + } + + public DictionaryBuilder list(String string, Dictionary... dicts) { + ListField list = new ListField(string); + for (Dictionary dictionary : dicts) { + list.add(dictionary); + } + dictionary.add(list); + return this; + } + + public DictionaryBuilder list2(String string, DefaultElement... elements) { + ListField2 list = new ListField2(string); + for (DefaultElement fieldElement : elements) { + list.add(fieldElement); + } + dictionary.add(list); + return this; + } + + public DictionaryBuilder scalar(String k, String dimensions, String v) { + dictionary.add(new DimensionedScalar(k, v, dimensions)); + return this; + } + + public DictionaryBuilder foamFile(String parent, String name) { + dictionary.setFoamFile(FoamFile.getDictionaryFoamFile(parent,name)); + return this; + } + +} diff --git a/src/eu/engys/core/dictionary/DictionaryEditor.java b/src/eu/engys/core/dictionary/DictionaryEditor.java new file mode 100644 index 0000000..756fe39 --- /dev/null +++ b/src/eu/engys/core/dictionary/DictionaryEditor.java @@ -0,0 +1,253 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dialog.ModalityType; +import java.awt.FlowLayout; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SwingConstants; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rtextarea.RTextScrollPane; + +import eu.engys.core.dictionary.parser.DictionaryReader2; +import eu.engys.core.project.system.BlockMeshDict; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; + +public class DictionaryEditor { + + public static final String CODE_EDITOR = "codeEditor"; + public static final String DICTIONARY_EDITOR_DIALOG_NAME = "dictionary.editor.dialog"; + + private static DictionaryEditor instance; + + private JDialog dialog; + private RSyntaxTextArea editor; + private DocumentListener documentListener; + + private Dictionary dictionary; + private boolean modified; + + private Runnable onDisposeRunnable; + + private Runnable onOKRunnable; + + private JButton okButton; + + public static DictionaryEditor getInstance() { + if (instance == null) + instance = new DictionaryEditor(); + return instance; + } + + private DictionaryEditor() { + initEditor(); + initListeners(); + } + + private void initEditor() { + this.editor = new RSyntaxTextArea(); + editor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); + editor.setCodeFoldingEnabled(true); + editor.setAntiAliasingEnabled(true); + editor.setBackground(new Color(240, 240, 240)); + editor.setName(CODE_EDITOR); + } + + private void initListeners() { + documentListener = new DocumentListener() { + + @Override + public void removeUpdate(DocumentEvent e) { + documentModified(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentModified(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentModified(); + } + }; + } + + private void documentModified() { + if (!modified) { + dialog.setTitle("*" + dialog.getTitle()); + this.modified = true; + } + } + + public void show(Window parent, Dictionary dictionary) { + show(parent, dictionary, null, null, null); + } + + public void show(final Window parent, Dictionary dictionary, final Runnable onShowRunnable, Runnable onDisposeRunnable, Runnable onOKRunnable) { + this.dictionary = dictionary; + this.onDisposeRunnable = onDisposeRunnable; + this.onOKRunnable = onOKRunnable; + ExecUtil.invokeAndWait(new Runnable() { + + @Override + public void run() { + initDialog(parent); + load(); + if (onShowRunnable != null) { + onShowRunnable.run(); + } + dialog.setVisible(true); + } + }); + } + + private void initDialog(Window parent) { + dialog = new JDialog(parent != null ? parent : UiUtil.getActiveWindow(), ModalityType.MODELESS); + dialog.setName(DICTIONARY_EDITOR_DIALOG_NAME); + dialog.getContentPane().setLayout(new BorderLayout()); + dialog.getContentPane().add(createMainPanel(), BorderLayout.CENTER); + dialog.getContentPane().add(createButtonsPanel(), BorderLayout.SOUTH); + dialog.getContentPane().doLayout(); + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + closeDialog(); + } + }); + + dialog.setSize(800, 600); + dialog.setLocationRelativeTo(null); + dialog.getRootPane().setDefaultButton(okButton); + } + + private JPanel createMainPanel() { + RTextScrollPane scrollPane = new RTextScrollPane(editor); + scrollPane.setFoldIndicatorEnabled(true); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(scrollPane); + return mainPanel; + } + + private JPanel createButtonsPanel() { + JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + + okButton = new JButton(new OKAction()); + okButton.setName("OK"); + + JButton cancelButton = new JButton(new CancelAction()); + cancelButton.setName("Cancel"); + + panel.add(okButton); + panel.add(cancelButton); + + JPanel buttonsPanel = new JPanel(new BorderLayout()); + buttonsPanel.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.NORTH); + buttonsPanel.add(panel, BorderLayout.CENTER); + + return buttonsPanel; + } + + private void closeDialog() { + dialog.setVisible(false); + dialog.dispose(); + dialog = null; + if (onDisposeRunnable != null) { + onDisposeRunnable.run(); + } + } + + private void load() { + editor.getDocument().removeDocumentListener(documentListener); + try { + editor.setText(dictionary.toString()); + editor.setCaretPosition(0); + } catch (Exception e) { + e.printStackTrace(); + } + dialog.setTitle(dictionary.getName()); + editor.getDocument().addDocumentListener(documentListener); + this.modified = false; + } + + private void save() { + dictionary.clear(); + // use name not instanceof! + if (dictionary.getName().equals(BlockMeshDict.BLOCK_DICT)) { + new DictionaryReader2(dictionary).read(editor.getText(), true); + } else { + new DictionaryReader(dictionary).read(editor.getText(), true); + } + dialog.setTitle(dictionary.getName()); + } + + private class OKAction extends AbstractAction { + public OKAction() { + super("OK"); + } + + @Override + public void actionPerformed(ActionEvent e) { + save(); + if(onOKRunnable != null){ + onOKRunnable.run(); + } + closeDialog(); + } + } + + private class CancelAction extends AbstractAction { + public CancelAction() { + super("Cancel"); + } + + @Override + public void actionPerformed(ActionEvent e) { + closeDialog(); + } + } + +} diff --git a/src/eu/engys/core/dictionary/DictionaryException.java b/src/eu/engys/core/dictionary/DictionaryException.java new file mode 100644 index 0000000..51119be --- /dev/null +++ b/src/eu/engys/core/dictionary/DictionaryException.java @@ -0,0 +1,34 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +public class DictionaryException extends RuntimeException { + + public DictionaryException(String message) { + super(message); + } +} diff --git a/src/eu/engys/core/dictionary/DictionaryLinkResolver.java b/src/eu/engys/core/dictionary/DictionaryLinkResolver.java new file mode 100644 index 0000000..98f3411 --- /dev/null +++ b/src/eu/engys/core/dictionary/DictionaryLinkResolver.java @@ -0,0 +1,116 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +public class DictionaryLinkResolver { + +// private Dictionary dictionary; + private Dictionary linksDestination; + + public DictionaryLinkResolver(Dictionary linksDestination) { + this.linksDestination = linksDestination; + } + + public void resolve(Dictionary dictionary) { + resolveLinks(dictionary, linksDestination); + } + + private void resolveLinks(Dictionary dict, Dictionary linksDestination) { + for (Dictionary d : dict.getDictionaries()) { + resolveLinks(d, linksDestination); + } + if (dict.found(Dictionary.DICTIONARY_LINK)) { + String link = dict.lookupString(Dictionary.DICTIONARY_LINK); + //System.out.println("------------> link: "+link); + String name = link.replace("$", ""); + //System.out.println("------------> name: "+name); + dict.remove(Dictionary.DICTIONARY_LINK); + + Dictionary dest = findDestination(name, linksDestination); + if (dest != null) { + dict.merge(dest); + //System.out.println("------------> dest: "+dest); + } + } + + for(ListField lf : dict.getListFields()) { + for(DefaultElement el : lf.getListElements()) { + if (el instanceof Dictionary) { + resolveLinks((Dictionary) el, linksDestination); + } + } + } + + for(FieldElement f : dict.getFields()) { + if (f.getName().startsWith(Dictionary.VALUE_LINK)) { + String key = f.getName().replace(Dictionary.VALUE_LINK, ""); + //System.out.println("------------> key: "+key); + String link = dict.lookupString(f.getName()); + //System.out.println("------------> link: "+link); + String name = link.replace("$", ""); + //System.out.println("------------> name: "+name); + dict.remove(f.getName()); + if (linksDestination.found(name)) { + String dest = linksDestination.lookupString(name); + //System.out.println("------------> dest: "+dest); + dict.add(key, dest); + } else { + //System.err.println("Warning: "+name+" not found in dictionary "+linksDestination.getName()); + } + } else if (f.getName().startsWith(Dictionary.VALUE_UNIFORM_LINK)) { + String key = f.getName().replace(Dictionary.VALUE_UNIFORM_LINK, ""); + //System.out.println("------------> key: "+key); + String link = dict.lookupString(f.getName()); + //System.out.println("------------> link: "+link); + String name = link.replace("$", ""); + //System.out.println("------------> name: "+name); + dict.remove(f.getName()); + if (linksDestination.found(name)) { + String dest = linksDestination.lookupString(name); + //System.out.println("------------> dest: "+dest); + dict.add(key, "uniform "+dest); + } else { + //System.err.println("Warning: "+name+" not found in dictionary "+linksDestination.getName()); + } + } + } + } + + private Dictionary findDestination(String name, Dictionary linksDestination) { + if (linksDestination.isDictionary(name)) { + return linksDestination.subDict(name); + } else { + for (Dictionary d : linksDestination.getDictionaries()) { + Dictionary dest = findDestination(name, d); + if (dest != null) { + return dest; + } + } + } + return null; + } +} diff --git a/src/eu/engys/core/dictionary/DictionaryReader.java b/src/eu/engys/core/dictionary/DictionaryReader.java new file mode 100644 index 0000000..34fdc18 --- /dev/null +++ b/src/eu/engys/core/dictionary/DictionaryReader.java @@ -0,0 +1,363 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import static eu.engys.core.dictionary.Dictionary.DICTIONARY_LINK; +import static eu.engys.core.dictionary.Dictionary.SPACER; +import static eu.engys.core.dictionary.Dictionary.VALUE_LINK; +import static eu.engys.core.dictionary.Dictionary.VALUE_UNIFORM_LINK; +import static eu.engys.core.dictionary.Dictionary.VERBOSE; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Stack; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.IOUtils; +import eu.engys.util.RegexpUtils; + +public class DictionaryReader { + + private static final Logger logger = LoggerFactory.getLogger(DictionaryReader.class); + + private static final String LIST_START = "!"; + private static final String MATRIX_START = "&"; + private static final String MATRIX_DELIMITER = "|"; + private static final String FIELD_END = ";"; + private static final String DICTIONARY_END = "}"; + private static final String DICTIONARY_START = "{"; + private static final String COMMENT_REGEX = "/\\*(?:.|[\\n\\r])*?\\*/"; + private Dictionary dictionary; + private DictionaryLinkResolver linkResolver; + + public DictionaryReader(Dictionary dictionary) { + this(dictionary, new DictionaryLinkResolver(dictionary)); + } + + public DictionaryReader(Dictionary dictionary, DictionaryLinkResolver linkResolver) { + this.dictionary = dictionary; + this.linkResolver = linkResolver; + } + + public void read(File file) { + String text = readFile(file); + text = prepareText(text, file); + textToDictionary(text); + if (dictionary.found("FoamFile")) + dictionary.remove("FoamFile"); + } + + public void read(InputStream is) { + String text = readStream(is); + text = prepareText(text, null); + textToDictionary(text); + if (dictionary.found("FoamFile")) + dictionary.remove("FoamFile"); + } + + public void read(String text) { + read(text, false); + } + + public void read(String text, boolean removeHeader) { + text = prepareText(text, null); + textToDictionary(text); + if (dictionary.found("FoamFile") && removeHeader) { + dictionary.remove("FoamFile"); + } + } + + private String readFile(File file) { + return IOUtils.readStringFromFile(file); + } + + private String readStream(InputStream is) { + String text = ""; + try { + text = IOUtils.readStringFromStream(is); + } catch (IOException e) { + logger.warn("Error reading stream: {} ", e.getMessage()); + } + return text; + } + + private String prepareText(String text, File file) { +// text = text.replaceAll(COMMENT_REGEX, ""); + text = new jregex.Pattern(COMMENT_REGEX).replacer("").replace(text); + text = text.replaceAll("\t", SPACER); + + StringTokenizer rowTokenizer = new StringTokenizer(text, "\n"); + StringBuffer sb = new StringBuffer(); + while (rowTokenizer.hasMoreTokens()) { + String token = rowTokenizer.nextToken(); + token = token.trim(); + if (token.startsWith("//")) + continue; + if (token.contains("//")) { + token = token.substring(0, token.indexOf("//")).trim(); + } + if (token.startsWith("#include")) { + sb.append(importFile(token, file)); + continue; + } + sb.append(token); + sb.append("\n"); + } + text = sb.toString(); + return text; + } + + private String importFile(String token, File file) { + String text = ""; + if (file != null) { + try { + Pattern regex = Pattern.compile("#include\\s+\"(.+)\""); + Matcher regexMatcher = regex.matcher(token); + if (regexMatcher.find() && regexMatcher.groupCount() == 1) { + String fileName = regexMatcher.group(1).trim(); + String parentDir = file.getParent(); + + File fileToImport = new File(parentDir, fileName); + text = readFile(fileToImport); + text = prepareText(text, fileToImport); + } + } catch (PatternSyntaxException ex) { + ex.printStackTrace(); + } + } + + return text; + } + + protected void textToDictionary(String text) { + text = text.replace("\n", SPACER); + + // exploit table data structure + text = text.replaceAll("\\(\\s*(" + RegexpUtils.DOUBLE + ")\\s*\\(([^\\)]*)\\)\\s*\\)", "< $1 <$2> >"); + + // exploit matrix structure + text = text.replaceAll("([\\d | \\s])\\(\\s*\\(", "$1" + SPACER + MATRIX_START); + text = text.replaceAll("\\)\\s*\\(", MATRIX_DELIMITER); + + // exploit list structure + /* a parenthesis preceded by whatever AND at least a space */ + text = text.replaceAll("(?<=[^\\]])\\s+\\(", SPACER + LIST_START); + /* a parenthesis preceded by a space+digit OR digit+digit */ + text = text.replaceAll("(?<=\\W\\d)\\(", SPACER + LIST_START); + + if (VERBOSE) + System.out.println(text); + + parseDictionary(text); + } + + protected void parseDictionary(String text) { + StringTokenizer tokenizer = new StringTokenizer(text, "};{!&", true); + Stack stack = new Stack(); + readDictionary(tokenizer, stack); + if (VERBOSE) + System.out.println("##################################\n" + toString()); + linkResolver.resolve(dictionary); + } + + void readDictionary(StringTokenizer st, Stack stack) { + while (st.hasMoreTokens()) { + String token = st.nextToken(); + token = token.trim(); // tolgo gli spazi + stack.push(token);// metto nella pila + + if (stack.peek().equals(DICTIONARY_START)) { + stack.pop(); + String name = stack.peek(); + Dictionary d = new Dictionary(name); + if (VERBOSE) + System.out.println("START DICTIONARY: " + name); + + new DictionaryReader(d).readDictionary(st, stack); + + if (isMultiple(name)) { + String[] names = extractMultipleKeys(name); + for (String n : names) { + if (isGeneric(withDoubleQuotes(n))) { + Dictionary copy = new Dictionary(d); + copy.setName(withDoubleQuotes(n)); + dictionary.addGeneric(copy); + } else { + Dictionary copy = new Dictionary(d); + copy.setName(n); + dictionary.add(copy); + } + } + } else if (isGeneric(name)) { + dictionary.addGeneric(d); + } else { + dictionary.add(d); + } + } else if (stack.peek().equals(DICTIONARY_END)) { + stack.pop(); + String name = stack.pop(); + if (VERBOSE) + System.out.println("FINE DICTIONARY: " + name); + return; + } else if (stack.peek().equals(FIELD_END)) { + stack.pop(); + String field = stack.pop(); + if (VERBOSE) + System.out.println(field); + + if (field.startsWith("$")) { + dictionary.add(DICTIONARY_LINK, field); + } else if (field.equals(")")) { + if (VERBOSE) + System.out.println("END LIST"); + return; + } else { + readField(field); + } + } else if (stack.peek().equals(LIST_START)) { + stack.pop(); + String name = stack.pop(); + if (VERBOSE) + System.out.println("START LIST: " + name); + ListField list = new ListField(name); + ListReader reader = new ListReader(list, dictionary); + reader.readList(st, stack); + if (!reader.isSimpleList()) { + dictionary.add(list); + } + } else if (stack.peek().equals(MATRIX_START)) { + stack.pop(); + String name = stack.pop(); + if (VERBOSE) + System.out.println("START MATRIX: " + name); + FieldElement matrix = new FieldElement(name, ""); + MatrixReader reader = new MatrixReader(matrix, dictionary); + reader.readMatrix(st, stack); + } + } + } + + protected void readField(String field) { + try { + dictionary.add(new DimensionedScalar(field)); + } catch (DictionaryException e) { + int splitIndex = field.indexOf(SPACER); + if (splitIndex < 0) { + String key = field.trim(); + String value = ""; + dictionary.add(key, value); + } else { + String key = field.substring(0, splitIndex).trim(); + String value = field.substring(splitIndex).trim(); + + // System.out.println("DictionaryReader.readField() FIELD: "+field+" -> K: "+key+", V: "+value); + + if (isMultiple(key)) { + String[] keys = extractMultipleKeys(key); + for (String k : keys) { + if (isGeneric(withDoubleQuotes(k))) { + dictionary.addGeneric(withDoubleQuotes(k), value); + } else { + dictionary.add(k, value); + } + } + } else if (isGeneric(key)) { + dictionary.addGeneric(key, value); + } else if (isLink(value)) { + extractLink(key, value); + } else { + dictionary.add(key, value); + } + } + } + } + + private String withDoubleQuotes(String k) { + return "\"" + k + "\""; + } + + public static String[] extractMultipleKeys(String key) { + key = key.replace("\"", ""); + + if (key.contains("(") && key.contains(")")) { + int start = key.indexOf("("); + int end = key.indexOf(")"); + String header = key.substring(0, start); + String footer = key.substring(end + 1, key.length()); + String core = key.substring(start + 1, end); + + String[] tokens = core.split("\\|"); + + String[] keys = new String[tokens.length]; + for (int i = 0; i < keys.length; i++) { + keys[i] = header + tokens[i] + footer; + } + return keys; + } else { + String[] tokens = key.split("\\|"); + return tokens; + } + + } + + public String cleanGenericKey(String key) { + key = key.substring(1, key.length() - 1); + key = key.substring(0, key.indexOf(".*")); + return key; + } + + public boolean isGeneric(String key) { + return key.startsWith("\"") && key.endsWith("\"") && key.contains(".*"); + } + + public boolean isMultiple(String key) { + return key.startsWith("\"") && key.endsWith("\"") && key.contains(MATRIX_DELIMITER); + } + + public boolean isLink(String value) { + return !value.startsWith("\"") && value.contains("$"); + } + + private void extractLink(String key, String value) { + if (value.startsWith("uniform")) { + String link = value.replace("uniform", "").trim(); + if (link.startsWith("$")) { + dictionary.add(VALUE_UNIFORM_LINK + key, link); + } + } else if (value.startsWith("$")) { + dictionary.add(VALUE_LINK + key, value); + } + } + +} diff --git a/src/eu/engys/core/dictionary/DictionaryUtils.java b/src/eu/engys/core/dictionary/DictionaryUtils.java new file mode 100644 index 0000000..1493183 --- /dev/null +++ b/src/eu/engys/core/dictionary/DictionaryUtils.java @@ -0,0 +1,160 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.parser.DictionaryReader2; +import eu.engys.util.progress.ProgressMonitor; + +public final class DictionaryUtils { + + private static final Logger logger = LoggerFactory.getLogger(DictionaryUtils.class); + + public static Dictionary readDictionary(String text) { + Dictionary dictionary = new Dictionary(""); + dictionary.readDictionaryFromString(text); + return dictionary; + } + + public static Dictionary readDictionary(File file, ProgressMonitor monitor) { + String name = file.getName(); + if (file.exists()) { + if (monitor != null) { + monitor.info(file.getName(), 1); + } + return new Dictionary(file); + } + if (monitor != null) + monitor.warning(file.getName() + " NOT FOUND", 1); + + return new Dictionary(name); + } + + public static Dictionary readDictionary2(File file) { + String name = file.getName(); + String parent = file.getParent(); + if (file.exists()) { + Dictionary d = new Dictionary(name); + d.setFoamFile(FoamFile.getDictionaryFoamFile(parent, name)); + DictionaryReader2 reader = new DictionaryReader2(d); + reader.read(file); + + return d; + } + + return new Dictionary(name); + } + + public static Dictionary readDictionary(File file, Dictionary linkDestination) { + String name = file.getName(); + if (file.exists()) { + Dictionary d = new Dictionary(name); + DictionaryReader reader = new DictionaryReader(d, new DictionaryLinkResolver(linkDestination)); + reader.read(file); + + return d; + } + return new Dictionary(name); + } + + public static void removeDictionary(File parent, Dictionary dict, ProgressMonitor monitor) { + if (dict != null) { + File dictFile = new File(parent, dict.getName()); + if (dictFile.exists()) { + logger.info("REMOVE: " + dict.getName() + " -> " + dictFile.getAbsolutePath()); + if (!dictFile.delete()) + logger.warn("REMOVE: Cannot remove {}", dictFile); + } else { + logger.warn("REMOVE: File {} does not exist", dictFile); + } + } + } + + public static void writeDictionary(File parent, Dictionary dict, ProgressMonitor monitor) { + if (dict != null) { + File dictFile = new File(parent, dict.getName()); + writeDictionaryFile(dictFile, dict); + String msg = "WRITE: " + dict.getName() + " -> " + dictFile.getAbsolutePath(); + if (monitor != null) { + monitor.info(dict.getName(), 1); + } + logger.info(msg); + } else { + logger.warn("Dictionary NOT FOUND in parent " + parent, 1); + } + } + + public static void writeDictionaryFile(File file, Dictionary dictionary) { + String text = dictionary.write(); + try { + FileUtils.writeStringToFile(file, text); + } catch (IOException e) { + logger.error(e.getMessage()); + } + } + + public static Dictionary header(String parent, Dictionary dict) { + if (dict == null) + return null; + dict.setFoamFile(FoamFile.getDictionaryFoamFile(parent, dict.getName())); + return dict; + } + + public static String[] string2StringArray(String list) { + String trimmedString = list.trim(); + String stringWithoutParentheses = trimmedString.substring(1, trimmedString.length() - 1).trim(); + if(stringWithoutParentheses.isEmpty()){ + return new String[0]; + } else { + return stringWithoutParentheses.split("\\s+"); + } + } + + public static String stringArray2String(String[] values) { + StringBuilder sb = new StringBuilder(); + sb.append("("); + for (String value : values) { + sb.append(value); + sb.append(" "); + } + sb.append(")"); + return sb.toString(); + } + + public static void copyIfFound(Dictionary dest, Dictionary source, String key) { + if (source.found(key)) { + dest.add(key, source.lookup(key)); + } + } + +} diff --git a/src/eu/engys/core/dictionary/DictionaryWriter.java b/src/eu/engys/core/dictionary/DictionaryWriter.java new file mode 100644 index 0000000..6eefff9 --- /dev/null +++ b/src/eu/engys/core/dictionary/DictionaryWriter.java @@ -0,0 +1,182 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary; + +import static eu.engys.core.dictionary.Dictionary.SPACER; +import static eu.engys.core.dictionary.Dictionary.TAB; +import static eu.engys.core.dictionary.Dictionary.VERBOSE; +import eu.engys.core.dictionary.parser.ListField2; + +public class DictionaryWriter { + + protected Dictionary dictionary; + + protected final String START = "{"; + protected final String END = "}\n"; + + public DictionaryWriter(Dictionary dictionary) { + this.dictionary = dictionary; + } + + public String write() { + StringBuffer sb = new StringBuffer(); + writeDictionary(sb, ""); + return sb.toString(); + } + + public void writeDictionary(StringBuffer sb, String rowHeader) { + if (dictionary.getFoamFile() != null) { + sb.append(FoamFile.HEADER); + DictionaryWriter writer = new DictionaryWriter(dictionary.getFoamFile()); + writer.writeDictionary(sb, ""); + + if (dictionary.hasOnlyList()) { + for (ListField list : dictionary.getListFields()) { + if (list.getName().isEmpty()) { + list.writeListDict(sb, rowHeader); + } else { + list.writeListField(sb, rowHeader); + } + } + return; + } + + if (dictionary.hasOnlyList2()) { + for (ListField2 list : dictionary.getListFields2()) { + if (list.nameIsANumber()) { + list.writeListDict(sb, rowHeader); + } else { + list.writeListField(sb, rowHeader); + } + } + return; + } + } else { + sb.append("\n"); + sb.append(rowHeader); + sb.append(dictionary.getName()); + sb.append("\n"); + sb.append(rowHeader); + sb.append(START); + } + for (String key : dictionary.getKeys()) { + DefaultElement ele = dictionary.getElement(key); + if (ele != null) { + writeElement(sb, rowHeader, ele); + } else { + System.out.println("DictionaryWriter.writeDictionary() ------------------------------>> " + key + " is NUUULLLLL in " + dictionary.getKeys() + " and " + dictionary.getDictionaries()); + } + } + for (String includeFile : dictionary.getIncludeFiles()) { + writeInclude(sb, includeFile, rowHeader); + } + + if (dictionary.getFoamFile() == null) + sb.append("\n" + rowHeader + END); + } + + public static void writeElement(StringBuffer sb, String rowHeader, DefaultElement ele) { + if (ele instanceof Dictionary) { + DictionaryWriter writer = new DictionaryWriter((Dictionary) ele); + writer.writeDictionary(sb, rowHeader + TAB); + } else if (ele instanceof DimensionedScalar) { + writeDimensionedScalar(sb, (DimensionedScalar) ele, rowHeader); + } else if (ele instanceof ListField) { + ListField.class.cast(ele).writeListField(sb, rowHeader); + } else if (ele instanceof ListField2) { + ListField2.class.cast(ele).writeListField(sb, rowHeader); + } else if (ele instanceof TableRowElement) { + TableRowElement.class.cast(ele).writeTableRow(sb, rowHeader); + } else if (hasParenthesis(ele)) { + writeMatrix(sb, (FieldElement) ele, rowHeader); + } else { + writeField(sb, (FieldElement) ele, rowHeader); + } + } + + private static boolean hasParenthesis(DefaultElement ele) { + FieldElement fieldElement = (FieldElement) ele; + String value = fieldElement.getValue(); + return value != null && value.contains("(") && value.contains("List"); + } + + protected static void writeField(StringBuffer sb, FieldElement field, String rowHeader) { + if (field.getName().isEmpty()) { + sb.append(SPACER); + sb.append(field.getValue()); + } else { + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(field.getName()); + sb.append(SPACER); + sb.append(field.getValue()); + sb.append(";"); + } + } + + protected static void writeMatrix(StringBuffer sb, FieldElement field, String rowHeader) { + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(field.getName()); + sb.append(SPACER); + String value = field.getValue(); + if (value.contains("vector")) { + sb.append(value.replace("(", "\n(").replace("))", ")\n)").replace("", "\n")); + } else { + sb.append(value.replace("(", "\n(").replace("", "\n").replaceAll("\\s+", "\n")); + } + sb.append(";"); + } + + protected void writeInclude(StringBuffer sb, String includeFile, String rowHeader) { + if (VERBOSE) + System.out.println("Dictionary.writeInclude() " + includeFile); + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append("#include"); + sb.append(SPACER); + sb.append(includeFile); + } + + private static void writeDimensionedScalar(StringBuffer sb, DimensionedScalar ds, String rowHeader) { + if (VERBOSE) + System.out.println("Dictionary.writeDimensionedScalar() " + (ds != null ? ds.getName() : "NULL!!!")); + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(ds.getName()); + sb.append(SPACER); + sb.append(ds.getName()); + sb.append(SPACER); + sb.append(ds.getDimensions()); + sb.append(SPACER); + sb.append(ds.getValue()); + sb.append(";"); + } +} diff --git a/src/eu/engys/core/dictionary/DimensionedScalar.java b/src/eu/engys/core/dictionary/DimensionedScalar.java new file mode 100644 index 0000000..9d43777 --- /dev/null +++ b/src/eu/engys/core/dictionary/DimensionedScalar.java @@ -0,0 +1,145 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import java.util.ArrayList; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DimensionedScalar extends FieldElement { + private static final Pattern PATTERN = Pattern.compile("(\\w+)\\s+(\\[.+\\])\\s+(.*\\z)"); + // private static final Pattern PATTERN = + // Pattern.compile("(\\w+)\\s+(\\[.+\\])\\s+(\\d+\\.?\\d?)"); + + private Dimensions dimensions; + + public DimensionedScalar(String name, String value, String dimensions) { + super(name, value); + this.dimensions = new Dimensions(dimensions); + } + + public DimensionedScalar(String name, String value, Dimensions dimensions) { + super(name, value); + this.dimensions = dimensions; + } + + public DimensionedScalar(DimensionedScalar ds) { + super(ds.getName(), ds.getValue()); + this.dimensions = new Dimensions(ds.getDimensions().toString()); + } + + /** + * La stringa contiene il value del field di cui bisogna fare il parsing per + * estrarre valore e unita' di misura + * + * @param field + * value + */ + public DimensionedScalar(String fieldValue) throws IllegalArgumentException { + super("", ""); + + Matcher matcher = PATTERN.matcher(fieldValue); + if (matcher.find()) { + String name = matcher.group(1); + String dimensions = matcher.group(2); + String value = matcher.group(3); + setName(name); + setValue(value); + this.dimensions = new Dimensions(dimensions); + } else { + throw new DictionaryException("CANNOT PARSE: >" + fieldValue + "<"); + } + } + + public double doubleValue() { + return Double.parseDouble(getValue()); + } + + public Dimensions getDimensions() { + return dimensions; + } + + public class Dimensions extends ArrayList { + public Dimensions(String dimString) { + dimString = dimString.trim(); + dimString = dimString.substring(1, dimString.length() - 1); // tolgo + // le + // parentesi + // quadre + StringTokenizer st = new StringTokenizer(dimString); + if (st.countTokens() == 7 || st.countTokens() == 5) { + while (st.hasMoreTokens()) { + add(Integer.decode(st.nextToken())); + } + if (size() == 5) { + add(Integer.valueOf(0)); + add(Integer.valueOf(0)); + } + } else { + throw new IllegalStateException("Bad number of dimensions: " + dimString); + } + } + + public Dimensions() { + } + + /** + * Perform a division among dimensions: we need to subtract each + * component + * + * @param d + * @return + */ + public Dimensions divide(Dimensions d) { + Dimensions result = new Dimensions(); + for (int i = 0; i < d.size(); i++) { + result.add(new Integer(get(i).intValue() - d.get(i).intValue())); + } + return result; + } + + public String toString() { + if (size() == 0) + return "[]"; + StringBuilder sb = new StringBuilder(); + sb.append('['); + + for (Integer i : this) { + sb.append(i); + sb.append(" "); + } + return sb.append(']').toString(); + } + } + + @Override + public String toString() { + return getName() + " " + getDimensions() + " " + getValue(); + } + +} diff --git a/src/eu/engys/core/dictionary/FieldChangeListener.java b/src/eu/engys/core/dictionary/FieldChangeListener.java new file mode 100644 index 0000000..f95afad --- /dev/null +++ b/src/eu/engys/core/dictionary/FieldChangeListener.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import java.awt.event.ActionListener; + +public interface FieldChangeListener extends ActionListener { + + public void fieldChanged(); + public boolean isAdjusting(); + public void setAdjusting(boolean b); +} diff --git a/src/eu/engys/core/dictionary/FieldElement.java b/src/eu/engys/core/dictionary/FieldElement.java new file mode 100644 index 0000000..dcc3763 --- /dev/null +++ b/src/eu/engys/core/dictionary/FieldElement.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +public class FieldElement extends DefaultElement { + + private String value; + + public FieldElement(String name, String value) { + super(name); + this.value = value; + } + + public FieldElement(FieldElement el) { + this(el.getName(), el.getValue()); + } + + public void setValue(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + @Override + public String toString() { + return getName() + "[" + value + "]"; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof FieldElement) { + return ((FieldElement) obj).getName().equals(getName()) && ((FieldElement) obj).value.equals(value) ; + } + return false; + } +} diff --git a/src/eu/engys/core/dictionary/FieldListener.java b/src/eu/engys/core/dictionary/FieldListener.java new file mode 100644 index 0000000..072aa20 --- /dev/null +++ b/src/eu/engys/core/dictionary/FieldListener.java @@ -0,0 +1,31 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +public interface FieldListener { + +} diff --git a/src/eu/engys/core/dictionary/FileEditor.java b/src/eu/engys/core/dictionary/FileEditor.java new file mode 100644 index 0000000..4cc76a1 --- /dev/null +++ b/src/eu/engys/core/dictionary/FileEditor.java @@ -0,0 +1,254 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dialog.ModalityType; +import java.awt.FlowLayout; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SwingConstants; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rtextarea.RTextScrollPane; + +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; + +public class FileEditor { + + public static final String FILE_EDITOR_DIALOG = "file.editor.dialog"; + public static final String FILE_EDITOR = "fileEditor"; + + private static FileEditor instance; + + private JDialog dialog; + private RSyntaxTextArea editor; + private DocumentListener documentListener; + + private String fileName; + private List fileContent; + private boolean modified; + + private Runnable onDisposeRunnable; + + private Runnable onOKRunnable; + + private JButton okButton; + + public static FileEditor getInstance() { + if (instance == null) + instance = new FileEditor(); + return instance; + } + + private FileEditor() { + initEditor(); + initListeners(); + } + + private void initEditor() { + this.editor = new RSyntaxTextArea(); + editor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE); + editor.setCodeFoldingEnabled(true); + editor.setAntiAliasingEnabled(true); + editor.setBackground(new Color(240, 240, 240)); + editor.setName(FILE_EDITOR); + } + + private void initListeners() { + documentListener = new DocumentListener() { + + @Override + public void removeUpdate(DocumentEvent e) { + documentModified(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentModified(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentModified(); + } + }; + } + + private void documentModified() { + if (!modified) { + dialog.setTitle("*" + dialog.getTitle()); + this.modified = true; + } + } + + public void show(final Window parent, List fileContent, String fileName) { + show(parent, fileContent, fileName, null, null, null); + } + + public void show(final Window parent, List fileContent, String fileName, final Runnable onShowRunnable, Runnable onDisposeRunnable, Runnable onOKRunnable) { + this.fileContent = fileContent; + this.fileName = fileName; + this.onDisposeRunnable = onDisposeRunnable; + this.onOKRunnable = onOKRunnable; + ExecUtil.invokeAndWait(new Runnable() { + + @Override + public void run() { + initDialog(parent); + load(); + if (onShowRunnable != null) { + onShowRunnable.run(); + } + dialog.setVisible(true); + } + }); + } + + private void initDialog(Window parent) { + dialog = new JDialog(parent != null ? parent : UiUtil.getActiveWindow(), ModalityType.MODELESS); + dialog.setName(FILE_EDITOR_DIALOG); + dialog.getContentPane().setLayout(new BorderLayout()); + dialog.getContentPane().add(createMainPanel(), BorderLayout.CENTER); + dialog.getContentPane().add(createButtonsPanel(), BorderLayout.SOUTH); + dialog.getContentPane().doLayout(); + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + closeDialog(); + } + }); + + dialog.setSize(800, 600); + dialog.setLocationRelativeTo(null); + dialog.getRootPane().setDefaultButton(okButton); + } + + private JPanel createMainPanel() { + RTextScrollPane scrollPane = new RTextScrollPane(editor); + scrollPane.setFoldIndicatorEnabled(true); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(scrollPane); + return mainPanel; + } + + private JPanel createButtonsPanel() { + JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + + okButton = new JButton(new OKAction()); + okButton.setName("OK"); + + JButton cancelButton = new JButton(new CancelAction()); + cancelButton.setName("Cancel"); + + panel.add(okButton); + panel.add(cancelButton); + + JPanel buttonsPanel = new JPanel(new BorderLayout()); + buttonsPanel.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.NORTH); + buttonsPanel.add(panel, BorderLayout.CENTER); + + return buttonsPanel; + } + + private void closeDialog() { + dialog.setVisible(false); + dialog.dispose(); + dialog = null; + if (onDisposeRunnable != null) { + onDisposeRunnable.run(); + } + } + + private void load() { + editor.getDocument().removeDocumentListener(documentListener); + editor.setText(""); + try { + for (String line : fileContent) { + editor.append(line + "\n"); + } + editor.setCaretPosition(0); + } catch (Exception e) { + e.printStackTrace(); + } + dialog.setTitle(fileName); + editor.getDocument().addDocumentListener(documentListener); + this.modified = false; + } + + private void save() { + fileContent.clear(); + for (String line : editor.getText().split("\\n")){ + fileContent.add(line); + } + dialog.setTitle(fileName); + } + + private class OKAction extends AbstractAction { + public OKAction() { + super("OK"); + } + + @Override + public void actionPerformed(ActionEvent e) { + save(); + if(onOKRunnable != null){ + onOKRunnable.run(); + } + closeDialog(); + } + } + + private class CancelAction extends AbstractAction { + public CancelAction() { + super("Cancel"); + } + + @Override + public void actionPerformed(ActionEvent e) { + closeDialog(); + } + } + +} diff --git a/src/eu/engys/core/dictionary/Finder.java b/src/eu/engys/core/dictionary/Finder.java new file mode 100644 index 0000000..6f5547b --- /dev/null +++ b/src/eu/engys/core/dictionary/Finder.java @@ -0,0 +1,32 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary; + +public interface Finder { + + boolean accept(String key); + +} diff --git a/src/eu/engys/core/dictionary/FoamFile.java b/src/eu/engys/core/dictionary/FoamFile.java new file mode 100644 index 0000000..fcf8f70 --- /dev/null +++ b/src/eu/engys/core/dictionary/FoamFile.java @@ -0,0 +1,65 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import eu.engys.util.ApplicationInfo; + +public class FoamFile extends Dictionary { + + private static final String HELYX = ApplicationInfo.getName(); + private static final String VERSION = ApplicationInfo.getVersion(); + public static final String HEADER = + "/*--------------------------------*- C++ -*----------------------------------*\\"+"\n"+ + "| o | |" +"\n"+ + "| o o | "+HELYX+" |" +"\n"+ + "| o O o | Version: "+VERSION+" |" +"\n"+ + "| o o | Web: http://www.engys.com |" +"\n"+ + "| o | |" +"\n"+ + "\\*---------------------------------------------------------------------------*/"; + + private FoamFile(String version, String format, String classe, String location, String object) { + super("FoamFile"); + add("version", version); + add("format", format); + add("class", classe); + add("location", location); + add("object", object); + } + + public static FoamFile getFieldFoamFile(String name) { + return new FoamFile("2.0", "ascii", name.startsWith("U") ? "volVectorField" : (name.startsWith("point") ? "pointVectorField" : "volScalarField"), "\"0\"", name); + } + + public static FoamFile getDictionaryFoamFile(String parent, String name) { + return new FoamFile("2.0", "ascii", "dictionary", parent, name); + } + + public static FoamFile getDictionaryFoamFile(String classe, String parent, String name) { + return new FoamFile("2.0", "ascii", classe, parent, name); + } + +} diff --git a/src/eu/engys/core/dictionary/ListField.java b/src/eu/engys/core/dictionary/ListField.java new file mode 100644 index 0000000..7ce63b9 --- /dev/null +++ b/src/eu/engys/core/dictionary/ListField.java @@ -0,0 +1,188 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import static eu.engys.core.dictionary.Dictionary.TAB; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.StringTokenizer; + +public class ListField extends DefaultElement { + + private static final String SPACER = " "; + private List list = new ArrayList(); + + public ListField(String name) { + super(decodeName(name)); + } + + public boolean isEmpty() { + return list.isEmpty(); + } + + public ListField(ListField lf) { + super(lf.getName()); + for (DefaultElement el : lf.getListElements()) { + if (el instanceof Dictionary) { + add(new Dictionary((Dictionary) el)); + } else { + System.err.println("ListField only dictionaries are allowed as elements: " + el.getName()); + } + } + } + + private static String decodeName(String name) { + if (name.contains(SPACER)) { + StringTokenizer tokenizer = new StringTokenizer(name, SPACER); + if (tokenizer.countTokens() == 1) { + // System.out.println("ListField.decodeName() 1 TOKEN"); + String token = tokenizer.nextToken(); + try { + int size = Integer.parseInt(token); + return ""; + } catch (NumberFormatException ex) { + return token; + } + } else if (tokenizer.countTokens() == 2) { + // System.out.println("ListField.decodeName() 2 TOKEN"); + String token1 = tokenizer.nextToken(); + String token2 = tokenizer.nextToken(); + try { + int size = Integer.parseInt(token2); + } catch (NumberFormatException ex) { + return name; + } + return token1; + } else if (tokenizer.countTokens() == 3) { + // System.out.println("ListField.decodeName() 3 TOKEN"); + String token1 = tokenizer.nextToken(); + String token2 = tokenizer.nextToken(); + String token3 = tokenizer.nextToken(); + try { + int size = Integer.parseInt(token3); + } catch (NumberFormatException ex) { + } + return name; + } + } else { + // System.out.println("ListField.decodeName() 4+ TOKEN"); + try { + int size = Integer.parseInt(name); + return ""; + } catch (NumberFormatException ex) { + return name; + } + } + return name; + } + + public void add(DefaultElement element) { + list.add(element); + } + + public List getListElements() { + return Collections.unmodifiableList(list); + } + + public void merge(ListField l) { + for (DefaultElement el : l.getListElements()) { + if (containsElement(el)) { + if (el instanceof Dictionary) { + Dictionary dictionary = getDictionary(el.getName()); + if (dictionary != null) { + dictionary.merge((Dictionary) el); + } else { + System.err.println("Error merging list '" + getName() + "' with " + l.getName() + ""); + } + } else { + // do nothing + } + } else { + add(el); + } + } + } + + private boolean containsElement(DefaultElement element) { + for (DefaultElement e : list) { + if (e instanceof Dictionary && e.getName().equals(element.getName()) && !e.getName().isEmpty()) { + return true; + } else if (e.getName().equals(element.getName()) && e.equals(element)) { + return true; + } + } + return false; + } + + public void writeListField(StringBuffer sb, String rowHeader) { + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(getName()); + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append("("); + for (DefaultElement el : getListElements()) { + DictionaryWriter.writeElement(sb, rowHeader, el); + } + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(");"); + } + + public void writeListDict(StringBuffer sb, String rowHeader) { + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(list.size()); + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append("("); + for (DefaultElement el : getListElements()) { + DictionaryWriter.writeElement(sb, rowHeader, el); + } + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(")"); + } + + public Dictionary getDictionary(String name) { + for (DefaultElement e : list) { + if (e instanceof Dictionary && !e.getName().isEmpty() && e.getName().equals(name)) { + return (Dictionary) e; + } + } + return null; + } + +} diff --git a/src/eu/engys/core/dictionary/ListReader.java b/src/eu/engys/core/dictionary/ListReader.java new file mode 100644 index 0000000..f83cdfd --- /dev/null +++ b/src/eu/engys/core/dictionary/ListReader.java @@ -0,0 +1,118 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import static eu.engys.core.dictionary.Dictionary.VERBOSE; + +import java.util.Stack; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ListReader { + + private ListField list; + private Dictionary parent; + private boolean simpleList; + + public ListReader(ListField list, Dictionary parent) { + this.list = list; + this.parent = parent; + } + + public void readList(StringTokenizer st, Stack stack) { + while (st.hasMoreTokens()) { + String token = st.nextToken(); + token = token.trim(); /* tolgo gli spazi */ + stack.push(token);/* metto nella pila */ + + if (stack.peek().equals("{")) { + stack.pop(); + String name = stack.peek(); + Dictionary d = new Dictionary(name); + if (VERBOSE) + System.out.println("START LIST DICTIONARY: " + name); + + new DictionaryReader(d).readDictionary(st, stack); + list.add(d); + } else if (stack.peek().equals("}")) { + stack.pop(); + String name = stack.pop(); + if (VERBOSE) + System.out.println("END LIST DICTIONARY: " + name); + return; + } else if (stack.peek().equals(";")) { + stack.pop(); + String field = stack.pop(); + if (VERBOSE) + System.out.println(list.getName()+", "+field); + + if (field.endsWith(")")) { + if (list.getListElements().isEmpty()) { + Pattern pattern = Pattern.compile("(\\w+)\\s+nonuniform\\s*(List)?\\s*(\\d+)?\\s*"); + Matcher listFieldMatcher = pattern.matcher(list.getName()); + if (field.equals(")")) { + if (listFieldMatcher.matches()) {/* is an empty array nonuniform 'nonuniform 0()' */ + parent.add(listFieldMatcher.group(1), "nonuniform 0()"); + simpleList = true; + } + } else { + if (listFieldMatcher.matches()) { + field = processField(field); + + parent.add(listFieldMatcher.group(1), "nonuniform List "+(listFieldMatcher.groupCount() == 3 ? listFieldMatcher.group(3)+" " : "" )+"( "+field); + } else if (list.getName().contains(" uniform")) {/* is a simple array (val1 val2 val3) not empty '( )' */ + parent.add(list.getName().replace("uniform", "").trim(), "uniform ( " + field); + } else if (field.startsWith("<")) {/* is a dataTable ( +++ (+++ +++ +++) ) */ + parent.add(list.getName(), "( " + field.replace("<", "(").replace(">", ")")); + } else { + field = processField(field); + parent.add(list.getName(), "( " + field); + } + simpleList = true; + } + } + if (VERBOSE) + System.out.println("END LIST"); + return; + } + } + } + } + + private String processField(String field) { + if (field.contains("|")) { + field = field.replace("|", ") ("); + } + return field; + } + + public boolean isSimpleList() { + return simpleList; + } + +} diff --git a/src/eu/engys/core/dictionary/MatrixReader.java b/src/eu/engys/core/dictionary/MatrixReader.java new file mode 100644 index 0000000..1282a35 --- /dev/null +++ b/src/eu/engys/core/dictionary/MatrixReader.java @@ -0,0 +1,98 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import static eu.engys.core.dictionary.Dictionary.VERBOSE; + +import java.util.Stack; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class MatrixReader { + + private FieldElement matrix; + private Dictionary parent; + + public MatrixReader(FieldElement matrix, Dictionary parent) { + this.matrix = matrix; + this.parent = parent; + } + + public void readMatrix(StringTokenizer st, Stack stack) { + while(st.hasMoreTokens()) { + String token = st.nextToken(); + token = token.trim(); //tolgo gli spazi + stack.push(token);//metto nella pila + + if (stack.peek().equals(";")) { + stack.pop(); + String field = stack.pop(); + if (VERBOSE) System.out.println(field); + + if (field.endsWith(")")) { + Pattern pattern = Pattern.compile("(\\w+)\\s+nonuniform\\s+(List)?\\s+(\\d+)?"); + Matcher matcher = pattern.matcher(matrix.getName()); + + if (matcher.matches()) { + field = processField(field); + parent.add(matcher.group(1), "nonuniform List "+(matcher.groupCount() == 3 ? matcher.group(3)+" " : "" )+"(( "+field); + } else { + field = processField(field); + parent.add(matrix.getName(), "(( "+field); + } + return; + } + } + } + } + + private String processField(String field) { + if (field.contains("|")) { + field = field.replace("|", ") ("); + } + return field; + } + + public static void matrixToVector(Dictionary dictionary, String key) { + if ( dictionary.found(key) ) { + String value = dictionary.lookupString(key); + value = value.replace("(", "").replace(")", ""); + value = "( "+value+" )"; + dictionary.add(key, value); + } + } + + public static void vectorToMatrix(Dictionary dictionary, String key) { + if ( dictionary.found(key) ) { + String value = dictionary.lookupString(key); + value = value.replace("(", "").replace(")", ""); + value = "(( "+value+" ))"; + dictionary.add(key, value); + } + } +} diff --git a/src/eu/engys/core/dictionary/StartWithFinder.java b/src/eu/engys/core/dictionary/StartWithFinder.java new file mode 100644 index 0000000..861483a --- /dev/null +++ b/src/eu/engys/core/dictionary/StartWithFinder.java @@ -0,0 +1,40 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary; + +public class StartWithFinder implements Finder { + + private String keyToFind; + + public StartWithFinder(String keyToFind) { + this.keyToFind = keyToFind; + } + + @Override + public boolean accept(String key) { + return key.startsWith(keyToFind); + } +} diff --git a/src/eu/engys/core/dictionary/TableRowElement.java b/src/eu/engys/core/dictionary/TableRowElement.java new file mode 100644 index 0000000..6eee171 --- /dev/null +++ b/src/eu/engys/core/dictionary/TableRowElement.java @@ -0,0 +1,100 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary; + +import static eu.engys.core.dictionary.Dictionary.SPACER; +import eu.engys.core.dictionary.parser.ListField2; + +public class TableRowElement extends DefaultElement { + + private ListField2 key; + private FieldElement[] values; + + public TableRowElement(ListField2 key, FieldElement... values) { + super(""); + this.key = key; + this.values = values; + } + + public TableRowElement(TableRowElement el) { + super(""); + this.key = new ListField2(el.getKey()); + this.values = copy(el.getValues()); + } + + private FieldElement[] copy(FieldElement[] values) { + FieldElement[] copy = new FieldElement[values.length]; + for (int i = 0; i < values.length; i++) { + copy[i] = new FieldElement(values[i]); + } + return copy; + } + + public void writeTableRow(StringBuffer sb, String rowHeader) { +// System.out.println("ListField2.writeListField() name: "+getName()+", size: "+size+", uniformity: "+uniformity+", identifier: "+identifier); + sb.append("\n"); + key.writeListField(sb, rowHeader); + sb.append(SPACER); + for (FieldElement f : values) { + sb.append(SPACER); + sb.append(f.getValue()); + } + } + + public ListField2 getKey() { + return key; + } + + public FieldElement[] getValues() { + return values; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TableRowElement) { + TableRowElement t = ((TableRowElement) obj); + return key.equals(t.key) /*&& valuesAreEquals(t.values)*/; + } + return super.equals(obj); + } + + private boolean valuesAreEquals(FieldElement[] values) { + if (this.values.length != values.length) { + return false; + } + for (int i = 0; i < values.length; i++) { + if (!this.values[i].equals(values[i])) { + return false; + } + } + return true; + } + + public void merge(TableRowElement el) { + this.values = el.values; + } +} diff --git a/src/eu/engys/core/dictionary/model/AbstractTableAdapter.java b/src/eu/engys/core/dictionary/model/AbstractTableAdapter.java new file mode 100644 index 0000000..d8ea2e8 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/AbstractTableAdapter.java @@ -0,0 +1,233 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.model; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSeparator; + +import eu.engys.util.ui.builder.PanelBuilder; + +public abstract class AbstractTableAdapter extends JPanel { + + public static final Integer LEAVE_ONE_LINE = 1; + + private Map rowsMap = new LinkedHashMap<>(); + + private final String[] columnLabels; + private final String rowLabel; + private PanelBuilder builder; + private final Integer linesToLeave; + protected JPanel buttonsPanel; + private boolean showColumnNames; + + public AbstractTableAdapter(String[] columnNames) { + this(columnNames, "", 0, true); + } + + public AbstractTableAdapter(String[] columnNames, String rowsLabel, Integer linesToLeave, boolean showColumnNames) { + super(new BorderLayout()); + this.rowLabel = rowsLabel; + this.columnLabels = columnNames; + this.linesToLeave = linesToLeave; + this.showColumnNames = showColumnNames; + layoutComponents(); + } + + private void layoutComponents() { + setOpaque(false); + setName("abstract.table.adapter"); + + this.builder = new PanelBuilder(); + buttonsPanel = getButtonsPanel(); + add(buttonsPanel, BorderLayout.NORTH); + add(builder.getPanel(), BorderLayout.CENTER); + clear(); + } + + private JPanel getButtonsPanel() { + JPanel buttonsPanel = new JPanel(new FlowLayout()); + buttonsPanel.setOpaque(false); + + JButton addButton = new JButton(new AddRowAction()); + addButton.setName("add.row.button"); + buttonsPanel.add(addButton); + + JButton remButton = new JButton(new RemRowAction()); + remButton.setName("rem.row.button"); + buttonsPanel.add(remButton); + return buttonsPanel; + } + + public void clear() { + rowsMap.clear(); + builder.clear(); + if(showColumnNames){ + builder.addComponent("", labelArrayField()); + builder.addFill(new JSeparator()); + } + } + + private JLabel[] labelArrayField() { + JLabel[] labels = new JLabel[columnLabels.length]; + for (int i = 0; i < labels.length; i++) { + labels[i] = new JLabel(columnLabels[i]); + } + return labels; + } + + public void hideButtonsPanel() { + buttonsPanel.setVisible(false); + } + + protected abstract void addRow(); + + protected JComponent[] addRow(JComponent[] field) { + return addRow(field, true); + } + + protected JComponent[] addRow(JComponent[] field, boolean save) { + addPropertyChangeListeners(field); + String label = rowLabel.isEmpty() ? "" : rowLabel + (rowsMap.size() + 1); + JComponent[] componentToAdd = createComponent(field); + builder.addComponent(label, componentToAdd); + setNames(rowsMap.size(), field); + updateGUI(); + rowsMap.put(rowsMap.size(), field); + if(save){ + save(); + } + return componentToAdd; + } + + private void setNames(int row, JComponent... c) { + for (int i = 0; i < c.length; i++) { + c[i].setName((rowLabel.isEmpty() ? getName() : rowLabel) + "." + columnLabels[i] + "." + row); + } + } + + protected JComponent[] createComponent(JComponent[] field) { + return field; + } + + protected void removeRow() { + if (rowsMap.size() > linesToLeave) { + removeLastRowFromMap(); + clear(); + load(); + updateGUI(); + } + } + + private void removeLastRowFromMap() { + Integer[] keys = rowsMap.keySet().toArray(new Integer[0]); + JComponent[] removedComp = rowsMap.remove(keys[keys.length - 1]); + save(); + triggerEventFor3D(removedComp); + } + + private void updateGUI() { + JPanel panel = builder.getPanel(); + panel.revalidate(); + panel.repaint(); + } + + public Map getRowsMap() { + return rowsMap; + } + + protected int elementsCount() { + return rowsMap.size(); + } + + protected abstract void load(); + + protected abstract void save(); + + protected void addPropertyChangeListeners(JComponent[] field) { + for (int i = 0; i < field.length; i++) { + JComponent f = field[i]; + if (f instanceof JCheckBox) { + ((JCheckBox) f).addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + save(); + } + }); + } else { + f.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + save(); + } + } + }); + } + } + } + + protected void triggerEventFor3D(JComponent[] comp) { + } + + private final class AddRowAction extends AbstractAction { + + private AddRowAction() { + super("+"); + } + + @Override + public void actionPerformed(ActionEvent e) { + addRow(); + } + } + + private final class RemRowAction extends AbstractAction { + private RemRowAction() { + super("-"); + } + + @Override + public void actionPerformed(ActionEvent e) { + removeRow(); + } + } + +} diff --git a/src/eu/engys/core/dictionary/model/AxisInfo.java b/src/eu/engys/core/dictionary/model/AxisInfo.java new file mode 100644 index 0000000..70da1e8 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/AxisInfo.java @@ -0,0 +1,56 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary.model; + +import eu.engys.util.ui.textfields.DoubleField; + +public class AxisInfo { + + public static final String PROPERTY_NAME = "point.location"; + public static final String LABEL = "Point "; + private DoubleField[] center; + private EventActionType action; + private DoubleField[] axis; + + public AxisInfo(DoubleField[] axis, DoubleField[] center, EventActionType action) { + this.axis = axis; + this.center = center; + this.action = action; + } + + public DoubleField[] getAxis() { + return axis; + } + + public DoubleField[] getCenter() { + return center; + } + + public EventActionType getAction() { + return action; + } + +} diff --git a/src/eu/engys/core/dictionary/model/DictionaryModel.java b/src/eu/engys/core/dictionary/model/DictionaryModel.java new file mode 100644 index 0000000..dc35441 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/DictionaryModel.java @@ -0,0 +1,1428 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary.model; + +import static eu.engys.util.ui.ComponentsFactory.checkBoxControllerField; +import static eu.engys.util.ui.ComponentsFactory.checkField; +import static eu.engys.util.ui.ComponentsFactory.comboBoxControllerField; +import static eu.engys.util.ui.ComponentsFactory.doubleArrayField; +import static eu.engys.util.ui.ComponentsFactory.doubleField; +import static eu.engys.util.ui.ComponentsFactory.doublePointField; +import static eu.engys.util.ui.ComponentsFactory.intArrayField; +import static eu.engys.util.ui.ComponentsFactory.intField; +import static eu.engys.util.ui.ComponentsFactory.listField; +import static eu.engys.util.ui.ComponentsFactory.radioField; +import static eu.engys.util.ui.ComponentsFactory.selectField; +import static eu.engys.util.ui.ComponentsFactory.spinnerField; +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JPanel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.dictionary.DimensionedScalar; +import eu.engys.core.dictionary.FieldChangeListener; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.FileFieldPanel; +import eu.engys.util.ui.ListBuilder; +import eu.engys.util.ui.ListFieldPanel; +import eu.engys.util.ui.RadioFieldPanel; +import eu.engys.util.ui.SelectionValueConfigurator; +import eu.engys.util.ui.builder.JCheckBoxController; +import eu.engys.util.ui.builder.JComboBoxController; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; +import eu.engys.util.ui.textfields.SpinnerField; +import eu.engys.util.ui.textfields.StringField; + +public class DictionaryModel { + + private static final Logger logger = LoggerFactory.getLogger(DictionaryModel.class); + + private final String key; + + private Dictionary dictionary; + private List companions = new LinkedList<>(); + + public interface DictionaryListener { + public void dictionaryChanged() throws DictionaryError; + } + + private List listeners = new CopyOnWriteArrayList(); + private Map subModels = new HashMap(); + + public static class DictionaryError extends Exception { + private String[] messages; + + public DictionaryError(String... msg) { + super(msg[0]); + this.messages = msg; + } + + public String[] getMessages() { + return messages; + } + } + + public DictionaryModel() { + this(null, new Dictionary("")); + } + + public DictionaryModel(String key) { + this(key, new Dictionary("")); + } + + public DictionaryModel(Dictionary dictionary) { + this(null, dictionary); + } + + public DictionaryModel(String key, Dictionary dictionary) { + this.key = key; + this.dictionary = dictionary; + } + + public void addCompanion(DictionaryModel companion) { + this.companions.add(companion); + } + + public void setCompanion(DictionaryModel companion) { + this.companions.clear(); + this.companions.add(companion); + } + + public List getCompanions() { + return companions; + } + + public Dictionary getDictionary() { + return dictionary; + } + + public DictionaryModel subModel(String key) { + if (subModels.containsKey(key)) { + return subModels.get(key); + } else { + Dictionary subDict = dictionary.subDict(key); + DictionaryModel model = new DictionaryModel(subDict != null ? subDict : new Dictionary(key)); + subModels.put(key, model); + return model; + } + } + + public void refresh() { + try { + fireDictionaryChange(); + } catch (DictionaryError e) { + } + } + + public void setDictionary(Dictionary dictionary) { + try { + if (dictionary != null) { + this.dictionary = dictionary; + for (String key : subModels.keySet()) { + DictionaryModel subModel = subModels.get(key); + subModel.setDictionary(dictionary.subDict(key)); + } + fireDictionaryChange(); + } + } catch (DictionaryError e) { + String[] messages = e.getMessages(); + + StringBuilder sb = new StringBuilder(); + for (String message : messages) { + sb.append(message); + sb.append("\n"); + } + // System.err.println(sb.toString()); + logger.warn(sb.toString()); + } + } + + private void fireDictionaryChange() throws DictionaryError { + List errors = new ArrayList(); + for (DictionaryListener listener : listeners) { + try { + // System.out.println("Listener: "+listener.getClass()); + // System.out.println("pre: "+dictionary); + listener.dictionaryChanged(); + // System.out.println("post: "+dictionary); + + } catch (DictionaryError e) { + errors.add(e.getMessage()); + // e.printStackTrace(); + } + } + if (!errors.isEmpty()) { + throw new DictionaryError(errors.toArray(new String[errors.size()])); + } + } + + public void addDictionaryListener(DictionaryListener listener) { + listeners.add(listener); + } + + /* + * BINDING + */ + public StringField bindLabel(String key) { + StringField field = stringField(); + field.addPropertyChangeListener(new LabelFieldHandler(key, field)); + return field; + } + + public StringField bindLabel(String key, boolean allowEmpty) { + StringField field = stringField(); + field.setToVerifier(allowEmpty, true); + field.addPropertyChangeListener(new LabelFieldHandler(key, field)); + return field; + } + + public JCheckBox bindBoolean(String key) { + JCheckBox field = checkField(); + field.addActionListener(new BooleanFieldHandler(key, field, false)); + return field; + } + + public JCheckBox bindBoolean(String key, boolean def) { + JCheckBox field = checkField(def); + field.addActionListener(new BooleanFieldHandler(key, field, def)); + return field; + } + + public JCheckBox bindBoolean(String key, String trueValue, String falseValue) { + JCheckBox field = checkField(); + field.addActionListener(new BooleanValuesFieldHandler(key, field, trueValue, falseValue)); + return field; + } + + public JCheckBox bindBoolean(String key, String trueValue, String falseValue, boolean def) { + JCheckBox field = checkField(def); + field.addActionListener(new BooleanValuesFieldHandler(key, field, trueValue, falseValue)); + return field; + } + + public SpinnerField bindSpinner(String key) { + SpinnerField field = spinnerField(); + field.addPropertyChangeListener(new SpinnerFieldHandler(key, field)); + return field; + } + + public IntegerField bindIntegerPositive(String key) { + IntegerField field = intField(0, Integer.MAX_VALUE); + field.addPropertyChangeListener(new IntFieldHandler(key, field)); + return field; + } + + public IntegerField bindIntegerNegative(String key) { + IntegerField field = intField(-Integer.MAX_VALUE, 0); + field.addPropertyChangeListener(new IntFieldHandler(key, field)); + return field; + } + + public IntegerField bindInteger(String key) { + IntegerField field = intField(-Integer.MAX_VALUE, Integer.MAX_VALUE); + field.addPropertyChangeListener(new IntFieldHandler(key, field)); + return field; + } + + public IntegerField bindInteger(String key, Integer lb, Integer ub) { + IntegerField field = intField(lb, ub); + field.addPropertyChangeListener(new IntFieldHandler(key, field)); + return field; + } + + public IntegerField bindIntegerAngle_360(String key) { + // Negative value = disabled + IntegerField field = intField(-Integer.MAX_VALUE, 359); + field.addPropertyChangeListener(new IntFieldHandler(key, field)); + return field; + } + + public IntegerField bindIntegerAngle_180(String key) { + // Negative value = disabled + IntegerField field = intField(-Integer.MAX_VALUE, 180); + field.addPropertyChangeListener(new IntFieldHandler(key, field)); + return field; + } + + // public IntegerField bindInteger(String key, String name) { + // IntegerField field = bindInteger(key); + // field.setName(name); + // return field; + // } + + public IntegerField bindIntegerLevels(String key, String mode) { + IntegerField field = intField(); + field.addPropertyChangeListener(new IntLevelsFieldHandler(key, mode, field)); + return field; + } + + public IntegerField[] bindIntegerArray(String key, Integer dimensions) { + return bindIntegerArray(key, dimensions, null); + } + + public IntegerField[] bindIntegerArray(String key, Integer dimensions, FieldChangeListener listener) { + IntegerField[] field = intArrayField(dimensions); + for (int i = 0; i < field.length; i++) { + IntegerField f = field[i]; + f.addPropertyChangeListener(new IntPointFieldHandler(key, field, listener)); + } + return field; + } + + public DoubleField bindDimensionedDouble(String key, String dimensions, Double lb, Double ub) { + DoubleField field = doubleField(lb, ub); + field.addPropertyChangeListener(new DoubleDimensionedFieldHandler(key, field, dimensions)); + return field; + } + + public DoubleField bindDimensionedDouble(String key, String dimensions) { + DoubleField field = doubleField(); + field.addPropertyChangeListener(new DoubleDimensionedFieldHandler(key, field, dimensions)); + return field; + } + + public DoubleField bindUniformDouble(String key) { + DoubleField field = doubleField(); + field.addPropertyChangeListener(new DoubleUniformFieldHandler(key, field)); + return field; + } + + // public DoubleField bindUniformDoubleWithName(String key, String name) { + // DoubleField field = doubleField(); + // field.setName(name); + // field.addPropertyChangeListener(new DoubleUniformFieldHandler(key, + // field)); + // return field; + // } + + public DoubleField bindUniformDouble(String key, double lb, double ub, double def) { + DoubleField field = doubleField(def, lb, ub); + field.addPropertyChangeListener(new DoubleUniformFieldHandler(key, field)); + return field; + } + + public DoubleField bindUniformDouble(String key, double lb, double ub) { + DoubleField field = doubleField(lb, ub); + field.addPropertyChangeListener(new DoubleUniformFieldHandler(key, field)); + return field; + } + + public DoubleField bindUniformNegativeDouble(String key) { + DoubleField field = doubleField(); + field.addPropertyChangeListener(new DoubleUniformNegativeFieldHandler(key, field)); + return field; + } + + public DoubleField bindUniformPositiveDouble(String key) { + DoubleField field = doubleField(); + field.addPropertyChangeListener(new DoubleUniformPositiveFieldHandler(key, field)); + return field; + } + + public DoubleField bindConstantDouble(String key) { + DoubleField field = doubleField(); + field.addPropertyChangeListener(new DoubleConstantFieldHandler(key, field)); + return field; + } + + public DoubleField bindUniformDouble(String key1, String key2) { + DoubleField field = doubleField(); + field.addPropertyChangeListener(new DoubleUniformFieldHandler(key1, field)); + field.addPropertyChangeListener(new DoubleUniformFieldHandler(key2, field)); + return field; + } + + public DoubleField bindDouble(String key) { + return bindDouble(key, (FieldChangeListener) null); + } + + public DoubleField bindDouble(String key, FieldChangeListener listener) { + DoubleField field = doubleField(); + field.addPropertyChangeListener(new DoubleFieldHandler(key, field, listener)); + return field; + } + + public DoubleField bindDouble(String key, Integer places, FieldChangeListener listener) { + DoubleField field = doubleField(places); + field.addPropertyChangeListener(new DoubleFieldHandler(key, field, listener)); + return field; + } + + public DoubleField bindDouble(String key, Double def) { + DoubleField field = doubleField(def); + field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null)); + return field; + } + + public DoubleField bindDouble(String key, double lb, double ub) { + DoubleField field = doubleField(lb, ub); + field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null)); + return field; + } + + public DoubleField bindDoublePositive(String key) { + DoubleField field = doubleField(0.0, Double.MAX_VALUE); + field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null)); + return field; + } + + public DoubleField bindDoubleNegative(String key) { + DoubleField field = doubleField(-Double.MAX_VALUE, 0.0); + field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null)); + return field; + } + + public DoubleField bindDoubleAngle_360(String key) { + // Negative value = disabled + DoubleField field = doubleField(-Double.MAX_VALUE, 360 - Double.MIN_VALUE); + field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null)); + return field; + } + + public DoubleField bindDoubleAngle_180(String key) { + // Negative value = disabled + DoubleField field = doubleField(-Double.MAX_VALUE, 180.0); + field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null)); + return field; + } + + public DoubleField[] bindPoint(String key, FieldChangeListener listener) { + DoubleField[] field = doublePointField(); + for (int i = 0; i < field.length; i++) { + DoubleField f = field[i]; + f.setName(key + "." + i); + f.addPropertyChangeListener(new PointFieldHandler(key, field, listener)); + } + return field; + } + + public DoubleField[] bindPoint(String key, Integer places, FieldChangeListener listener) { + DoubleField[] field = doublePointField(places); + for (int i = 0; i < field.length; i++) { + DoubleField f = field[i]; + f.setName(key + "." + i); + f.addPropertyChangeListener(new PointFieldHandler(key, field, listener)); + } + return field; + } + + public DoubleField[] bindPoint(String key) { + return bindPoint(key, null); + } + + public ShowLocationAdapter bindLocation(String key, int places) { + return bindLocation(key, places, Color.RED); + } + + public ShowAxisAdapter bindAxis(String key, Color colorKey) { + DoubleField[] axis = bindPoint(key, null); + DoubleField[] center = bindPoint(key, null); + return new ShowAxisAdapter(axis, center); + } + + public ShowLocationAdapter bindLocation(String key, int places, Color colorKey) { + DoubleField[] field = bindPoint(key, places, null); + return new ShowLocationAdapter(field, colorKey); + } + + public DoubleField[] bindUniformPoint(String key) { + DoubleField[] field = doublePointField(); + for (int i = 0; i < field.length; i++) { + DoubleField f = field[i]; + f.addPropertyChangeListener(new PointUniformFieldHandler(key, field)); + } + return field; + } + + // public DoubleField[] bindUniformPointWithName(String key, String name) { + // DoubleField[] field = doublePointField(); + // for (int i = 0; i < field.length; i++) { + // DoubleField f = field[i]; + // f.setName(name + "." + i); + // f.addPropertyChangeListener(new PointUniformFieldHandler(key, field)); + // } + // return field; + // } + + public DoubleField[] bindUniformPoint(String key1, String key2) { + DoubleField[] field = doublePointField(); + for (int i = 0; i < field.length; i++) { + DoubleField f = field[i]; + f.addPropertyChangeListener(new PointUniformFieldHandler(key1, field)); + f.addPropertyChangeListener(new PointUniformFieldHandler(key2, field)); + } + return field; + } + + public DoubleField[] bindDimensionedPoint(String key, String dimensions) { + DoubleField[] field = doublePointField(); + for (int i = 0; i < field.length; i++) { + DoubleField f = field[i]; + f.addPropertyChangeListener(new PointDimensionedFieldHandler(key, field, dimensions)); + } + return field; + } + + public DoubleField[] bindArray(String key, int dimensions) { + DoubleField[] field = doubleArrayField(dimensions); + for (int i = 0; i < field.length; i++) { + DoubleField f = field[i]; + f.setColumns(1); + f.setName(key + "." + i); + f.addPropertyChangeListener(new PointFieldHandler(key, field, null)); + } + return field; + } + + public FileFieldPanel bindFile(String key) { + FileFieldPanel field = ComponentsFactory.fileField(SelectionMode.FILES_ONLY, "Select file", true); + field.addPropertyChangeListener(new FileFieldHandler(key, field)); + return field; + } + + public FileFieldPanel bindFolder(String key) { + FileFieldPanel field = ComponentsFactory.fileField(SelectionMode.DIRS_ONLY, "Select folder", true); + field.addPropertyChangeListener(new FileFieldHandler(key, field)); + return field; + } + + public JComboBox bindSelection(String key) { + JComboBox combo = selectField(); + combo.addActionListener(new SelectFieldHandler(key, combo, null)); + return combo; + } + + public JComboBox bindSelection(String key, ListBuilder builder) { + JComboBox combo = selectField(builder); + combo.addActionListener(new SelectFieldHandler(key, combo, null)); + return combo; + } + + public JComboBox bindSelection(String key, String... keys) { + JComboBox combo = selectField(keys, keys); + combo.addActionListener(new SelectFieldHandler(key, combo, null)); + return combo; + } + + public JComboBox bindSelection(String key, String[] keys, String[] items) { + return bindSelection(key, keys, items, null); + } + + public JComboBox bindSelection(String key, String[] keys, String[] items, SelectionValueConfigurator configurator) { + JComboBox combo = selectField(keys, items); + combo.addActionListener(new SelectFieldHandler(key, combo, configurator)); + return combo; + } + + public JComboBoxController bindComboBoxController(String key) { + JComboBoxController combo = comboBoxControllerField(); + combo.addActionListener(new SelectFieldHandler(key, combo, null)); + return combo; + } + + public JCheckBoxController bindCheckBoxController(String key, String name) { + JCheckBoxController combo = checkBoxControllerField(name); + combo.addActionListener(new BooleanFieldHandler(key, combo, false)); + return combo; + } + + public RadioFieldPanel bindChoice(String key, String[] keys, String[] items) { + RadioFieldPanel panel = radioField(keys, items); + panel.addPropertyChangeListener(new ChoiceFieldHandler(key, panel)); + return panel; + } + + public ListFieldPanel bindList(String key, ListBuilder listBuilder) { + ListFieldPanel field = listField(listBuilder); + field.addPropertyChangeListener(new ListFieldHandler(key, field)); + return field; + } + + public PatchesMapTableAdapter bindPatchMapTable(DictionaryModel dictionaryModel, Patches targetPatches) { + return new PatchesMapTableAdapter(dictionaryModel, targetPatches); + } + + public JPanel bindTableLevels(String[] columnNames, final Class[] type) { + return new LevelsTableAdapter(this, columnNames, type); + } + + public PointTableAdapter bindPointMatrix(String[] columnNames, final String tableKey, int linesToLeave, boolean showPoint) { + return new PointTableAdapter(this, columnNames, tableKey, linesToLeave, showPoint); + } + + public JPanel bindOneDictionaryPerRowTable(String[] columnNames, final String[] columnKeys, final String tableKey, String[] rowNames, String[] rowKeys, final Class[] type) { + return new OneDictionaryPerRowTableAdapter(this, columnNames, columnKeys, rowNames, rowKeys, tableKey, type); + } + + class DoubleDimensionedFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private String dimensions; + private DoubleField field; + + public DoubleDimensionedFieldHandler(String key, DoubleField field, String dimensions) { + this.key = key; + this.field = field; + this.dimensions = dimensions; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + dictionary.add(new DimensionedScalar(key, Double.toString(field.getDoubleValue()), dimensions)); + logger.trace("DoubleFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + if (value != null) { + field.setDoubleValue(parseDouble(value)); + } else { + field.setDoubleValue(0); + } + logger.trace("DoubleFieldHandler -> read value: {}", value); + } + } + + class PointDimensionedFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private String dimensions; + private DoubleField[] field; + + public PointDimensionedFieldHandler(String key, DoubleField[] field, String dimensions) { + this.key = key; + this.field = field; + this.dimensions = dimensions; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + StringBuilder sb = new StringBuilder(); + sb.append("("); + for (int i = 0; i < field.length; i++) { + sb.append(field[i].getDoubleValue()); + sb.append(" "); + } + sb.append(")"); + dictionary.add(new DimensionedScalar(key, sb.toString(), dimensions)); + logger.trace("PointDimensionedFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + if (value != null) { + String[] values = value.trim().substring(1, value.length() - 1).trim().split("\\s+"); + for (int i = 0; i < values.length; i++) { + field[i].setDoubleValue(parseDouble(values[i])); + } + } else { + for (int i = 0; i < field.length; i++) { + field[i].setDoubleValue(0); + } + } + logger.trace("PointDimensionedFieldHandler -> value: {}", value); + } + + } + + class LabelFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private StringField field; + + public LabelFieldHandler(String key, StringField field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + if (field.getValue() == null) { + if (dictionary.found(key)) + dictionary.remove(key); + } else { + dictionary.add(key, field.getStringValue()); + } + logger.trace("LabelFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + field.setValue(value); + logger.trace("LabelFieldHandler -> value: {}", value); + } + } + + class ListFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private ListFieldPanel field; + + public ListFieldHandler(String key, ListFieldPanel field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + String value = DictionaryUtils.stringArray2String(field.getValues()); + dictionary.add(key, value); + logger.trace("ListFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + if (dictionary.isField(key)) { + String value = dictionary.lookup(key); + String[] values = DictionaryUtils.string2StringArray(value); + field.setValues(values); + logger.trace("ListFieldHandler -> value: {}", value); + } else { + field.setValues(new String[0]); + } + } + } + + class ChoiceFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private RadioFieldPanel field; + + public ChoiceFieldHandler(String key, RadioFieldPanel field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + dictionary.add(key, field.getSelectedKey()); + logger.trace("ChoiceFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + field.select(value); + logger.trace("ChoiceFieldHandler -> value: {}", value); + } + } + + class SpinnerFieldHandler implements PropertyChangeListener, DictionaryListener { + public SpinnerFieldHandler(String key, SpinnerField field) { + // TODO Auto-generated constructor stub + } + + @Override + public void dictionaryChanged() throws DictionaryError { + // TODO Auto-generated method stub + + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + // TODO Auto-generated method stub + + } + } + + class IntFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private IntegerField field; + + public IntFieldHandler(String key, IntegerField field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + if (field.getValue() == null) { + if (dictionary.found(key)) + dictionary.remove(key); + } else { + dictionary.add(key, Integer.toString(field.getIntValue())); + } + logger.trace("IntegerFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + if (value != null) { + field.setIntValue(parseInt(value)); + } else { + field.setValue(null); + } + logger.trace("IntegerFieldHandler -> value: {}", value); + } + } + + class IntLevelsFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private IntegerField field; + private String mode; + + public IntLevelsFieldHandler(String key, String mode, IntegerField field) { + this.key = key; + this.mode = mode; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + String lookupMode = dictionary.lookup("mode"); + if (mode.equals(lookupMode)) { + if (field.getValue() == null) { + if (dictionary.found(key)) + dictionary.remove(key); + } else { + dictionary.add(key, String.format("(( 1E5 %s ))", Integer.toString(field.getIntValue()))); + } + logger.trace("IntegerFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String lookupMode = dictionary.lookup("mode"); + if (lookupMode != null) { + if (mode.equals(lookupMode)) { + String value = dictionary.lookup(key); + if (value != null && value.length() > 4) { + String[] values = value.trim().substring(2, value.length() - 2).trim().split("\\s+"); + field.setIntValue(parseInt(values[1])); + } else { + field.setValue(null); + } + logger.trace("IntegerFieldHandler -> value: {}", value); + } else { + field.setValue(null); + } + } else { + field.setValue(null); + } + } + } + + class IntPointFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private IntegerField[] field; + private FieldChangeListener listener; + + public IntPointFieldHandler(String key, IntegerField[] field, FieldChangeListener listener) { + this.key = key; + this.field = field; + this.listener = listener; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + StringBuilder sb = new StringBuilder(); + sb.append("("); + for (int i = 0; i < field.length; i++) { + if (field[i].getValue() != null) { + sb.append(field[i].getIntValue()); + sb.append(" "); + } else { + if (dictionary.found(key)) + dictionary.remove(key); + return; + } + } + sb.append(")"); + dictionary.add(key, sb.toString()); + logger.trace("PointFieldHandler -> value: {}", dictionary.lookup(key)); + if (listener != null) { + listener.fieldChanged(); + } + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + if (listener != null) { + listener.setAdjusting(true); + } + if (value != null) { + String[] values = value.trim().substring(1, value.length() - 1).trim().split("\\s+"); + for (int i = 0; i < values.length; i++) { + field[i].setIntValue(parseInt(values[i])); + } + logger.trace("PointFieldHandler -> value: {}", value); + } else { + for (int i = 0; i < field.length; i++) { + field[i].setValue(null); + } + } + if (listener != null) { + listener.setAdjusting(false); + } + } + } + + class DoubleFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private DoubleField field; + private FieldChangeListener listener; + + public DoubleFieldHandler(String key, DoubleField field, FieldChangeListener listener) { + this.key = key; + this.field = field; + this.listener = listener; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + if (field.getValue() == null) { + if (dictionary.found(key)) + dictionary.remove(key); + } else { + dictionary.add(key, Double.toString(field.getDoubleValue())); + logger.trace("DoubleFieldHandler -> value: {}", dictionary.lookup(key)); + if (listener != null) { + listener.fieldChanged(); + } + } + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + if (listener != null) + listener.setAdjusting(true); + if (value != null) { + field.setDoubleValue(parseDouble(value)); + } else { + field.setValue(field.getDefaultValue()); + } + if (listener != null) + listener.setAdjusting(false); + + logger.trace("DoubleFieldHandler -> value: {}", value); + } + } + + class DoubleUniformFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private DoubleField field; + + public DoubleUniformFieldHandler(String key, DoubleField field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + if (!Double.isInfinite(field.getDoubleValue())) { + dictionary.add(key, "uniform " + Double.toString(field.getDoubleValue())); + logger.trace("DoubleUniformFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); // uniform value + logger.trace("DoubleUniformFieldHandler -> value: {}", value); + if (value != null) { + if (value.startsWith("nonuniform")) { + field.setDoubleValue(Double.POSITIVE_INFINITY); + } else { + value = value.replace("uniform ", ""); + field.setDoubleValue(parseDouble(value)); + } + } else { + field.setDoubleValue(field.getDefaultValue()); + } + } + } + + class DoubleUniformNegativeFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private DoubleField field; + + public DoubleUniformNegativeFieldHandler(String key, DoubleField field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + dictionary.add(key, "uniform " + Double.toString(-Math.abs(field.getDoubleValue()))); + logger.trace("DoubleUniformFieldHandler -> " + dictionary.toString()); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); // uniform value + logger.trace("DoubleUniformFieldHandler -> value: " + value); + if (value != null) { + value = value.replace("uniform ", ""); + field.setDoubleValue(Math.abs(parseDouble(value))); + } else { + field.setDoubleValue(field.getDefaultValue()); + } + } + } + + class DoubleUniformPositiveFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private DoubleField field; + + public DoubleUniformPositiveFieldHandler(String key, DoubleField field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + dictionary.add(key, "uniform " + Double.toString(Math.abs(field.getDoubleValue()))); + logger.trace("DoubleUniformFieldHandler -> " + dictionary.toString()); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); // uniform value + logger.trace("DoubleUniformFieldHandler -> value: " + value); + if (value != null) { + value = value.replace("uniform ", ""); + field.setDoubleValue(Math.abs(parseDouble(value))); + } else { + field.setDoubleValue(field.getDefaultValue()); + } + } + } + + class DoubleConstantFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private DoubleField field; + + public DoubleConstantFieldHandler(String key, DoubleField field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + dictionary.add(key, "constant " + Double.toString(field.getDoubleValue())); + logger.trace("DoubleUniformFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); // uniform value + logger.trace("DoubleUniformFieldHandler -> value: {}", value); + if (value != null) { + value = value.replace("constant ", ""); + field.setDoubleValue(parseDouble(value)); + } else { + field.setDoubleValue(field.getDefaultValue()); + } + } + } + + class BooleanFieldHandler implements ActionListener, DictionaryListener { + + private JCheckBox check; + private String key; + private final boolean def; + + public BooleanFieldHandler(String key, JCheckBox check, boolean def) { + this.check = check; + this.key = key; + this.def = def; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void actionPerformed(ActionEvent e) { + boolean selected = check.isSelected(); + dictionary.add(key, selected ? "true" : "false"); + logger.trace("BooleanFieldHandler -> value: {}", dictionary.lookup(key)); + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + String correctedForYesNo = value == null ? String.valueOf(def) : value.equals("yes") ? "true" : value.equals("no") ? "false" : value; + boolean b = Boolean.parseBoolean(correctedForYesNo); + if (b != check.isSelected()) { + check.doClick(); + check.setSelected(b); + } + logger.trace("BooleanFieldHandler -> value: {}", value); + } + } + + class BooleanValuesFieldHandler implements ActionListener, DictionaryListener { + + private JCheckBox check; + private String key; + private final String trueValue; + private final String falseValue; + + public BooleanValuesFieldHandler(String key, JCheckBox check, String trueValue, String falseValue) { + this.check = check; + this.key = key; + this.trueValue = trueValue; + this.falseValue = falseValue; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void actionPerformed(ActionEvent e) { + boolean selected = check.isSelected(); + dictionary.add(key, selected ? trueValue : falseValue); + logger.trace("BooleanValuesFieldHandler -> value: {}", dictionary.lookup(key)); + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + boolean selected = value != null && value.equals(trueValue); + if (shouldClick(selected, check.isSelected())) { + check.doClick(); + } + logger.trace("BooleanValuesFieldHandler -> value: {}", value); + } + + private boolean shouldClick(boolean select, boolean isSelected) { + return (isSelected && !select) || (!isSelected && select); + } + } + + class FileFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private FileFieldPanel field; + + public FileFieldHandler(String key, FileFieldPanel field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + if (field.getFilePath() != null && !field.getFilePath().isEmpty()) { + String value = "\"" + field.getFilePath() + "\""; + dictionary.add(key, value); + logger.trace("FileFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + loadFromDictionary(); + } + + private void loadFromDictionary() { + String value = dictionary.lookup(key); + if (value != null) { + value = value.replace("\"", ""); + File file = new File(value); + if (file.exists()) { + field.setFile(file); + } else { + field.setFile(new File("")); + // throw new DictionaryError("File doesn't exist: " + + // value); + } + } else { + field.setFile(new File("")); + } + } + } + + class PointFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private DoubleField[] field; + private FieldChangeListener listener; + + public PointFieldHandler(String key, DoubleField[] field, FieldChangeListener listener) { + this.key = key; + this.field = field; + this.listener = listener; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + StringBuilder sb = new StringBuilder(); + sb.append("("); + for (int i = 0; i < field.length; i++) { + if (field[i].getValue() != null) { + sb.append(field[i].getDoubleValue()); + sb.append(" "); + } else { + sb.append("0 "); + } + } + sb.append(")"); + dictionary.add(key, sb.toString()); + logger.trace("PointFieldHandler -> value: {}", dictionary.lookup(key)); + if (listener != null) { + listener.fieldChanged(); + } + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + if (listener != null) + listener.setAdjusting(true); + if (value != null && !value.isEmpty()) { + try { + String[] values = value.trim().substring(1, value.length() - 1).trim().split("\\s+"); + for (int i = 0; i < values.length; i++) { + field[i].setDoubleValue(parseDouble(values[i])); + } + } catch (ArrayIndexOutOfBoundsException e) { + } + logger.trace("PointFieldHandler -> value: {}", value); + } else { + for (int i = 0; i < field.length; i++) { + field[i].setDoubleValue(0); + } + } + if (listener != null) + listener.setAdjusting(false); + } + } + + class PointUniformFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private DoubleField[] field; + + public PointUniformFieldHandler(String key, DoubleField[] field) { + this.key = key; + this.field = field; + DictionaryModel.this.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + for (int i = 0; i < field.length; i++) { + if (Double.isInfinite(field[i].getDoubleValue())) { + return; + } + } + StringBuilder sb = new StringBuilder(); + sb.append("uniform ("); + for (int i = 0; i < field.length; i++) { + sb.append(field[i].getDoubleValue()); + sb.append(" "); + } + sb.append(")"); + dictionary.add(key, sb.toString()); + logger.trace("PointFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + String value = dictionary.lookup(key); + if (value != null) { + if (value.startsWith("nonuniform")) { + for (int i = 0; i < field.length; i++) { + field[i].setDoubleValue(Double.POSITIVE_INFINITY); + } + } else { + value = value.replace("uniform ", ""); + String[] values = value.trim().substring(1, value.length() - 1).trim().split("\\s+"); + for (int i = 0; i < values.length; i++) { + field[i].setDoubleValue(parseDouble(values[i])); + } + } + logger.trace("PointFieldHandler -> value: {}", value); + } else { + for (int i = 0; i < field.length; i++) { + field[i].setDoubleValue(0); + } + } + } + } + + class SelectFieldHandler implements ActionListener, DictionaryListener { + + private JComboBox combo; + private String key; + private SelectionValueConfigurator configurator; + + public SelectFieldHandler(String key, JComboBox combo, SelectionValueConfigurator configurator) { + this.combo = combo; + this.key = key; + this.configurator = configurator; + DictionaryModel.this.addDictionaryListener(this); + try { + loadFromDictionary(); + } catch (DictionaryError e) { + // e.printStackTrace(); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + Object item; + if (combo instanceof JComboBoxController) { + item = ((JComboBoxController) combo).getSelectedKey(); + } else { + item = combo.getSelectedItem(); + } + if (item != null && item instanceof String) { + String value = (String) item; + if (configurator != null) + value = configurator.write(value); + if (value != null) + dictionary.add(key, value); + logger.trace("SelectFieldHandler -> value: {}", dictionary.lookup(key)); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + loadFromDictionary(); + } + + public void loadFromDictionary() throws DictionaryError { + if (dictionary.found(key)) { + String value = dictionary.lookup(key); + if (configurator != null) + value = configurator.read(value); + + if (combo instanceof JComboBoxController) { + ((JComboBoxController) combo).setSelectedKey(value); + } else if (contains(value)) { + combo.setSelectedItem(value); + } else if (value == null || "".equals(value)) { + combo.setSelectedIndex(-1); + } else if (combo.getItemCount() > 0) { + combo.setSelectedIndex(0); + throw new DictionaryError(String.format("Missing %s value. Set to %s", value, combo.getItemAt(0))); + } + + logger.trace("SelectFieldHandler -> value: {}", value); + } else { + combo.setSelectedIndex(-1); + // throw new + // DictionaryError(String.format("Missing %s key in %s dictionary", + // key, dictionary.getName())); + } + } + + private boolean contains(String value) { + for (int i = 0; i < combo.getItemCount(); i++) { + if (value.equals(combo.getItemAt(i))) { + return true; + } + } + return false; + } + + } + + public String getKey() { + return key != null ? key : String.valueOf(hashCode()); + } + + private double parseDouble(String value) { + try { + return Double.parseDouble(value); + } catch (Exception e) { + return 0; + } + } + + private int parseInt(String value) { + try { + return Double.valueOf(value).intValue(); + } catch (Exception e) { + return 0; + } + } +} diff --git a/src/eu/engys/core/dictionary/model/DictionaryPanelBuilder.java b/src/eu/engys/core/dictionary/model/DictionaryPanelBuilder.java new file mode 100644 index 0000000..eb695b8 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/DictionaryPanelBuilder.java @@ -0,0 +1,206 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary.model; + +import static eu.engys.core.dictionary.Dictionary.TYPE; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.util.ui.builder.GroupController; +import eu.engys.util.ui.builder.PanelBuilder; + +public class DictionaryPanelBuilder extends PanelBuilder { + + private static final Logger logger = LoggerFactory.getLogger(DictionaryPanelBuilder.class); + + private DictionaryModel selectedModel; + private Map modelsByKey = new HashMap(); + private Map dictionarySelectors = new HashMap(); + + private boolean selectModelAfterSelection = true; + + public DictionaryPanelBuilder() { + super(); + } + + public DictionaryPanelBuilder(String name) { + super(name); + } + + public void startDictionary(String groupName, DictionaryModel model) { + String groupKey = model.getKey(); + + startGroup(groupKey, groupName); + + modelsByKey.put(groupKey, model); + dictionarySelectors.put(groupKey, new DictionarySelector(controllers, groups)); + + checkForParent(); + } + + public void endDictionary() { + modelsByKey.get(groups.peek().groupKey).refresh(); + endGroup(); + } + + public DictionaryModel getSelectedModel() { + return selectedModel; + } + + private void setSelectedModel(DictionaryModel selectedModel) { + if (selectedModel != null) { + this.selectedModel = selectedModel; + } + } + + public void selectDictionaries(Dictionary newDictionary, Dictionary newCompanion) { + String newName = newDictionary.getName(); + String newType = newDictionary.lookup(TYPE); + String newCompanionType = newCompanion.lookup(TYPE); + // System.out.println("ChoicePanelBuilder.selectDictionary() NEW TYPE: "+newType+" NEW NAME: "+newName+" NEW COMPANION TYPE: "+newCompanionType); + // System.out.println("-------------------"); + for (String key : modelsByKey.keySet()) { + DictionaryModel model = modelsByKey.get(key); + Dictionary oldDictionary = model.getDictionary(); + if (model.getCompanions().size() > 0) { + Dictionary oldCompanion = model.getCompanions().get(0).getDictionary(); + String oldName = oldDictionary.getName(); + String oldType = oldDictionary.lookup(TYPE); + String oldCompanionType = oldCompanion.lookup(TYPE); + // System.out.println("DictionaryPanelBuilder.selectDictionaries() OLD TYPE: "+oldType+" OLD NAME: "+oldName+" OLD COMPANION TYPE: "+oldCompanionType); + + if (newName.equals(oldName) && newType.equals(oldType) && newCompanionType.equals(oldCompanionType)) { + // System.out.println("DictionaryPanelBuilder.selectDictionaries() FOUND"); + dictionarySelectors.get(key).select(); + selectedModel.setDictionary(newDictionary); + + DictionaryModel companion = selectedModel.getCompanions().get(0); + if (companion != null) { + companion.setDictionary(newCompanion); + } + return; + } + } + } + // System.out.println("DictionaryPanelBuilder.selectDictionaries() NOT FOUND"); + } + + public void selectDictionary(Dictionary newDictionary) { + if (newDictionary != null /* && newDictionary.found(TYPE) */) { + String newName = newDictionary.getName(); + String newType = newDictionary.lookup(TYPE); + + // System.out.println("DictionaryPanelBuilder.selectDictionary() NEW TYPE: "+newType+" NEW NAME: "+newName); + if (newName != null && newType != null) { + for (String key : modelsByKey.keySet()) { + DictionaryModel model = modelsByKey.get(key); + if (model.getCompanions().size() == 0) { + Dictionary oldDictionary = model.getDictionary(); + String oldName = oldDictionary.getName(); + String oldType = oldDictionary.lookup(TYPE); + + // System.out.println("DictionaryPanelBuilder.selectDictionary() OLD TYPE: "+oldType+" OLD NAME: "+oldName); + + if (newName.equals(oldName) && newType.equals(oldType)) { + // System.out.println("DictionaryPanelBuilder.selectDictionary() FOUND"); + dictionarySelectors.get(key).select(); + selectedModel.setDictionary(newDictionary); + return; + } + } + } + logger.warn("NOT FOUND: if the model you are trying to select has a companion, use the metod 'selectDictionaries(dictionary,companion) ' instead"); + } else { + logger.warn("DICTIONARY NAME OR TYPE ARE NULL. NAME: {}, TYPE: {}", newName, newType); + } + } else { + logger.warn("NULL DICTIONARY"); + } + } + + public void setShowing(String hideable, String group) { + selectModelAfterSelection = false; + super.setShowing(hideable, group); + selectModelAfterSelection = true; + } + + public void selectDictionaryByModel(DictionaryModel model, Dictionary newDictionary) { + String key = model.getKey(); + dictionarySelectors.get(key).select(); + selectedModel.setDictionary(newDictionary); + } + + public void selectDictionaryByKey(String key, Dictionary newDictionary) { + dictionarySelectors.get(key).select(); + selectedModel.setDictionary(newDictionary); + } + + @Override + protected void afterSelection(String selectedKey) { + super.afterSelection(selectedKey); + DictionaryModel model = modelsByKey.get(selectedKey); + // System.out.println("DictionaryPanelBuilder.afterSelection() "+selectedKey); + if (model != null && selectModelAfterSelection) { + setSelectedModel(model); + model.refresh(); + if (model.getCompanions().size() > 0) { + model.getCompanions().get(0).refresh(); + } + } else { + // System.err.println("setSelectedModel -> -> -> -> -> -> Model is NULLLL"); + } + } + + class DictionarySelector { + + private List controllersStack = new ArrayList(); + private List groupsStack = new ArrayList(); + + public DictionarySelector(Stack controllers, Stack groups) { + this.controllersStack.addAll(controllers); + this.groupsStack.addAll(groups); + } + + public void select() { + for (int i = 0; i < controllersStack.size(); i++) { + GroupController controller = controllersStack.get(i); + KeydRowGroup group = groupsStack.get(i); + // System.out.println("DictionaryPanelBuilder.DictionarySelector.select() ["+i+"] "+group.groupKey); + controller.setSelectedKey(group.groupKey); + } + } + + } + +} diff --git a/src/eu/engys/core/dictionary/model/DictionaryTableAdapter.java b/src/eu/engys/core/dictionary/model/DictionaryTableAdapter.java new file mode 100644 index 0000000..dfbea5a --- /dev/null +++ b/src/eu/engys/core/dictionary/model/DictionaryTableAdapter.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary.model; + +import eu.engys.core.dictionary.model.DictionaryModel.DictionaryListener; + +public abstract class DictionaryTableAdapter extends AbstractTableAdapter { + + protected DictionaryModel dictionaryModel; + + public DictionaryTableAdapter(DictionaryModel dictionaryModel, String[] columnNames) { + super(columnNames); + this.dictionaryModel = dictionaryModel; + dictionaryModel.addDictionaryListener(new DictionaryListener() { + @Override + public void dictionaryChanged() { + clear(); + load(); + } + }); + } + + public DictionaryTableAdapter(DictionaryModel dictionaryModel, String[] columnNames, String rowsLabel, Integer linesToLeave, boolean showColumnNames) { + super(columnNames, rowsLabel, linesToLeave, showColumnNames); + this.dictionaryModel = dictionaryModel; + dictionaryModel.addDictionaryListener(new DictionaryListener() { + @Override + public void dictionaryChanged() { + clear(); + load(); + } + }); + } + + public void setDictionaryModel(DictionaryModel dictionaryModel) { + this.dictionaryModel = dictionaryModel; + } + +} diff --git a/src/eu/engys/core/dictionary/model/EventActionType.java b/src/eu/engys/core/dictionary/model/EventActionType.java new file mode 100644 index 0000000..086d797 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/EventActionType.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary.model; + +public enum EventActionType { + SHOW, HIDE, REMOVE; + + public void isShow() { + this.equals(SHOW); + } + + public void isHide() { + this.equals(HIDE); + } + + public void isRemove() { + this.equals(REMOVE); + } +} diff --git a/src/eu/engys/core/dictionary/model/LevelsTableAdapter.java b/src/eu/engys/core/dictionary/model/LevelsTableAdapter.java new file mode 100644 index 0000000..4adb732 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/LevelsTableAdapter.java @@ -0,0 +1,129 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.model; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import javax.swing.JComponent; +import javax.swing.JTextField; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; + +public class LevelsTableAdapter extends DictionaryTableAdapter { + + protected final String[] columnNames; + private static final String DICTKEY = "levels"; + private static final String MODE = "distance"; + private final Class[] type; + + public LevelsTableAdapter(DictionaryModel dictionaryModel, String[] names, final Class[] type) { + super(dictionaryModel, names); + this.columnNames = names; + this.type = type; + } + + @Override + protected void addRow() { + JTextField[] fields = new JTextField[2]; + fields[0] = new DoubleField(); + fields[1] = new IntegerField(); + addRow(fields); + } + + @Override + public void load() { + Dictionary dictionary = dictionaryModel.getDictionary(); + if (MODE.equals(dictionary.lookup("mode")) && dictionary.isField(DICTKEY)) { + String value = dictionary.lookup(DICTKEY); + if (value != null && value.startsWith("(") && value.endsWith(")")) { + value = value.substring(1, value.length() - 1); + try { + Pattern regex = Pattern.compile("\\((\\s*\\d+\\.?\\d+)\\s*(\\d+\\s*)\\)"); + Matcher regexMatcher = regex.matcher(value); + while (regexMatcher.find()) { + JTextField[] row = new JTextField[type.length]; + for (int j = 1; j <= regexMatcher.groupCount(); j++) { + String cellValue = regexMatcher.group(j).trim(); + int i = j - 1; + Class klass = type[i]; + if (klass == Integer.class) { + row[i] = new IntegerField(); + ((IntegerField) row[i]).setIntValue(Integer.valueOf(cellValue)); + } else if (klass == Double.class) { + row[i] = new DoubleField(); + ((DoubleField) row[i]).setDoubleValue(Double.valueOf(cellValue)); + } else { + row[i] = new JTextField(); + } + } + addRow(row); + } + } catch (PatternSyntaxException ex) { + // Syntax error in the regular expression + } + } + } + } + + @Override + protected void save() { + if (getRowsMap().isEmpty()) { + dictionaryModel.getDictionary().remove(DICTKEY); + return; + } + StringBuilder sb = new StringBuilder(); + sb.append("( "); + + TreeMap orderedMap = getOrderedMap(); + for (Integer key : orderedMap.descendingKeySet()) { + sb.append("( "); + sb.append(orderedMap.get(key)); + sb.append(" "); + sb.append(key); + sb.append(" )"); + sb.append(" "); + } + sb.append(")"); + dictionaryModel.getDictionary().add(DICTKEY, sb.toString()); + } + + private TreeMap getOrderedMap() { + Map map = new HashMap<>(); + for (JComponent[] row : getRowsMap().values()) { + map.put(((IntegerField) row[1]).getIntValue(), ((DoubleField) row[0]).getDoubleValue()); + } + return new TreeMap(map); + } + +} diff --git a/src/eu/engys/core/dictionary/model/LinesTableAdapter.java b/src/eu/engys/core/dictionary/model/LinesTableAdapter.java new file mode 100644 index 0000000..1dfa915 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/LinesTableAdapter.java @@ -0,0 +1,191 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.model; + +import java.awt.BorderLayout; +import java.awt.Dialog.ModalityType; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; + +public class LinesTableAdapter extends DictionaryTableAdapter { + + private static final String LEVELS = "levels"; + private static final String LEVEL = "level"; + private Dictionary lineDictionary; + private final Class[] type; + + public LinesTableAdapter(DictionaryModel dictionaryModel, Dictionary lineDictionary, String[] columnNames, final Class[] type) { + super(dictionaryModel, columnNames, "", LEAVE_ONE_LINE, true); + this.lineDictionary = lineDictionary; + this.type = type; + fixOldStyleLevels(); + } + + public JButton getButton() { + JButton b = new JButton(new AbstractAction("Edit") { + @Override + public void actionPerformed(ActionEvent e) { + getDialog().setVisible(true); + } + + }); + return b; + } + + private JDialog getDialog() { + final JDialog dialog = new JDialog(UiUtil.getActiveWindow(), "Refinement Level", ModalityType.MODELESS); + dialog.setName("line.adapter.dialog"); + + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + JButton okButton = new JButton(new AbstractAction("OK") { + @Override + public void actionPerformed(ActionEvent e) { + save(); + dialog.setVisible(false); + } + }); + okButton.setName("OK"); + buttonsPanel.add(okButton); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(new JScrollPane(this), BorderLayout.CENTER); + mainPanel.add(buttonsPanel, BorderLayout.SOUTH); + + dialog.add(mainPanel); + dialog.setSize(600, 400); + dialog.setLocationRelativeTo(null); + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.getRootPane().setDefaultButton(okButton); + return dialog; + } + + private void fixOldStyleLevels() { + if (lineDictionary.found(LEVEL)) { + Dictionary clone = new Dictionary(lineDictionary); + String levelValue = clone.lookup(LEVEL); + clone.remove(LEVEL); + clone.add(LEVELS, "( ( 0.0 " + levelValue + " ) )"); + this.lineDictionary = clone; + } + } + + public Dictionary getLineDictionary() { + return lineDictionary; + } + + @Override + protected void addRow() { + JTextField[] fields = new JTextField[2]; + fields[0] = new DoubleField(); + fields[1] = new IntegerField(); + addRow(fields); + } + + @Override + public void load() { + String value = lineDictionary.lookup(LEVELS); + if (value != null && value.startsWith("(") && value.endsWith(")")) { + value = value.substring(1, value.length() - 1); + try { + Pattern regex = Pattern.compile("\\((\\s*\\d+\\.?\\d+)\\s*(\\d+\\s*)\\)"); + Matcher regexMatcher = regex.matcher(value); + while (regexMatcher.find()) { + JTextField[] row = new JTextField[type.length]; + for (int j = 1; j <= regexMatcher.groupCount(); j++) { + String cellValue = regexMatcher.group(j).trim(); + int i = j - 1; + Class klass = type[i]; + if (klass == Integer.class) { + row[i] = new IntegerField(); + ((IntegerField) row[i]).setIntValue(Integer.valueOf(cellValue)); + } else if (klass == Double.class) { + row[i] = new DoubleField(); + ((DoubleField) row[i]).setDoubleValue(Double.valueOf(cellValue)); + } else { + row[i] = new JTextField(); + } + } + addRow(row); + } + } catch (PatternSyntaxException ex) { + ex.printStackTrace(); + } + } + if (getRowsMap().isEmpty()) { + addRow(); + } + } + + @Override + protected void save() { + if (getRowsMap().isEmpty()) { + lineDictionary.remove(LEVELS); + return; + } + StringBuilder sb = new StringBuilder(); + TreeMap orderedMap = getOrderedMap(); + sb.append("( "); + for (Integer key : orderedMap.descendingKeySet()) { + sb.append("( "); + sb.append(orderedMap.get(key)); + sb.append(" "); + sb.append(key); + sb.append(" )"); + sb.append(" "); + } + sb.append(")"); + lineDictionary.add(LEVELS, sb.toString()); + } + + private TreeMap getOrderedMap() { + Map map = new HashMap<>(); + for (JComponent[] row : getRowsMap().values()) { + map.put(((IntegerField) row[1]).getIntValue(), ((DoubleField) row[0]).getDoubleValue()); + } + return new TreeMap(map); + } + +} diff --git a/src/eu/engys/core/dictionary/model/OneDictionaryPerRowTableAdapter.java b/src/eu/engys/core/dictionary/model/OneDictionaryPerRowTableAdapter.java new file mode 100644 index 0000000..c049afa --- /dev/null +++ b/src/eu/engys/core/dictionary/model/OneDictionaryPerRowTableAdapter.java @@ -0,0 +1,188 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.model; + +import static eu.engys.util.Symbols.DOT; + +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; +import eu.engys.util.ui.textfields.StringField; + +public class OneDictionaryPerRowTableAdapter extends DictionaryTableAdapter { + + private final int NAME_COL = 0; + protected final String[] columnNames; + protected final String[] columnKeys; + protected final String[] rowNames; + protected final String[] rowKeys; + protected final String dictKey; + + protected final Class[] type; + + public static void main(String[] args) { + String[] columnNames = { "Name", "Thickness [m]", "Conductivity [W/K" + DOT + "m]" }; + String[] columnKeys = { "thickness", "lambda" }; + Class[] type = { String.class, Double.class, Double.class }; + + JPanel table = new OneDictionaryPerRowTableAdapter(new DictionaryModel(), columnNames, columnKeys, null, null, "layers", type); + JFrame f = UiUtil.defaultTestFrame("test", table); + f.setSize(600, 600); + f.setVisible(true); + } + + public OneDictionaryPerRowTableAdapter(DictionaryModel dictionaryModel, String[] columnNames, String[] columnKeys, String[] rowNames, String[] rowKeys, String key, Class[] type) { + super(dictionaryModel, columnNames); + this.columnNames = columnNames; + this.columnKeys = columnKeys; + this.rowNames = rowNames; + this.rowKeys = rowKeys; + this.dictKey = key; + this.type = type; + + setName("one.dict.row"); + + if (isStaticTable()) { + setRowHeader(); + hideButtonsPanel(); + } + } + + @Override + protected void addRow() { + if (!isStaticTable()) { + JTextField[] row = new JTextField[type.length]; + for (int i = 0; i < type.length; i++) { + Class klass = type[i]; + if (klass == Integer.class) { + row[i] = new IntegerField(); + ((IntegerField) row[i]).setIntValue(Integer.valueOf(0)); + } else if (klass == Double.class) { + row[i] = new DoubleField(); + ((DoubleField) row[i]).setDoubleValue(Integer.valueOf(0)); + } else if (klass == String.class) { + row[i] = new StringField("name" + (getRowsMap().size() + 1)); + } else { + row[i] = new StringField(""); + } + } + addRow(row); + } + } + + private boolean isStaticTable() { + return rowNames != null; + } + + public void setRowHeader() { + for (int i = 0; i < rowNames.length; i++) { + JComponent[] row = new JComponent[columnKeys.length + 1]; + row[0] = new JLabel(rowNames[i]); + for (int j = 1; j < row.length; j++) { + Class klass = type[j]; + if (klass == Integer.class) { + row[j] = new IntegerField(); + ((IntegerField) row[j]).setIntValue(Integer.valueOf(0)); + } else if (klass == Double.class) { + row[j] = new DoubleField(); + ((DoubleField) row[j]).setDoubleValue(Double.valueOf(0)); + } else { + row[j] = new JLabel(""); + } + } + addRow(row, false); + } + } + + @Override + public void load() { + if (dictionaryModel.getDictionary().found(dictKey)) { + Dictionary dict = dictionaryModel.getDictionary().subDict(dictKey); + if (isStaticTable() && dict.getDictionaries().size() != rowKeys.length) { + setRowHeader(); + } else { + int rowIndex = 0; + for (Dictionary d : dict.getDictionaries()) { + JComponent[] row = new JComponent[columnKeys.length + 1]; + if (isStaticTable()) + row[0] = new JLabel(rowKeys[rowIndex]); + else + row[0] = new StringField(d.getName()); + + for (int k = 0; k < columnKeys.length; k++) { + String value = d.lookup(columnKeys[k]); + int j = k + 1; + if (value == null) + row[j] = new JTextField("0"); + else if (type[j] == Double.class) { + row[j] = new DoubleField(); + ((DoubleField) row[j]).setDoubleValue(Double.valueOf(value)); + } else if (type[j] == Integer.class) { + row[j] = new IntegerField(); + ((IntegerField) row[j]).setIntValue(Integer.valueOf(value)); + } else { + row[j] = new JLabel(value); + } + } + addRow(row); + rowIndex++; + } + } + } + } + + @Override + protected void save() { + Dictionary layers = new Dictionary(dictKey); + for (int r = 0; r < getRowsMap().values().size(); r++) { + String name; + if (isStaticTable()) { + name = rowKeys[r]; + } else { + JComponent[][] fields = getRowsMap().values().toArray(new JComponent[0][0]); + name = String.valueOf(((JTextField) fields[r][NAME_COL]).getText()); + } + + Dictionary layer = new Dictionary(name); + for (int k = 0; k < columnKeys.length; k++) { + JComponent[][] fields = getRowsMap().values().toArray(new JComponent[0][0]); + String value = String.valueOf(((JTextField) fields[r][k + 1]).getText()); + layer.add(columnKeys[k], value); + } + layers.add(layer); + } + dictionaryModel.getDictionary().add(layers); + } + +} diff --git a/src/eu/engys/core/dictionary/model/PatchesMapTableAdapter.java b/src/eu/engys/core/dictionary/model/PatchesMapTableAdapter.java new file mode 100644 index 0000000..0d1eb13 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/PatchesMapTableAdapter.java @@ -0,0 +1,162 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.model; + +import static eu.engys.core.project.system.MapFieldsDict.PATCH_MAP_KEY; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JComboBox; +import javax.swing.JOptionPane; + +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.util.ui.UiUtil; + +public class PatchesMapTableAdapter extends DictionaryTableAdapter { + + private Patches sourcePatches = new Patches(); + private Patches targetPatches; + private ActionListener sourceListener; + private ActionListener targetListener; + + public PatchesMapTableAdapter(DictionaryModel dictionaryModel, Patches targetPatches) { + super(dictionaryModel, new String[] { "Source", "Target" }); + this.targetPatches = targetPatches; + this.sourceListener = new SourceComboActionListener(); + this.targetListener = new TargetComboActionListener(); + } + + public void updateSourceList(Patches sourcePatches) { + this.sourcePatches = sourcePatches; + } + + @SuppressWarnings("unchecked") + @Override + protected void addRow() { + JComboBox[] fields = new JComboBox[2]; + fields[0] = new JComboBox(); + for (Patch sp : sourcePatches) { + fields[0].addItem(sp.getName()); + } + fields[0].setSelectedIndex(-1); + fields[0].addActionListener(sourceListener); + + fields[1] = new JComboBox(); + for (Patch sp : targetPatches) { + fields[1].addItem(sp.getName()); + } + fields[1].setSelectedIndex(-1); + fields[1].addActionListener(targetListener); + + addRow(fields, false); + } + + @SuppressWarnings("unchecked") + @Override + public void load() { + String patchMap = dictionaryModel.getDictionary().lookup(PATCH_MAP_KEY); + String[] patches = DictionaryUtils.string2StringArray(patchMap); + + for (int i = 0; i < patches.length; i += 2) { + JComboBox[] fields = new JComboBox[2]; + fields[0] = new JComboBox(); + fields[0].removeActionListener(sourceListener); + for (Patch sp : sourcePatches) { + fields[0].addItem(sp.getName()); + } + fields[0].setSelectedItem(patches[i]); + fields[0].addActionListener(sourceListener); + + fields[1] = new JComboBox(); + fields[1].removeActionListener(targetListener); + for (Patch sp : targetPatches) { + fields[1].addItem(sp.getName()); + } + fields[1].setSelectedItem(patches[i + 1]); + fields[1].addActionListener(targetListener); + + addRow(fields, false); + } + } + + @SuppressWarnings("unchecked") + @Override + public void save() { + dictionaryModel.getDictionary().remove(PATCH_MAP_KEY); + + StringBuilder sb = new StringBuilder("("); + for (Integer key : getRowsMap().keySet()) { + JComboBox[] comps = (JComboBox[]) getRowsMap().get(key); + if(comps[0].getSelectedIndex() > -1){ + sb.append((String) comps[0].getSelectedItem() + " "); + sb.append((String) comps[1].getSelectedItem() + " "); + } + } + sb.append(")"); + dictionaryModel.getDictionary().add(PATCH_MAP_KEY, sb.toString()); + } + + private class SourceComboActionListener implements ActionListener { + + @SuppressWarnings("unchecked") + @Override + public void actionPerformed(ActionEvent e) { + JComboBox combo = ((JComboBox) e.getSource()); + for (Integer key : getRowsMap().keySet()) { + JComboBox sourceCombo = (JComboBox) getRowsMap().get(key)[0]; + if (sourceCombo != combo && sourceCombo.getSelectedItem() !=null && sourceCombo.getSelectedItem().equals(combo.getSelectedItem())) { + combo.hidePopup(); + combo.setSelectedIndex(-1); + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Source patch already used", "Fields Map Error", JOptionPane.ERROR_MESSAGE); + return; + } + } + } + } + + private class TargetComboActionListener implements ActionListener { + + @SuppressWarnings("unchecked") + @Override + public void actionPerformed(ActionEvent e) { + JComboBox combo = ((JComboBox) e.getSource()); + for (Integer key : getRowsMap().keySet()) { + JComboBox targetCombo = (JComboBox) getRowsMap().get(key)[1]; + if (targetCombo != combo && targetCombo.getSelectedItem() != null && targetCombo.getSelectedItem().equals(combo.getSelectedItem())) { + combo.hidePopup(); + combo.setSelectedIndex(-1); + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Target patch already used", "Fields Map Error", JOptionPane.ERROR_MESSAGE); + return; + } + } + } + } + +} diff --git a/src/eu/engys/core/dictionary/model/PointInfo.java b/src/eu/engys/core/dictionary/model/PointInfo.java new file mode 100644 index 0000000..89c0dd8 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/PointInfo.java @@ -0,0 +1,64 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary.model; + +import java.awt.Color; + +import eu.engys.util.ui.textfields.DoubleField; + +public class PointInfo { + + public static final String PROPERTY_NAME = "point.location"; + public static final String LABEL = "Point "; + private DoubleField[] field; + private Color color; + private String key; + private EventActionType action; + + public PointInfo(DoubleField[] field, String key, EventActionType action, Color color) { + this.field = field; + this.key = key; + this.action = action; + this.color = color; + } + + public DoubleField[] getPoint() { + return field; + } + + public String getKey() { + return key; + } + + public EventActionType getAction() { + return action; + } + + public Color getColor() { + return color; + } + +} diff --git a/src/eu/engys/core/dictionary/model/PointTableAdapter.java b/src/eu/engys/core/dictionary/model/PointTableAdapter.java new file mode 100644 index 0000000..aa8c7e2 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/PointTableAdapter.java @@ -0,0 +1,175 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.model; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import javax.swing.JComponent; +import javax.swing.JToggleButton; + +import eu.engys.util.ColorUtil; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.textfields.DoubleField; + +public class PointTableAdapter extends DictionaryTableAdapter { + + private String dictKey; + private List buttons; + private List visibility; + private final boolean showPoint; + + public PointTableAdapter(DictionaryModel dictionaryModel, String[] columnNames, String dictKey, int linesToLeave, boolean showPoint) { + super(dictionaryModel, columnNames, PointInfo.LABEL, linesToLeave, false); + this.dictKey = dictKey; + this.showPoint = showPoint; + this.buttons = new LinkedList<>(); + this.visibility = new LinkedList(); + } + + @Override + protected void addRow() { + DoubleField[] fields = ComponentsFactory.doublePointField(4); + addRow(fields); + } + + @Override + protected void removeRow() { + updateVisibilityList(); + super.removeRow(); + visibility.clear(); + } + + private void updateVisibilityList() { + visibility.clear(); + for (int i = 0; i < buttons.size() - 1; i++) { + visibility.add(buttons.get(i).isSelected()); + } + turnOffPointsIn3D(); + buttons.clear(); + } + + @Override + protected JComponent[] createComponent(final JComponent[] field) { + if (showPoint) { + List comps = new ArrayList(Arrays.asList(field)); + JToggleButton showMaterialPoint = null; + if (visibility.size() > getRowsMap().size()) { + showMaterialPoint = ShowLocationAdapter.newShowPointButton((DoubleField[]) field, getRowsMap().size(), visibility.get(getRowsMap().size())); + } else { + showMaterialPoint = ShowLocationAdapter.newShowPointButton((DoubleField[]) field, getRowsMap().size(), false); + } + showMaterialPoint.getAction().addPropertyChangeListener(new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if(evt.getPropertyName().equals(PointInfo.PROPERTY_NAME)){ + firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); + } + } + }); + + buttons.add(showMaterialPoint); + comps.add(showMaterialPoint); + return comps.toArray(new JComponent[0]); + } else { + return field; + } + } + + @Override + protected void triggerEventFor3D(JComponent[] comp) { + String key = ColorUtil.getColor(getRowsMap().size()).toString(); + firePropertyChange(PointInfo.PROPERTY_NAME, null, new PointInfo((DoubleField[]) comp, key, EventActionType.REMOVE, null)); + } + + public void turnOffPointsIn3D() { + for (JToggleButton b : buttons) { + if (b.isSelected()) { + b.doClick(); + } + } + } + + @Override + public void load() { + turnOffPointsIn3D(); + buttons.clear(); + String value = dictionaryModel.getDictionary().lookup(dictKey); + if (value != null && value.startsWith("(") && value.endsWith(")")) { + value = value.substring(1, value.length() - 1).trim(); + try { + Pattern regex = Pattern.compile("(\\([^\\)]*\\))"); + Matcher regexMatcher = regex.matcher(value); + + while (regexMatcher.find()) { + DoubleField[] fields = new DoubleField[3]; + String row = regexMatcher.group().trim(); + Pattern rowRegex = Pattern.compile("(\\s*\\-?\\d*\\.?\\d+([eE][-+]?[0-9]+)*\\s*)"); + Matcher rowRegexMatcher = rowRegex.matcher(row); + + int columnCounter = 0; + while (rowRegexMatcher.find()) { + fields[columnCounter] = new DoubleField(); + fields[columnCounter].setDoubleValue(Double.valueOf(rowRegexMatcher.group().trim())); + if (columnCounter > fields.length) { + break; + } + columnCounter++; + } + addRow(fields); + } + } catch (PatternSyntaxException ex) { + // Syntax error in the regular expression + } + } + } + + @Override + protected void save() { + StringBuilder sb = new StringBuilder(); + sb.append("( "); + for (JComponent[] row : getRowsMap().values()) { + sb.append("( "); + for (DoubleField doubleField : (DoubleField[]) row) { + sb.append(doubleField.getDoubleValue()); + sb.append(" "); + } + sb.append(")"); + sb.append(" "); + } + sb.append(")"); + dictionaryModel.getDictionary().add(dictKey, sb.toString()); + } +} diff --git a/src/eu/engys/core/dictionary/model/ShowAxisAdapter.java b/src/eu/engys/core/dictionary/model/ShowAxisAdapter.java new file mode 100644 index 0000000..f556783 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/ShowAxisAdapter.java @@ -0,0 +1,112 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.model; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JToggleButton; + +import net.java.dev.designgridlayout.Componentizer; +import eu.engys.util.ui.textfields.DoubleField; + +public class ShowAxisAdapter extends JPanel { + + private static final ImageIcon ICON_ON = new ImageIcon(AbstractTableAdapter.class.getClassLoader().getResource("eu/engys/resources/images/lightbulb16.png")); + private static final ImageIcon ICON_OFF = new ImageIcon(AbstractTableAdapter.class.getClassLoader().getResource("eu/engys/resources/images/lightbulb_off16.png")); + + private JToggleButton button; + private DoubleField[] axis; + private DoubleField[] centre; + + public ShowAxisAdapter(DoubleField[] axis, DoubleField[] centre) { + super(new BorderLayout()); + this.axis = axis; + this.centre = centre; + this.button = newShowAxisButton(false); + JComponent component = Componentizer.create().minAndMore(centre).minToPref(button).component(); + add(component, BorderLayout.CENTER); + } + + @Override + public void setName(String name) { + super.setName(name); + button.setName(getName()+".button"); + axis[0].setName(getName()+".axis.0"); + axis[1].setName(getName()+".axis.1"); + axis[2].setName(getName()+".axis.2"); + centre[0].setName(getName()+".centre.0"); + centre[1].setName(getName()+".centre.1"); + centre[2].setName(getName()+".centre.2"); + } + + @Override + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + super.addPropertyChangeListener(propertyName, listener); + if (propertyName.equals("point.location")) { + button.getAction().addPropertyChangeListener(listener); + } + } + + public void turnOff() { + if (button.isSelected()) { + button.doClick(); + } + } + + public JToggleButton newShowAxisButton(boolean selected) { + final JToggleButton button = new JToggleButton(new AbstractAction() { + // private Border originalBorder; + + @Override + public void actionPerformed(ActionEvent e) { + AbstractButton b = ((AbstractButton) e.getSource()); + if (b.isSelected()) { + firePropertyChange(PointInfo.PROPERTY_NAME, null, new AxisInfo(axis, centre, EventActionType.SHOW)); + } else { + firePropertyChange(PointInfo.PROPERTY_NAME, null, new AxisInfo(axis, centre, EventActionType.HIDE)); + } + } + }); + if (selected && !button.isSelected() || (!selected && button.isSelected())) { + button.doClick(); + } + button.setPreferredSize(new Dimension(22, 22)); + button.setIcon(ICON_OFF); + button.setSelectedIcon(ICON_ON); + button.setToolTipText("Click to display this point in the 3D canvas"); + return button; + } + +} diff --git a/src/eu/engys/core/dictionary/model/ShowLocationAdapter.java b/src/eu/engys/core/dictionary/model/ShowLocationAdapter.java new file mode 100644 index 0000000..72f99f0 --- /dev/null +++ b/src/eu/engys/core/dictionary/model/ShowLocationAdapter.java @@ -0,0 +1,125 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary.model; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JToggleButton; +import javax.swing.border.Border; + +import net.java.dev.designgridlayout.Componentizer; +import eu.engys.util.ColorUtil; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.textfields.DoubleField; + +public class ShowLocationAdapter extends JPanel { + + private static final Icon ICON_ON = ResourcesUtil.getResourceIcon("eu/engys/resources/images/lightbulb16.png"); + private static final Icon ICON_OFF = ResourcesUtil.getResourceIcon("eu/engys/resources/images/lightbulb_off16.png"); + + private JToggleButton button; + private DoubleField[] fields; + + public ShowLocationAdapter(DoubleField[] fields, Color key) { + super(new BorderLayout()); + this.fields = fields; + this.button = newShowPointButton(fields, key, false); + JComponent component = Componentizer.create().minAndMore(fields).minToPref(button).component(); + add(component, BorderLayout.CENTER); + } + + @Override + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + super.addPropertyChangeListener(propertyName, listener); + if (propertyName.equals(PointInfo.PROPERTY_NAME)) { + button.getAction().addPropertyChangeListener(listener); + } + } + + public void turnMaterialPointsOn() { + if (!button.isSelected()) { + button.doClick(); + } + } + + public void turnMaterialPointsOff() { + if (button.isSelected()) { + button.doClick(); + } + } + + public static JToggleButton newShowPointButton(final DoubleField[] locationInMesh, int index, boolean selected) { + return newShowPointButton(locationInMesh, ColorUtil.getColor(index), selected); + } + + public static JToggleButton newShowPointButton(final DoubleField[] locationInMesh, final Color color, boolean selected) { + final JToggleButton button = new JToggleButton(new AbstractAction() { + private Border originalBorder; + + @Override + public void actionPerformed(ActionEvent e) { + AbstractButton b = ((AbstractButton) e.getSource()); + if (b.isSelected()) { + firePropertyChange(PointInfo.PROPERTY_NAME, null, new PointInfo(locationInMesh, color.toString(), EventActionType.SHOW, color)); + originalBorder = b.getBorder(); + b.setBorder(BorderFactory.createLineBorder(color, 2)); + } else { + firePropertyChange(PointInfo.PROPERTY_NAME, null, new PointInfo(locationInMesh, color.toString(), EventActionType.HIDE, color)); + if (originalBorder != null) { + b.setBorder(originalBorder); + } + } + } + }); + if (selected && !button.isSelected() || (!selected && button.isSelected())) { + button.doClick(); + } + button.setPreferredSize(new Dimension(22, 22)); + button.setIcon(ICON_OFF); + button.setSelectedIcon(ICON_ON); + button.setToolTipText("Click to display this point in the 3D canvas"); + return button; + } + + @Override + public void setToolTipText(String text) { + super.setToolTipText(text); + for (DoubleField f : fields) { + f.setToolTipText(text); + } + } + +} diff --git a/src/eu/engys/core/dictionary/parser/DictionaryReader2.java b/src/eu/engys/core/dictionary/parser/DictionaryReader2.java new file mode 100644 index 0000000..b02e5b7 --- /dev/null +++ b/src/eu/engys/core/dictionary/parser/DictionaryReader2.java @@ -0,0 +1,443 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.parser; + +import static eu.engys.core.dictionary.Dictionary.SPACER; +import static eu.engys.core.dictionary.Dictionary.VALUE_LINK; +import static eu.engys.core.dictionary.Dictionary.VALUE_UNIFORM_LINK; +import static eu.engys.core.dictionary.Dictionary.VERBOSE; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.DictionaryLinkResolver; +import eu.engys.core.dictionary.DimensionedScalar; +import eu.engys.util.IOUtils; + +public class DictionaryReader2 { + + private static final String NAME_WITH_PARENTHESIS_REGEXP = ";\\s([^(\\s]*?\\([^\\s]*?\\)[^)\\s]*?)\\s"; + static final String LIST_START = "("; + static final String LIST_END = ")"; + // private static final String LIST_START = "!"; + // private static final String MATRIX_START = "&"; + // private static final String MATRIX_DELIMITER = "|"; + static final String FIELD_END = ";"; + static final String DICTIONARY_END = "}"; + static final String DICTIONARY_START = "{"; + + static final String TOKENS_LIST = DICTIONARY_END + FIELD_END + DICTIONARY_START + LIST_START + LIST_END;// " };{("; + + private static final String COMMENT_REGEX = "/\\*(?:.|[\\n\\r])*?\\*/"; + private Dictionary dictionary; + private DictionaryLinkResolver linkResolver; + + public DictionaryReader2(Dictionary dictionary) { + this(dictionary, new DictionaryLinkResolver(dictionary)); + } + + public DictionaryReader2(Dictionary dictionary, DictionaryLinkResolver linkResolver) { + this.dictionary = dictionary; + this.linkResolver = linkResolver; + } + + public void read(File file) { + String text = readFile(file); + text = prepareText(text, file); + textToDictionary(text); + if (dictionary.found("FoamFile")) + dictionary.remove("FoamFile"); + } + + public void read(InputStream is) { + String text = readStream(is); + text = prepareText(text, null); + textToDictionary(text); + if (dictionary.found("FoamFile")) + dictionary.remove("FoamFile"); + } + + public void read(String text) { + read(text, false); + } + + public void read(String text, boolean removeHeader) { + text = prepareText(text, null); + textToDictionary(text); + if (dictionary.found("FoamFile") && removeHeader) { + dictionary.remove("FoamFile"); + } + } + + private String readFile(File file) { + return IOUtils.readStringFromFile(file); + } + + private String readStream(InputStream is) { + String text = ""; + try { + text = IOUtils.readStringFromStream(is); + } catch (IOException e) { + System.err.println("Error reading stream : " + e.getMessage()); + } + return text; + } + + private String prepareText(String text, File file) { + text = text.replaceAll(COMMENT_REGEX, ""); + text = text.replaceAll("\t", SPACER); + + StringTokenizer rowTokenizer = new StringTokenizer(text, "\n"); + StringBuffer sb = new StringBuffer(); + while (rowTokenizer.hasMoreTokens()) { + String token = rowTokenizer.nextToken(); + token = token.trim(); + if (token.startsWith("//")) + continue; + if (token.contains("//")) { + token = token.substring(0, token.indexOf("//")).trim(); + } + if (token.startsWith("#include")) { + sb.append(importFile(token, file)); + continue; + } + sb.append(token); + sb.append("\n"); + } + text = sb.toString(); + return text; + } + + private String importFile(String token, File file) { + String text = ""; + if (file != null) { + try { + Pattern regex = Pattern.compile("#include\\s+\"(.+)\""); + Matcher regexMatcher = regex.matcher(token); + if (regexMatcher.find() && regexMatcher.groupCount() == 1) { + String fileName = regexMatcher.group(1).trim(); + String parentDir = file.getParent(); + + File fileToImport = new File(parentDir, fileName); + text = readFile(fileToImport); + text = prepareText(text, fileToImport); + } + } catch (PatternSyntaxException ex) { + ex.printStackTrace(); + } + } + + return text; + } + + protected void textToDictionary(String text) { + text = text.replace("\n", SPACER); + text = new Rewriter(NAME_WITH_PARENTHESIS_REGEXP) { + public String replacement() { + String nameWithParenthesis = group(1); + // System.out.println("nameWithParentesis = "+nameWithParenthesis); + return FIELD_END + SPACER + nameWithParenthesis.replace("(", "<<").replace(")", ">>") + SPACER; + } + }.rewrite(text); + + printOut(text); + + text = text.replaceAll("\\{", SPACER + "{" + SPACER); + text = text.replaceAll("\\}", SPACER + "}" + SPACER); + text = text.replaceAll(";", SPACER + ";" + SPACER); + text = text.replaceAll("\\(", SPACER + "(" + SPACER); + text = text.replaceAll("\\)", SPACER + ")" + SPACER); + text = text.replaceAll("\\s+", SPACER); + text = text.replaceAll("<<", "("); + text = text.replaceAll(">>", ")"); + + printOut(text); + + parseDictionary(text); + } + + protected void parseDictionary(String text) { + StringTokenizer tokenizer = new StringTokenizer(text, SPACER); + Stack stack = new Stack(); + readDictionary(tokenizer, stack); + printOut("##################################\n" + toString()); + linkResolver.resolve(dictionary); + } + + void readDictionary(StringTokenizer st, Stack stack) { + while (st.hasMoreTokens()) { + String token = st.nextToken(); + printOut("TOKEN: " + token); + stack.push(token);// metto nella pila + + if (stack.peek().equals(DICTIONARY_START)) { + stack.pop(); + String name = stack.pop(); + Dictionary d = new Dictionary(name); + printOut("START DICTIONARY: " + name); + + new DictionaryReader2(d).readDictionary(st, stack); + + if (isMultiple(name)) { + String[] names = extractMultipleKeys(name); + for (String n : names) { + if (isGeneric(withDoubleQuotes(n))) { + Dictionary copy = new Dictionary(d); + copy.setName(withDoubleQuotes(n)); + dictionary.addGeneric(copy); + } else { + Dictionary copy = new Dictionary(d); + copy.setName(n); + dictionary.add(copy); + } + } + } else if (isGeneric(name)) { + dictionary.addGeneric(d); + } else { + dictionary.add(d); + } + } else if (stack.peek().equals(DICTIONARY_END)) { + // stack.pop(); + String name = stack.pop(); + printOut("FINE DICTIONARY: " + name); + return; + } else if (stack.peek().equals(FIELD_END)) { + stack.pop(); // tolgo il ; + + /* in teoria nello stack c'e' tutto il field */ + if (stack.isEmpty()) + continue; + + readFields(stack); + } else if (stack.peek().equals(LIST_START)) { + ListField2 list = listFromStack(stack); + + printOut("START LIST: " + list.getName()); + + ListReader2 reader; + if (list instanceof ThetaListField2) { + reader = new ThetaListReader2((ThetaListField2) list, true); + } else { + if (dictionary.getFoamFile() != null) { + reader = new ListReader2(list, true); + } else { + reader = new ListReader2(list, false); + } + } + + if (reader.readList(st, stack)) { + dictionary.add(list); + } else { + List unspecifiedList = new ArrayList<>(stack); + String key = list.getName(); + String value = ""; + for (String item : unspecifiedList) { + value += SPACER + item; + } + dictionary.add(key, value); + } + } + } + } + + private ListField2 listFromStack(Stack stack) { + String separator = stack.pop(); + Stack listStack = new Stack<>(); + while (!stack.isEmpty() && !isSeparator(stack.peek())) { + String pop = stack.pop(); + listStack.push(pop); + } + if (listStack.isEmpty()) { + stack.push(separator); + return new ListField2(""); + } else { + String name = listStack.pop(); + while (!listStack.isEmpty()) { + name += " " + listStack.pop(); + } + stack.push(separator); + + if (name.equals("thetaProperties")) { + return new ThetaListField2(name); + } else { + return new ListField2(name); + } + } + } + + private void readFields(Stack stack) { + Stack fieldStack = new Stack<>(); + while (!stack.isEmpty() && !isSeparator(stack.peek())) { + String pop = stack.pop(); + fieldStack.push(pop); + } + if (fieldStack.size() == 0) { + // do nothing + } else if (fieldStack.size() == 1) { + dictionary.add(fieldStack.pop(), ""); + } else if (fieldStack.size() >= 2) { + String key = fieldStack.pop(); + String value = fieldStack.pop(); + while (!fieldStack.isEmpty()) { + value += " " + fieldStack.pop(); + } + + if (readDimensionedScalar(key + " " + value)) { + return; + } + + if (isMultiple(key)) { + String[] keys = extractMultipleKeys(key); + for (String k : keys) { + if (isGeneric(withDoubleQuotes(k))) { + dictionary.addGeneric(withDoubleQuotes(k), value); + } else { + dictionary.add(k, value); + } + } + } else if (isGeneric(key)) { + dictionary.addGeneric(key, value); + } else if (isLink(value)) { + extractLink(key, value); + } else { + dictionary.add(key, value); + } + } + } + + static boolean isSeparator(String token) { + return token.equals("{") || token.equals("}") || token.equals("(") || token.equals(")") || token.equals(";"); + } + + private boolean readDimensionedScalar(String field) { + try { + dictionary.add(new DimensionedScalar(field)); + return true; + } catch (DictionaryException e) { + return false; + } + } + + private String withDoubleQuotes(String k) { + return "\"" + k + "\""; + } + + public static String[] extractMultipleKeys(String key) { + key = key.replace("\"", ""); + + if (key.contains("(") && key.contains(")")) { + int start = key.indexOf("("); + int end = key.indexOf(")"); + String header = key.substring(0, start); + String footer = key.substring(end + 1, key.length()); + String core = key.substring(start + 1, end); + + String[] tokens = core.split("\\|"); + + String[] keys = new String[tokens.length]; + for (int i = 0; i < keys.length; i++) { + keys[i] = header + tokens[i] + footer; + } + return keys; + } else { + String[] tokens = key.split("\\|"); + return tokens; + } + + } + + public String cleanGenericKey(String key) { + key = key.substring(1, key.length() - 1); + key = key.substring(0, key.indexOf(".*")); + return key; + } + + public boolean isGeneric(String key) { + return key.startsWith("\"") && key.endsWith("\"") && key.contains(".*"); + } + + public boolean isMultiple(String key) { + return key.startsWith("\"") && key.endsWith("\"") && key.contains("|"); + } + + public boolean isLink(String value) { + return !value.startsWith("\"") && value.contains("$"); + } + + private void extractLink(String key, String value) { + if (value.startsWith("uniform")) { + String link = value.replace("uniform", "").trim(); + if (link.startsWith("$")) { + dictionary.add(VALUE_UNIFORM_LINK + key, link); + } + } else if (value.startsWith("$")) { + dictionary.add(VALUE_LINK + key, value); + } + } + + private static void printOut(String msg) { + if (VERBOSE) + System.out.println("[DICT] " + msg); + } + + public static abstract class Rewriter { + private Pattern pattern; + private Matcher matcher; + + public Rewriter(String regex) { + this.pattern = Pattern.compile(regex); + } + + public String group(int i) { + return matcher.group(i); + } + + public abstract String replacement(); + + public String rewrite(CharSequence original) { + this.matcher = pattern.matcher(original); + StringBuffer result = new StringBuffer(original.length()); + while (matcher.find()) { + matcher.appendReplacement(result, ""); + result.append(replacement()); + } + matcher.appendTail(result); + return result.toString(); + } + + } +} diff --git a/src/eu/engys/core/dictionary/parser/ListField2.java b/src/eu/engys/core/dictionary/parser/ListField2.java new file mode 100644 index 0000000..52a04c1 --- /dev/null +++ b/src/eu/engys/core/dictionary/parser/ListField2.java @@ -0,0 +1,361 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.parser; + +import static eu.engys.core.dictionary.Dictionary.SPACER; +import static eu.engys.core.dictionary.Dictionary.TAB; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.commons.lang.math.NumberUtils; + +import com.google.common.primitives.Doubles; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryWriter; +import eu.engys.core.dictionary.FieldElement; + +public class ListField2 extends DefaultElement { + + private List listElements = new ArrayList(); + private int size; + private String uniformity = ""; + private String identifier = ""; + + public ListField2(String name) { + super(name); + decodeName(name); + } + + public boolean isEmpty() { + return listElements.isEmpty(); + } + + public ListField2(ListField2 lf) { + super(lf.getName()); + for (DefaultElement el : lf.getListElements()) { + if (el instanceof Dictionary) { + add(new Dictionary((Dictionary) el)); + } else if (el instanceof ListField2) { + add(new ListField2((ListField2) el)); + } else if (el instanceof FieldElement) { + add(new FieldElement((FieldElement) el)); + } else { + System.err.println("ListField2: only dictionaries are allowed as elements " + el.getName()); + } + } + this.size = lf.size; + this.uniformity = lf.uniformity; + this.identifier = lf.identifier; + } + + private void decodeName(String name) { + if (name.contains(SPACER)) { + StringTokenizer tokenizer = new StringTokenizer(name, SPACER); + if (tokenizer.countTokens() == 1) { // internalField (...); oppure + // 10 (...); +// System.out.println("ListField2.decodeName() 1"); + String token = tokenizer.nextToken(); + try { + this.size = Integer.parseInt(token); + setName(""); + } catch (NumberFormatException ex) { + this.size = -1; + setName(token); + } + this.uniformity = ""; + this.identifier = ""; + } else if (tokenizer.countTokens() == 2) {// internalField 10 (...); + String token1 = tokenizer.nextToken(); + String token2 = tokenizer.nextToken(); +// System.out.println("ListField2.decodeName() token1: [" + token1 + "], token2: [" + token2 + "]"); + + try { + this.size = Integer.parseInt(token2); + } catch (NumberFormatException ex) { + this.size = -1; + } + if(size < 0){ + setName(token1 + " " + token2); + } else { + setName(token1); + } + this.uniformity = ""; + this.identifier = ""; + } else if (tokenizer.countTokens() == 3) {// internalField + // nonuniform 0() +// System.out.println("ListField2.decodeName() 3"); + String token1 = tokenizer.nextToken(); + String token2 = tokenizer.nextToken(); + String token3 = tokenizer.nextToken(); +// System.out.println("ListField2.decodeName() token1 = '" + token1 + "'"); +// System.out.println("ListField2.decodeName() token2 = '" + token2 + "'"); +// System.out.println("ListField2.decodeName() token3 = '" + token3 + "'"); + try { + this.size = Integer.parseInt(token3); + } catch (NumberFormatException ex) { + this.size = -1; + } + setName(token1); + this.uniformity = token2; + this.identifier = ""; + } else if (tokenizer.countTokens() == 4) { // internalField + // nonuniform + // List 10 +// System.out.println("ListField2.decodeName() 4"); + String token1 = tokenizer.nextToken(); + String token2 = tokenizer.nextToken(); + String token3 = tokenizer.nextToken(); + String token4 = tokenizer.nextToken(); + try { + this.size = Integer.parseInt(token4); + } catch (NumberFormatException ex) { + this.size = -1; + } + setName(token1); + this.uniformity = token2; + this.identifier = token3; + } + } else { + try { + this.size = Integer.parseInt(name); + setName(Integer.toString(hashCode())); + } catch (NumberFormatException ex) { + this.size = -1; + setName(name); + } + } + } + + public void add(DefaultElement element) { + listElements.add(element); + } + + public void add(Collection elements) { + listElements.addAll(elements); + } + + public void add(String... values) { + for (String value : values) { + listElements.add(new FieldElement("", value)); + } + } + + public List getListElements() { + return Collections.unmodifiableList(listElements); + } + + public void removeTopElements(int n) { + for (int i = 0; i < n; i++) { + listElements.remove(0); + } + } + + public void merge(ListField2 l) { + for (DefaultElement el : l.getListElements()) { + if (!containsElement(el)) { + add(el); + } else { + } + } + } + + private boolean containsElement(DefaultElement element) { + if (element instanceof FieldElement) { + return false; + } + for (DefaultElement e : listElements) { + if (haveSameName(element, e) && e.equals(element)) { + return true; + } + } + return false; + } + + protected boolean haveSameName(DefaultElement element, DefaultElement e) { + return e.getName().equals(element.getName()); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ListField2) { + ListField2 list = (ListField2) obj; + boolean haveSameName = haveSameName(this, list); +// boolean equalCollection = CollectionUtils.isEqualCollection(list.getListElements(), listElements); + boolean equalCollection = list.getListElements().containsAll(listElements) && listElements.containsAll(list.getListElements()); + return haveSameName && equalCollection; + } + return false; + } + + public void writeListField(StringBuffer sb, String rowHeader) { +// System.out.println("ListField2.writeListField() name: "+getName()+", size: "+size+", uniformity: "+uniformity+", identifier: "+identifier); + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + writeName(sb); + sb.append(SPACER); + sb.append(uniformity); + sb.append(SPACER); + sb.append(identifier); + if (size >= 0 && !identifier.isEmpty()) { + sb.append(SPACER); + sb.append(size); + } else if (size == 0 && isNonuniform()) { + sb.append(SPACER); + sb.append("0();"); + return; + } + if (!getName().isEmpty()) { + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + } + sb.append("("); + for (DefaultElement el : getListElements()) { + DictionaryWriter.writeElement(sb, rowHeader, el); + } + if (!getName().isEmpty()) { + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(");"); + } else { + sb.append(")"); + } + } + + public boolean nameIsANumber() { + String name = getName(); + return NumberUtils.isNumber(name); + } + + private void writeName(StringBuffer sb) { + String name = getName(); + if (NumberUtils.isNumber(name)) { + sb.append(""); + } else { + sb.append(name); + } + } + + public void writeListDict(StringBuffer sb, String rowHeader) { + sb.append(uniformity); + sb.append(identifier); + sb.append("\n"); + sb.append(rowHeader); + writeName(sb); + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(listElements.size()); + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append("("); + for (DefaultElement el : getListElements()) { + DictionaryWriter.writeElement(sb, rowHeader, el); + } + sb.append("\n"); + sb.append(rowHeader); + sb.append(TAB); + sb.append(")"); + } + + public Dictionary getDictionary(String name) { + for (DefaultElement e : listElements) { + if (e instanceof Dictionary && !e.getName().isEmpty() && e.getName().equals(name)) { + return (Dictionary) e; + } + } + return null; + } + + public void setListSize(int size2) { + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + writeListField(sb, ""); + return sb.toString(); + } + + public boolean isNonuniform() { + return uniformity.equals("nonuniform"); + } + + public static String convertToString(ListField2 listField) { + StringBuilder sb = new StringBuilder(); + convertToString(listField, sb); + return sb.toString(); + } + + private static void convertToString(ListField2 listField, StringBuilder sb) { + sb.append("("); + for (DefaultElement el : listField.getListElements()) { + if(el instanceof FieldElement){ + sb.append(((FieldElement) el).getValue()); + sb.append(" "); + } else if(el instanceof ListField2){ + convertToString((ListField2)el, sb); + } + } + sb.append(")"); + } + + public List getElementsAsScalarList() { + List list = new ArrayList<>(); + for (DefaultElement e : listElements) { + if (e instanceof FieldElement && e.getName().isEmpty()) { + String value = ((FieldElement) e).getValue(); + try { + list.add(Double.parseDouble(value)); + } catch (NumberFormatException ex) { + } + } + } + return list; + } + + public List getElementsAsVectorList() { + List list = new ArrayList<>(); + for (DefaultElement e : listElements) { + if (e instanceof ListField2 && e.getName().isEmpty()) { + List value = ((ListField2) e).getElementsAsScalarList(); + list.add(Doubles.toArray(value)); + } + } + return list; + } + +} diff --git a/src/eu/engys/core/dictionary/parser/ListReader2.java b/src/eu/engys/core/dictionary/parser/ListReader2.java new file mode 100644 index 0000000..132f7c7 --- /dev/null +++ b/src/eu/engys/core/dictionary/parser/ListReader2.java @@ -0,0 +1,420 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.dictionary.parser; + +import static eu.engys.core.dictionary.Dictionary.VERBOSE; +import static eu.engys.core.dictionary.parser.DictionaryReader2.DICTIONARY_END; +import static eu.engys.core.dictionary.parser.DictionaryReader2.DICTIONARY_START; +import static eu.engys.core.dictionary.parser.DictionaryReader2.FIELD_END; +import static eu.engys.core.dictionary.parser.DictionaryReader2.LIST_END; +import static eu.engys.core.dictionary.parser.DictionaryReader2.LIST_START; + +import java.util.List; +import java.util.Stack; +import java.util.StringTokenizer; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FieldElement; + +class ListReader2 { + + private final ListField2 list; + private final boolean subList; + + public ListReader2(ListField2 list, boolean subList) { + this.list = list; + this.subList = subList; + } + + public boolean readList(StringTokenizer st, Stack stack) { + while (st.hasMoreTokens()) { + String token = st.nextToken(); + stack.push(token); + + printOut("TOKEN: " + token); + + if (stack.peek().equals(DICTIONARY_START)) { + stack.pop(); + String name = (stack.isEmpty() || stack.peek().equals(LIST_START) || stack.peek().equals(LIST_END)) ? "" : stack.pop(); + Dictionary d = new Dictionary(name); + printOut("START LIST DICTIONARY: " + name); + + new DictionaryReader2(d).readDictionary(st, stack); + list.add(d); + } else if (stack.peek().equals(DICTIONARY_END)) { + /* should not happen ! */ + } else if (stack.peek().equals(LIST_START)) { + printOut("START SUB LIST"); + processStack(stack); + + ListField2 child = new ListField2(""); + ListReader2 reader = new ListReader2(child, true); + reader.readList(st, stack); + list.add(child); + printOut("ADDING CHILD: " + child); + } else if (stack.peek().equals(LIST_END)) { + if (subList) { + printOut("END SUB LIST"); + return processStack(stack); + } + } else if (stack.peek().equals(FIELD_END)) { + printOut("FIELD_END"); + stack.pop(); // ; + + if (stack.peek().equals(LIST_END)) { + return processStack(stack); + } else { + // throw new + // RuntimeException("finisce il field ma non la lista"); + /* forse qui non si arriva mai ? */ + return false; + } + } + } + return true; + } + + private boolean processStack(Stack stack) { + printOut("-BEGIN PROCESS STACK: " + stackToString(stack)); + boolean success = false; + if (containsBox(stack)) { + printOut("-PROCESS STACK BOX"); + // readBox(stack); + success = false; + } else if (containsMatrix(stack)) { + printOut("-PROCESS STACK MATRIX"); + readMatrix(stack); + success = true; + } else if (containsVector(stack)) { + printOut("-PROCESS STACK VECTOR"); + readVector(stack); + success = true; + } else if (containsScalar(stack)) { + printOut("-PROCESS STACK SCALAR"); + readScalar(stack); + success = true; + } else if (containsWord(stack)) { + printOut("-PROCESS STACK WORD"); + readWord(stack); + success = true; + } else if (contains2Words(stack)) { + printOut("-PROCESS STACK 2 WORDS"); + read2Words(stack); + success = true; + } else if (containsScalarList(stack)) { + printOut("-PROCESS STACK SCALAR LIST"); + readScalarList(stack); + success = true; + } else { + printOut("-PROCESS STACK NOT RECOGNIZED"); + success = false; + } + printOut("-END PROCESS STACK"); + return success; + } + + private static boolean isNumeric(String str) { + try { + Double.parseDouble(str); + } catch (NumberFormatException nfe) { + return false; + } + return true; + } + + private static boolean isWord(String str) { + for (char c : str.toCharArray()) { + if(!isValid(c)){ + return false; + } + } + return true; + } + + private static boolean isValid(char c) { + return Character.isLetterOrDigit(c) || c == '_' || c == '-'; + } + + private String stackToString(Stack stack) { + StringBuilder sb = new StringBuilder(); + for (String s : stack) { + sb.append(s + ","); + } + return sb.toString(); + } + + private boolean containsBox(Stack stack) { + int counter = 0, start = 0, end = 0, max = 0; + for (int i = stack.size() - 1; i >= 0; i--) { + String s = stack.get(i); + + if (s.equals(LIST_START)) { + counter--; + start++; + } + if (s.equals(LIST_END)) { + counter++; + end++; + } + + max = Math.max(max, counter); + + if (counter == 0 && max == 1 && start == 2 && end == 2) { + printOut("Contains BOX"); + return true; + } + } + return false; + } + + // private void readBox(Stack stack) { + // int start = getListStart(stack, 2); + // int end = getListEnd(stack, ); + // List subList = stack.subList(start, end); + // for (String item : subList) { + // if (item.equals(LIST_START) || item.equals(LIST_END) ) continue; + // list.add(new FieldElement("", item)); + // } + // subList.clear(); + // } + + private boolean containsWord(Stack stack) { + String list_start = stack.pop(); // could be a LIST_START + String word = stack.pop(); // token to analyze + if (!stack.isEmpty() && stack.peek().equals(LIST_START)) { + stack.push(word); + stack.push(list_start); + if (isWord(word)) { + printOut("Contains WORD"); + return true; + } else { + return false; + } + } else { + stack.push(word); + stack.push(list_start); + return false; + } + } + + private boolean contains2Words(Stack stack) { + String list_start = stack.pop(); // could be a LIST_START + String word1 = stack.pop(); // token to analyze + if(!stack.isEmpty()){ + String word2 = stack.pop(); // token to analyze + if (!stack.isEmpty() && stack.peek().equals(LIST_START)) { + stack.push(word2); + stack.push(word1); + stack.push(list_start); + if (isWord(word1) && isWord(word2)) { + printOut("Contains TWO WORDS"); + return true; + } else { + return false; + } + } else { + stack.push(word2); + stack.push(word1); + stack.push(list_start); + return false; + } + } + stack.push(word1); + stack.push(list_start); + return false; + } + + private boolean containsScalar(Stack stack) { + String list_start = stack.pop(); // could be a LIST_START + String scalar = stack.pop(); // token to analyze + if (!stack.isEmpty() && stack.peek().equals(LIST_START)) { + stack.push(scalar); + stack.push(list_start); + if (isNumeric(scalar)) { + printOut("Contains SCALAR"); + return true; + } else { + return false; + } + } else { + stack.push(scalar); + stack.push(list_start); + return false; + } + } + + private void readScalarList(Stack stack) { + int start = 1; + int end = stack.size() - 1; + List subList = stack.subList(start, end); + for (String item : subList) { + if (item.equals(LIST_START) || item.equals(LIST_END)) + continue; + list.add(new FieldElement("", item)); + } + subList.clear(); + } + + private void readScalar(Stack stack) { + String pop = stack.pop(); + String s = stack.pop(); + stack.push(pop); + list.add(new FieldElement("", s)); + } + + private void readWord(Stack stack) { + String pop = stack.pop();//should be list start + String s = stack.pop(); + stack.push(pop); + list.add(new FieldElement("", s)); + } + + private void read2Words(Stack stack) { + String pop = stack.pop();//should be list start + String w1 = stack.pop(); + String w2 = stack.pop(); + stack.push(pop); + list.add(new FieldElement("", w2)); + list.add(new FieldElement("", w1)); + } + + private boolean containsScalarList(List stack) { + if (stack.get(0).equals(LIST_START)) { + if (stack.get(stack.size() - 1).equals(LIST_START)) { + if (stack.size() > 2) { + for (int i = stack.size() - 2; i > 0; i--) { + if (!isNumeric(stack.get(i))) { + return false; + } + } + return true; + } + return false; + } else { + return false; + } + } else { + return false; + } + } + + private boolean containsVector(List stack) { + int counter = 0, max = 0; + for (int i = stack.size() - 1; i >= 0; i--) { + String s = stack.get(i); + + if (s.equals(LIST_START)) + counter--; + if (s.equals(LIST_END)) + counter++; + + max = Math.max(max, counter); + + if (counter == 0 && max == 1) { + printOut("-Contains VECTOR"); + return true; + } + } + return false; + } + + private void readVector(Stack stack) { + int start = getListStart(stack); + int end = getListEnd(stack); + List subList = stack.subList(start, end); + for (String item : subList) { + if (item.equals(LIST_START) || item.equals(LIST_END)) + continue; + list.add(new FieldElement("", item)); + } + subList.clear(); + } + + private int getListStart(List stack) { + for (int i = stack.size() - 1; i >= 0; i--) { + String s = stack.get(i); + if (s.equals(LIST_START)) + return i; + } + return -1; + } + + private int getListEnd(List stack) { + for (int i = stack.size() - 1; i >= 0; i--) { + String s = stack.get(i); + if (s.equals(LIST_END)) + return i + 1; + } + return -1; + } + + private boolean containsMatrix(List stack) { + int start = 0, end = 0, level = 0, max = 0; + for (String s : stack) { + if (s.equals(LIST_START)) { + start++; + level++; + } + if (s.equals(LIST_END)) { + end++; + level--; + } + max = Math.max(max, level); + } + return start == end && max == 2; + } + + private void readMatrix(List stackList) { + ListField2 child = null; + for (String item : stackList) { + if (item.equals(LIST_START) && child == null) { + child = new ListField2(""); + list.add(child); + continue; + } + if (item.equals(LIST_END) && child != null) { + child = null; + continue; + } + if (item.equals(LIST_START) || item.equals(LIST_END)) + continue; + child.add(new FieldElement("", item)); + } + } + + private String processField(String field) { + if (field.contains("|")) { + field = field.replace("|", ") ("); + } + return field; + } + + private static void printOut(String msg) { + if (VERBOSE) + System.out.println("[LIST] " + msg); + } +} diff --git a/src/eu/engys/core/dictionary/parser/ThetaListField2.java b/src/eu/engys/core/dictionary/parser/ThetaListField2.java new file mode 100644 index 0000000..3bd9e08 --- /dev/null +++ b/src/eu/engys/core/dictionary/parser/ThetaListField2.java @@ -0,0 +1,93 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary.parser; + +import java.util.ArrayList; +import java.util.List; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.dictionary.TableRowElement; + +public class ThetaListField2 extends ListField2 { + + public ThetaListField2(String name) { + super(name); + } + + public ThetaListField2(ThetaListField2 tf) { + super(tf.getName()); + for (DefaultElement el : tf.getListElements()) { + if (el instanceof TableRowElement) { + add(new TableRowElement((TableRowElement) el)); + } else { + System.err.println("ThetaListField2: only TableRowElement are allowed as elements"); + } + } + } + + public void merge(ListField2 l) { + if (l instanceof ThetaListField2) { + for (DefaultElement el : l.getListElements()) { + DefaultElement this_el = containsElement(el); + + if (this_el == null) { + add(el); + } else { + if (this_el instanceof TableRowElement) { + if (el instanceof TableRowElement) { + ((TableRowElement) this_el).merge((TableRowElement) el); + } + } + } + } + } else { + super.merge(l); + } + } + + private DefaultElement containsElement(DefaultElement element) { + if (element instanceof FieldElement) { + return null; + } + for (DefaultElement e : getListElements()) { + if (haveSameName(element, e) && e.equals(element)) { + return e; + } + } + return null; + } + + public List getRows() { + List list = new ArrayList<>(); + for (DefaultElement e : getListElements()) { + if (e instanceof TableRowElement) { + list.add((TableRowElement) e); + } + } + return list; + } +} diff --git a/src/eu/engys/core/dictionary/parser/ThetaListReader2.java b/src/eu/engys/core/dictionary/parser/ThetaListReader2.java new file mode 100644 index 0000000..27479a6 --- /dev/null +++ b/src/eu/engys/core/dictionary/parser/ThetaListReader2.java @@ -0,0 +1,72 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.dictionary.parser; + +import static eu.engys.core.dictionary.Dictionary.VERBOSE; + +import java.util.List; +import java.util.Stack; +import java.util.StringTokenizer; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.dictionary.TableRowElement; + +public class ThetaListReader2 extends ListReader2 { + private ThetaListField2 thetaList; + + public ThetaListReader2(ThetaListField2 list, boolean subList) { + super(list, subList); + this.thetaList = list; + } + + @Override + public boolean readList(StringTokenizer st, Stack stack) { + boolean b = super.readList(st, stack); + if (b) { + processElements(); + } + return b; + } + + private void processElements() { + printOut("--- PROCESS ELEMENTS ---"); + List elements = thetaList.getListElements(); + int size = elements.size(); + if (size > 0 && (size%5 == 0) ) { + int rowCount = size/5; + for (int i = 0; i < rowCount; i++) { + thetaList.add(new TableRowElement((ListField2) elements.get(5*i), (FieldElement)elements.get(5*i+1), (FieldElement)elements.get(5*i+2), (FieldElement)elements.get(5*i+3), (FieldElement)elements.get(5*i+4))); + } + } + thetaList.removeTopElements(size); + } + + private static void printOut(String msg) { + if (VERBOSE) + System.out.println("[THETA LIST] " + msg); + } +} diff --git a/src/eu/engys/core/executor/AbstractExecutor.java b/src/eu/engys/core/executor/AbstractExecutor.java new file mode 100644 index 0000000..2b8972f --- /dev/null +++ b/src/eu/engys/core/executor/AbstractExecutor.java @@ -0,0 +1,230 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import java.io.File; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +import eu.engys.core.executor.ExecutorListener.ExecutorState; + + +public abstract class AbstractExecutor extends Executor { + + + protected File currentDir; + protected String description; + protected ExecutorTerminal terminal; + protected Map environment; + protected ExecutorService service; + protected Properties properties; + protected ExecutorMonitor[] monitors; + protected boolean keepFileOnEnd = false; + protected boolean loadOpenFoamEnv; + + private ExecutorState state; + private ExecutorError error; + + @Override + public Executor env(Map environment) { + this.environment = environment; + return this; + } + + @Override + public Executor description(String description) { + this.description = description; + return this; + } + + @Override + public Executor properties(Properties p) { + this.properties = p; + return this; + } + + @Override + public Executor inService(ExecutorService service) { + this.service = service; + return this; + } + + @Override + public ExecutorService getService() { + return service; + } + + @Override + public Executor inTerminal(ExecutorTerminal terminal) { + this.terminal = terminal; + return this; + } + + @Override + public Executor withMonitors(ExecutorMonitor... monitors) { + this.monitors = monitors; + return this; + } + + @Override + public Executor inFolder(File currentDir) { + this.currentDir = currentDir; + return this; + } + + @Override + public Executor withOpenFoamEnv() { + this.loadOpenFoamEnv = true; + return this; + } + + @Override + public Executor keepFileOnEnd() { + this.keepFileOnEnd = true; + return this; + } + + @Override + public int execAndWait() { + int returnValue = 0; + if (service == null) { + this.service = Executor.newExecutor("BuiltInExecutor"); + } + + if (terminal != null) { + terminal.setExecutor(service); + terminal.setTitle(description); + } + + Future task = service.submit(new Callable() { + @Override + public Integer call() throws Exception { + return _exec(); + } + }); + try { + returnValue = task.get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + + return returnValue; + } + + @Override + public void exec() { + if (service == null) { + this.service = Executor.newExecutor("BuiltInExecutor"); + } + if (terminal != null) { + terminal.setExecutor(service); + terminal.setTitle(description); + } + service.submit(new Runnable() { + @Override + public void run() { + _exec(); + } + }); + } + + protected abstract int _exec(); + + @Override + public ExecutorState getState() { + return state; + } + + @Override + public ExecutorError getError() { + return error; + } + + protected void notifyStart() { + this.state = ExecutorState.START; + if (terminal != null) { + terminal.start(); + } + if (monitors != null) { + for (ExecutorMonitor monitor : monitors) { + monitor.start(); + } + } + } + protected void notifyRefresh() { + this.state = ExecutorState.RUNNING; + if (terminal != null) { + terminal.refresh(); + } + if (monitors != null) { + for (ExecutorMonitor monitor : monitors) { + monitor.refresh(); + } + } + } + protected void notifyError(int exitValue, String msg) { + this.state = ExecutorState.ERROR; + this.error = new ExecutorError(exitValue, msg); + + if (terminal != null) { + terminal.error(exitValue, msg); + } + if (monitors != null) { + for (ExecutorMonitor monitor : monitors) { + monitor.error(exitValue, msg); + } + } + } + + protected void notifyFinish(int exitValue) { + this.state = ExecutorState.FINISH; + if (terminal != null) { + terminal.finish(exitValue); + } + if (monitors != null) { + for (ExecutorMonitor monitor : monitors) { + monitor.finish(exitValue); + } + } + } + + @Override + public void notify(ExecutorState state) { + switch (state) { + case START: notifyStart(); break; + case RUNNING: notifyRefresh(); break; + case ERROR: notifyError(1, ""); break; + + default: break; + } + } +} diff --git a/src/eu/engys/core/executor/AbstractScriptExecutor.java b/src/eu/engys/core/executor/AbstractScriptExecutor.java new file mode 100644 index 0000000..0fd6f47 --- /dev/null +++ b/src/eu/engys/core/executor/AbstractScriptExecutor.java @@ -0,0 +1,231 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import org.apache.commons.exec.CommandLine; +import org.apache.commons.exec.DefaultExecuteResultHandler; +import org.apache.commons.exec.DefaultExecutor; +import org.apache.commons.exec.ExecuteException; +import org.apache.commons.exec.ExecuteStreamHandler; +import org.apache.commons.exec.ExecuteWatchdog; +import org.apache.commons.exec.PumpStreamHandler; +import org.apache.commons.exec.environment.EnvironmentUtils; +import org.apache.commons.io.FileUtils; + +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; + +public abstract class AbstractScriptExecutor extends AbstractExecutor { + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + protected int _exec() { + int returnValue = 0; + CommandLine cmdLine = getCommandLine(); + + DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); + ExecuteWatchdog watchdog = new ScriptExecuteWatchdog(); + + DefaultExecutor executor = new DefaultExecutor(); + executor.setExitValue(0); + executor.setWorkingDirectory(currentDir); + executor.setWatchdog(watchdog); + if (terminal != null) { + ExecuteStreamHandler monitorStreamHandler = new PumpStreamHandler(terminal.getOutputStream(), terminal.getErrorStream()); + executor.setStreamHandler(monitorStreamHandler); + } else { + ExecuteStreamHandler silentStreamHandler = new PumpStreamHandler(); + executor.setStreamHandler(silentStreamHandler); + } + + Map procEnvironment = null; + if (environment != null) { + try { + procEnvironment = EnvironmentUtils.getProcEnvironment(); + procEnvironment.putAll(environment); + } catch (IOException e) { + logger.error(e.getMessage()); + procEnvironment = null; + } + } + + try { + executor.execute(cmdLine, procEnvironment, resultHandler); + notifyStart(); + } catch (Exception e) { + logger.warn("[EXECUTOR] ERROR: {}", e.getMessage()); + + notifyError(-1, e.getMessage()); + + return 1; + } + + try { + if (resultHandler.hasResult()) { + notifyRefresh(); + } else { + logger.info("[EXECUTOR] RUNNING"); + while (!resultHandler.hasResult()) { + resultHandler.waitFor(PrefUtil.getInt(PrefUtil.SCRIPT_RUN_REFRESH_TIME, 1000)); + notifyRefresh(); + } + } + } catch (InterruptedException e) { + logger.warn("[EXECUTOR] INTERRUPTED"); + watchdog.destroyProcess(); + } finally { + if (watchdog.killedProcess()) { + logger.warn("[EXECUTOR] WAITING FOR KILL"); + try { + resultHandler.waitFor(PrefUtil.getInt(PrefUtil.SCRIPT_WAIT_FOR_KILL_REFRESH_TIME, 5000)); + } catch (InterruptedException e) { + logger.warn("[EXECUTOR] INTERRUPTED: {}", e.getMessage()); + notifyError(-1, e.getMessage()); + } + } + try { + ExecuteException exception = resultHandler.getException(); + if (exception != null) { + returnValue = resultHandler.getExitValue(); + logger.warn("[EXECUTOR] ERROR: {}", exception.getMessage()); + + if (terminal != null) { + // String error = terminal.getErrorStream().peekLines(); + // notifyError(returnValue, error); + // error is empty + notifyError(returnValue, exception.getMessage()); + } else { + notifyError(returnValue, exception.getMessage()); + } + service.shutdownNow(); + } else { + returnValue = resultHandler.getExitValue(); + logger.info("[EXECUTOR] FINISH: {}", returnValue); + notifyFinish(resultHandler.getExitValue()); + } + } catch (IllegalStateException e) { + returnValue = -1; + logger.warn("[EXECUTOR] INTERRUPTED: {}", e.getMessage()); + notifyError(returnValue, e.getMessage()); + } + } + if (!keepFileOnEnd) { + internalDeleteOnEnd(); + } + + return returnValue; + } + + protected abstract void internalDeleteOnEnd(); + + private class ScriptExecuteWatchdog extends ExecuteWatchdog { + + public ScriptExecuteWatchdog() { + super(ExecuteWatchdog.INFINITE_TIMEOUT); + } + + private Process process; + + @Override + public synchronized void start(Process process) { + this.process = process; + super.start(process); + } + + @Override + public synchronized void destroyProcess() { + if (Util.isWindows()) { + killWindowsProcess(); + } else { + killLinuxProcess(); + } + super.destroyProcess(); + } + + private void killWindowsProcess() { + int pid = -1; + try { + pid = Util.getWindowsProcessId(process); + if (pid != -1) { + CommandLine command = getWindowsKillCommand(pid); + DefaultExecutor executor = new DefaultExecutor(); + executor.setStreamHandler(new PumpStreamHandler(System.out)); + executor.execute(command); + } + } catch (Exception e) { + logger.error("No process for pid {}", pid); + } + } + + private CommandLine getWindowsKillCommand(int pid) { + CommandLine command = new CommandLine("taskkill"); + command.addArgument("/F"); + command.addArgument("/PID"); + command.addArgument("" + pid); + command.addArgument("/T"); + return command; + } + + private void killLinuxProcess() { + try { + int pid = Util.getLinuxProcessId(process); + File file = new File(currentDir, "killer.run"); + FileUtils.write(file, getLinuxKillScript(pid)); + try { + file.createNewFile(); + } catch (IOException e) { + // e.printStackTrace(); + logger.error(e.getMessage()); + } + file.setExecutable(true); + Executor.script(file).inService(Executor.newExecutor("Killer")).execAndWait(); + } catch (Exception e) { + // e.printStackTrace(); + logger.error(e.getMessage()); + } + } + + private String getLinuxKillScript(int pid) { + StringBuilder sb = new StringBuilder(); + sb.append("#!/bin/bash"); + sb.append("\n\n"); + sb.append("for i in `ps h --ppid " + pid + " -o pid`;"); + sb.append("\n"); + sb.append("do"); + sb.append("\n"); + sb.append("kill -9 $i"); + sb.append("\n"); + sb.append("done"); + sb.append("\n"); + return sb.toString(); + } + }; + +} diff --git a/src/eu/engys/core/executor/CollapseManager.java b/src/eu/engys/core/executor/CollapseManager.java new file mode 100644 index 0000000..1ab312b --- /dev/null +++ b/src/eu/engys/core/executor/CollapseManager.java @@ -0,0 +1,83 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +public class CollapseManager { + + private JTabbedPane tabbedPane; + + public CollapseManager(JTabbedPane tabbedPane) { + this.tabbedPane = tabbedPane; + tabbedPane.getModel().addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + collapsePanelIfEmpty(); + } + }); + } + + private void collapsePanelIfEmpty() { + boolean isEmpty = tabbedPane.getTabCount() == 0; + if (isEmpty) { + collapse(); + } else if (canExpand()) { + expand(); + } + } + + public boolean canExpand() { + boolean hasOne = tabbedPane.getTabCount() >= 1; + boolean isCollapsed = getSplitPane().getResizeWeight() == 1; + return hasOne && isCollapsed; + } + + public void collapse() { + getSplitPane().setDividerLocation(getSplitPane().getHeight()); + getSplitPane().setResizeWeight(1); + } + + public void expand() { + getSplitPane().setDividerLocation(getSplitPane().getHeight() - 300); + getSplitPane().setResizeWeight(0.7); + } + + public void toggle() { + if (canExpand()) { + expand(); + } else { + collapse(); + } + } + + private JSplitPane getSplitPane() { + return (JSplitPane) tabbedPane.getParent(); + } +} diff --git a/src/eu/engys/core/executor/CommandExecutor.java b/src/eu/engys/core/executor/CommandExecutor.java new file mode 100644 index 0000000..9cf7e3d --- /dev/null +++ b/src/eu/engys/core/executor/CommandExecutor.java @@ -0,0 +1,91 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import static eu.engys.core.OpenFOAMEnvironment.cleanEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.loadEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.printHeader; + +import java.io.File; +import java.util.List; + +import org.apache.commons.exec.CommandLine; +import org.apache.commons.io.FileUtils; + +import eu.engys.core.controller.ScriptBuilder; +import eu.engys.util.IOUtils; +import eu.engys.util.Util; + +public class CommandExecutor extends AbstractScriptExecutor { + + private CommandLine commandLine; + private File supportFile; + + public CommandExecutor(String command, String... arguments) { + this.commandLine = new CommandLine(command); + commandLine.addArguments(arguments); + } + + @Override + protected CommandLine getCommandLine() { + this.supportFile = IOUtils.getSupportFile(currentDir); + writeCommandInSupportFile(supportFile); + return new CommandLine(supportFile); + } + + @Override + protected void internalDeleteOnEnd() { + FileUtils.deleteQuietly(supportFile); + } + + private void writeCommandInSupportFile(File supportFile) { + IOUtils.writeLinesToFile(supportFile, getCommand()); + supportFile.setExecutable(true); + } + + private List getCommand() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, description); + if (Util.isWindows()) { + if (loadOpenFoamEnv) { + loadEnvironment(sb); + sb.append("cd /D \"" + currentDir + "\""); + } else { + cleanEnvironment(sb); + } + sb.append(commandLine.toString()); + } else { + if (loadOpenFoamEnv) { + loadEnvironment(sb); + } else { + cleanEnvironment(sb); + } + sb.append(commandLine.toString()); + } + return sb.getLines(); + } + +} diff --git a/src/eu/engys/core/executor/ConsoleExecutorMonitor.java b/src/eu/engys/core/executor/ConsoleExecutorMonitor.java new file mode 100644 index 0000000..b92fade --- /dev/null +++ b/src/eu/engys/core/executor/ConsoleExecutorMonitor.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +public class ConsoleExecutorMonitor extends ExecutorTerminal { + + @Override + public void start() { + } + + @Override + public void finish(int returnValue) { + super.finish(returnValue); + System.err.print(getErrorStream().flushLinesBuffer()); + } + + @Override + public void error(int returnValue, String msg) { + System.err.println(msg); + System.err.print(getErrorStream().flushLinesBuffer()); + } + + @Override + public void refresh() { + System.out.print(getOutputStream().flushLinesBuffer()); + } + +} diff --git a/src/eu/engys/core/executor/Executor.java b/src/eu/engys/core/executor/Executor.java new file mode 100644 index 0000000..c9c4d8d --- /dev/null +++ b/src/eu/engys/core/executor/Executor.java @@ -0,0 +1,131 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +import java.io.File; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.exec.CommandLine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +import eu.engys.core.executor.ExecutorListener.ExecutorState; + +public abstract class Executor { + + protected static final Logger logger = LoggerFactory.getLogger(Executor.class); + + + public static Executor script(File file, String... args) { + return new ScriptExecutor(file, args); + } + + public static Executor command(String command, String... args) { + return new CommandExecutor(command, args); + } + + public static Executor command(File file, String... args) { + return new CommandExecutor("\"" + file.getAbsolutePath() + "\"", args); + } + + public static JavaExecutor jvm(String className, String... args) { + return new JavaExecutor(className, args); + } + + public abstract Executor description(String description); + + public abstract Executor keepFileOnEnd(); + + public abstract Executor inFolder(File currentDir); + + public abstract Executor env(Map environment); + + public abstract Executor inService(ExecutorService service); + + public abstract Executor inTerminal(ExecutorTerminal terminal); + + public abstract Executor withMonitors(ExecutorMonitor... monitor); + + public abstract Executor withOpenFoamEnv(); + + public abstract void exec(); + + public abstract int execAndWait(); + + public abstract Executor properties(Properties p); + + protected abstract CommandLine getCommandLine(); + + public abstract ExecutorService getService(); + public abstract ExecutorState getState(); + public abstract ExecutorError getError(); + + public void notify(ExecutorState state) { + } + + public static ThreadPoolExecutor newExecutor(final String name) { + ThreadFactory threadFactory = new ThreadFactoryBuilder() + .setNameFormat(name + "-%d") + .setDaemon(false) + .build(); + + return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), threadFactory) { + @Override + protected void afterExecute(Runnable r, Throwable t) { + super.afterExecute(r, t); + if (t == null && r instanceof Future) { + try { + Future future = (Future) r; + if (future.isDone()) + future.get(); + } catch (CancellationException ce) { + t = ce; + } catch (ExecutionException ee) { + t = ee.getCause(); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); // ignore/reset + } + } + if (t != null) { + logger.error("ERROR FOR EXECUTOR: " + name, t); + } + } + }; + } + +} diff --git a/src/eu/engys/core/executor/ExecutorError.java b/src/eu/engys/core/executor/ExecutorError.java new file mode 100644 index 0000000..085bf0f --- /dev/null +++ b/src/eu/engys/core/executor/ExecutorError.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import java.io.Serializable; + +public class ExecutorError implements Serializable { + + private int returnValue; + private String message; + + public ExecutorError() { + } + + public ExecutorError(int returnValue, String message) { + this.returnValue = returnValue; + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public int getReturnValue() { + return returnValue; + } + + public void setReturnValue(int returnValue) { + this.returnValue = returnValue; + } + + @Override + public String toString() { + return "(" +returnValue+ ") " + (message != null ? message : ""); + } +} diff --git a/src/eu/engys/core/executor/ExecutorHook.java b/src/eu/engys/core/executor/ExecutorHook.java new file mode 100644 index 0000000..3bbe5a4 --- /dev/null +++ b/src/eu/engys/core/executor/ExecutorHook.java @@ -0,0 +1,32 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +public interface ExecutorHook { + + public void run(ExecutorMonitor monitor); + +} diff --git a/src/eu/engys/core/executor/ExecutorListener.java b/src/eu/engys/core/executor/ExecutorListener.java new file mode 100644 index 0000000..f138d14 --- /dev/null +++ b/src/eu/engys/core/executor/ExecutorListener.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +public interface ExecutorListener { + + public enum ExecutorState { + START, RUNNING, FINISH, ERROR; + + public boolean isDoingSomething() { + return this == START || this == RUNNING; + } + + public boolean isError() { + return this == ERROR; + } + + public boolean isRunning() { + return this == RUNNING; + } + } + + public void refresh(); + public void start(); + public void finish(int exitValue); + public void error(int exitValue, String msg); + +} diff --git a/src/eu/engys/core/executor/ExecutorMonitor.java b/src/eu/engys/core/executor/ExecutorMonitor.java new file mode 100644 index 0000000..7ffc3f1 --- /dev/null +++ b/src/eu/engys/core/executor/ExecutorMonitor.java @@ -0,0 +1,124 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ExecutorMonitor implements ExecutorListener { + + protected static final Logger logger = LoggerFactory.getLogger(ExecutorMonitor.class); + private Map> stateHooks = new HashMap<>(); + + protected ExecutorService executor; + private ExecutorState state; + + private int returnValue; + private String errorMessage; + + @Override + public void start() { + logger.info("[EXECUTOR MONITOR] START"); + state = ExecutorState.START; + runHook(); + } + + @Override + public void refresh() { + state = ExecutorState.RUNNING; + runHook(); + } + + @Override + public void finish(int returnValue) { + logger.info("[EXECUTOR MONITOR] FINISH: value = {}", returnValue); + this.state = ExecutorState.FINISH; + this.returnValue = returnValue; + runHook(); + } + + @Override + public void error(int returnValue, String msg) { + logger.info("[EXECUTOR MONITOR] ERROR: {}", msg); + this.returnValue = -1; + this.errorMessage = decodeError(returnValue, msg); + this.state = ExecutorState.ERROR; + runHook(); + } + + public static String decodeError(int returnValue, String msg) { + switch (returnValue) { + case 127: + return "Command not found"; + case 130: + return "Script Terminated"; + case 137: + return "Process Killed"; + case 255: + return "Script Error"; + + default: + return msg; + } + } + + public void setExecutor(ExecutorService executor) { + this.executor = executor; + } + + public void addHook(ExecutorState state, ExecutorHook hook) { + if (!stateHooks.containsKey(state)) { + stateHooks.put(state, new ArrayList()); + } + stateHooks.get(state).add(hook); + } + + public String getErrorMessage() { + return errorMessage; + } + + public int getReturnValue() { + return returnValue; + } + + public ExecutorState getState() { + return state; + } + + private void runHook() { + if (stateHooks.containsKey(state)) { + for (ExecutorHook hook : stateHooks.get(state)) { + hook.run(this); + } + } + } +} diff --git a/src/eu/engys/core/executor/ExecutorTerminal.java b/src/eu/engys/core/executor/ExecutorTerminal.java new file mode 100644 index 0000000..f22ab4d --- /dev/null +++ b/src/eu/engys/core/executor/ExecutorTerminal.java @@ -0,0 +1,85 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import java.util.concurrent.ExecutorService; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class ExecutorTerminal implements ExecutorListener { + + protected static final Logger logger = LoggerFactory.getLogger(ExecutorTerminal.class); + + private TerminalOutputStream outputStream = new TerminalOutputStream(); + private TerminalOutputStream errorStream = new TerminalOutputStream(); + + private String title; + + protected ExecutorService executor; + + @Override + public void start() { + } + + @Override + public void refresh() { + } + + @Override + public void finish(int returnValue) { + logger.info("[TERMINAL] FINISH: value = {}", returnValue); + outputStream.close(); + errorStream.close(); + } + + @Override + public void error(int exitValue, String msg) { + logger.info("[TERMINAL] ERROR: value = {}", exitValue); + outputStream.close(); + errorStream.close(); + } + + public void setTitle(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public TerminalOutputStream getOutputStream() { + return outputStream; + } + + public TerminalOutputStream getErrorStream() { + return errorStream; + } + + public void setExecutor(ExecutorService executor) { + this.executor = executor; + } +} diff --git a/src/eu/engys/core/executor/FileManagerSupport.java b/src/eu/engys/core/executor/FileManagerSupport.java new file mode 100644 index 0000000..4216049 --- /dev/null +++ b/src/eu/engys/core/executor/FileManagerSupport.java @@ -0,0 +1,170 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import java.awt.Desktop; +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.JOptionPane; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.PDFFileFilter; +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; +import eu.engys.util.ui.UiUtil; + +public class FileManagerSupport { + + private static final Logger logger = LoggerFactory.getLogger(FileManagerSupport.class); + + private static final String ACTION_NAME = "Open File Manager"; + + public static void openPDF(File parent, String key) { + logger.debug("Looking for PDF file with key {} inside {}", key, parent.getAbsolutePath()); + Collection files = FileUtils.listFiles(parent, new PDFFileFilter(key), null); + if (files.size() == 1) { + open(files.iterator().next()); + } else { + boolean emptyDocumentation = (files.size() == 0); + UiUtil.showDocumentationNotLoadedWarning(emptyDocumentation); + } + } + + public static void open(File file) { + if (Util.isWindows()) { + // Desktop.getDesktop().open(file) on windows may hang + _open(file, "Open action not supported"); + } else { + openOnLinux(file); + } + } + + private static void openOnLinux(File file) { + if (Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.OPEN)) { + try { + Desktop.getDesktop().open(file); + } catch (IOException e) { + _open(file, e.getMessage()); + } + } else { + _open(file, "Open action not supported"); + } + } else { + _open(file, "Desktop class not supported by this platform"); + } + } + + private static void _open(File file, String logInfo) { + Executor.command(getOpenCommand(file), getOpenCommandArguments(file)).description(ACTION_NAME).exec(); + } + + private static String getOpenCommand(File file) { + String command; + if (Util.isWindows()) { + if (file.isDirectory()) { + command = "explorer"; + } else { + command = "rundll32.exe"; + } + } else { + if (file.isDirectory()) { + command = getLinuxFileManager(); + } else { + command = getLinuxFileOpener(); + } + } + return command; + } + + private static String[] getOpenCommandArguments(File file) { + List command = new LinkedList<>(); + if (Util.isWindows() && !file.isDirectory()) { + command.add("url.dll,FileProtocolHandler"); + } + command.add(file.getAbsolutePath()); + return command.toArray(new String[0]); + } + + private static String getLinuxFileManager() { + String preferredFileManager = PrefUtil.getString(PrefUtil.HELYX_DEFAULT_FILE_MANAGER); + if (preferredFileManager.isEmpty()) { + if (checkTerminal("nautilus")) { + return "nautilus"; + } else if (checkTerminal("dolphin")) { + return "dolphin"; + } else if (checkTerminal("konqueror")) { + return "konqueror"; + } else if (checkTerminal("thunar")) { + return "thunar"; + } else { + logger.error("No file manager found"); + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "No File Manager Found", "File System error", JOptionPane.ERROR_MESSAGE); + return ""; + } + } else { + return preferredFileManager; + } + } + + private static String getLinuxFileOpener() { + String preferredFileOpener = PrefUtil.getString(PrefUtil.HELYX_DEFAULT_FILE_OPENER); + if (preferredFileOpener.isEmpty()) { + if (checkTerminal("gnome-open")) { + return "gnome-open"; + } else if (checkTerminal("xdg-open")) { + return "xdg-open"; + } else if (checkTerminal("kde-open")) { + return "kde-open"; + } else { + logger.error("No command available to open the default application, containing folder will be opened instead"); + return getLinuxFileManager(); + } + } else { + return preferredFileOpener; + } + } + + private static boolean checkTerminal(String terminal) { + try { + new ProcessBuilder(terminal, "--help").start().waitFor(); + // System.out.println("RunScript.checkTerminal() "+terminal+" OK"); + return true; + } catch (InterruptedException | IOException e) { + // System.out.println("RunScript.checkTerminal() "+terminal+" NO"); + return false; + } + } + +} diff --git a/src/eu/engys/core/executor/JavaExecutor.java b/src/eu/engys/core/executor/JavaExecutor.java new file mode 100644 index 0000000..753d5cc --- /dev/null +++ b/src/eu/engys/core/executor/JavaExecutor.java @@ -0,0 +1,95 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.apache.commons.exec.CommandLine; + +public class JavaExecutor extends AbstractScriptExecutor { + + private String className; + private String[] args; + + public JavaExecutor(String className, String... args) { + super(); + this.className = className; + this.args = args; + } + + @Override + public CommandLine getCommandLine() { + return buildCommandLineScript(); + } + + private CommandLine buildCommandLineScript() { + String separator = System.getProperty("file.separator"); + String classpath = System.getProperty("java.class.path"); + String java = System.getProperty("java.home") + separator + "bin" + separator + "java"; + + final CommandLine cmdLine = new CommandLine(java); + cmdLine.addArgument("-classpath"); + cmdLine.addArgument(reletivize(classpath)); + addSystemProperties(cmdLine); + cmdLine.addArgument(className); + cmdLine.addArguments(args); + + return cmdLine; + } + + private String reletivize(String classpath) { + if (currentDir != null) { + String relative = ""; + String[] paths = classpath.split(System.getProperty("path.separator")); + for (String path : paths) { + Path p = Paths.get(path); + if(!p.isAbsolute()){ + p = p.toAbsolutePath(); + } + Path relativize = currentDir.getAbsoluteFile().toPath().relativize(p); + relative += (relativize + System.getProperty("path.separator")); + } + return relative; + } else { + return classpath; + } + } + + private void addSystemProperties(CommandLine cmdLine) { + if (properties != null) { + for (String key : properties.stringPropertyNames()) { + cmdLine.addArgument("-D"+key+"="+properties.getProperty(key)); + } + } + } + + @Override + protected void internalDeleteOnEnd() { + + } +} diff --git a/src/eu/engys/core/executor/MailManagerSupport.java b/src/eu/engys/core/executor/MailManagerSupport.java new file mode 100644 index 0000000..d414568 --- /dev/null +++ b/src/eu/engys/core/executor/MailManagerSupport.java @@ -0,0 +1,136 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import javax.swing.JOptionPane; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.Util; +import eu.engys.util.ui.UiUtil; + +public class MailManagerSupport { + + private static final Logger logger = LoggerFactory.getLogger(MailManagerSupport.class); + // private static final String PREFERRED_MAIL_MANAGER = + // PrefUtil.getString(PrefUtil.HELYX_DEFAULT_MAIL_MANAGER); + private static final String SUPPORT_MAIL = "support@engys.com"; + private static final String SUPPORT_SUBJECT = "Support request"; + + public static void mailSupport() { + mail(SUPPORT_MAIL, SUPPORT_SUBJECT); + } + + public static void mail(String to, String subject) { + if (Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.MAIL)) { + try { + Desktop.getDesktop().mail(new URI("mailto:" + to + "?subject=" + subject + "&body=")); + } catch (IOException | URISyntaxException e) { + _mail(to, subject, e.getMessage()); + } + } else { + _mail(to, subject, "Mail action not supported"); + } + } else { + _mail(to, subject, "Desktop class not supported by this platform"); + } + } + + private static void _mail(String to, String subject, String logInfo) { + try { + ProcessBuilder pb = getProcessBuilder(to, subject); + pb.start(); + } catch (IOException e) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "No mail client found.", "Mail error", JOptionPane.ERROR_MESSAGE); + } + } + + private static ProcessBuilder getProcessBuilder(String to, String subject) { + ProcessBuilder pb = null; + if (Util.isWindows()) { + pb = new ProcessBuilder("rundll32.exe", "url.dll,FileProtocolHandler", "mailto:" + to + "?subject=" + subject + "&body="); + } else { + MailToken token = getLinuxMailManager(to, subject); + pb = new ProcessBuilder(token.getProvider(), token.getCommand()); + } + return pb; + } + + private static MailToken getLinuxMailManager(String to, String subject) { + // if (PREFERRED_MAIL_MANAGER.isEmpty()) { + if (checkMailClient("thunderbird")) { + return new MailToken("thunderbird", "-compose \"to='" + to + "',subject='" + subject.replace("%20", " ") + "'\""); + } else if (checkMailClient("evolution")) { + return new MailToken("evolution", ""); + } else { + logger.error("No mail client found"); + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "No mail client found", "Mail Error", JOptionPane.ERROR_MESSAGE); + return new MailToken("", ""); + } + // } else { + // return new MailToken(PREFERRED_MAIL_MANAGER, ""); + // } + } + + private static boolean checkMailClient(String client) { + try { + new ProcessBuilder(client, "--help").start().waitFor(); + return true; + } catch (InterruptedException | IOException e) { + return false; + } + } + + private static class MailToken { + + private final String provider; + private final String command; + + public MailToken(String provider, String command) { + this.provider = provider; + this.command = command; + } + + public String getProvider() { + return provider; + } + + public String getCommand() { + return command; + } + + } + +} diff --git a/src/eu/engys/core/executor/ProgressExecutorMonitor.java b/src/eu/engys/core/executor/ProgressExecutorMonitor.java new file mode 100644 index 0000000..cf1585f --- /dev/null +++ b/src/eu/engys/core/executor/ProgressExecutorMonitor.java @@ -0,0 +1,116 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +import javax.swing.JOptionPane; +import javax.swing.ProgressMonitor; + +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; + +public class ProgressExecutorMonitor extends ExecutorTerminal { + + private ProgressMonitor progressMonitor; + private double counter = 0; +// private int counter = 0; + private int max; + private boolean stopped; + + public ProgressExecutorMonitor(int max) { + this.max = max; + } + + @Override + public void start() { + counter = 0; + progressMonitor = new ProgressMonitor(UiUtil.getActiveWindow(), getTitle(),"", 0, 100); + progressMonitor.setProgress((int) counter); +// progressMonitor.setProgress(counter); + } + + @Override + public void finish(int returnValue) { + super.finish(returnValue); + progressMonitor.setProgress(progressMonitor.getMaximum()); + progressMonitor.setNote("Finished"); + } + + @Override + public void error(final int returnValue, final String msg) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), ExecutorMonitor.decodeError(returnValue, msg), "Execution Error", JOptionPane.ERROR_MESSAGE); + } + }); + } + + @Override + public void refresh() { + if (stopped) return; + + counter += getIncrement(); + progressMonitor.setProgress((int)counter); +// progressMonitor.setProgress(++counter); + + String message = String.format("%d%% Completed", (int) counter); + + progressMonitor.setNote(message); +// if (progressMonitor.isCanceled() || getState() == ExecutorState.FINISH || getState() == ExecutorState.ERROR ) { + if (progressMonitor.isCanceled()) { + this.stopped = stopExecutor(); + } +// } + } + + private double getIncrement() { + if (counter < 50) { + return 1; + } else if (counter < 75) { + return 1/2D; + } else { + return 1/4D; + } + } + + public boolean stopExecutor() { +// if (getState() == ExecutorState.START || getState() == ExecutorState.RUNNING) { + if (executor != null) { + int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "Stop execution?", "Close Monitor", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (retVal == JOptionPane.YES_OPTION) { + executor.shutdownNow(); + return true; + } + return false; + } else { + return true; + } +// } else { +// return true; +// } + } +} diff --git a/src/eu/engys/core/executor/QueueExecutorMonitor.java b/src/eu/engys/core/executor/QueueExecutorMonitor.java new file mode 100644 index 0000000..9600bce --- /dev/null +++ b/src/eu/engys/core/executor/QueueExecutorMonitor.java @@ -0,0 +1,91 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.input.Tailer; +import org.apache.commons.io.input.TailerListenerAdapter; + +public class QueueExecutorMonitor extends ExecutorTerminal { + + private File[] outputFiles; + private List tailers; + + public QueueExecutorMonitor(File... outputFile) { + this.outputFiles = outputFile; + this.tailers = new ArrayList<>(); + } + + @Override + public void start() { + super.start(); + for (File outputFile : outputFiles) { + tailers.add(Tailer.create(outputFile, new MyListener(), 500L)); + } + } + + @Override + public void finish(int returnValue) { + super.finish(returnValue); + for (Tailer tailer : tailers) { + tailer.stop(); + } + } + + @Override + public void error(int returnValue, String msg) { + super.error(returnValue, msg); + for (Tailer tailer : tailers) { + tailer.stop(); + } + System.err.println(msg); + } + + @Override + public void refresh() { + super.refresh(); + System.out.print(getOutputStream().flushLinesBuffer()); + System.err.print(getErrorStream().flushLinesBuffer()); + } + + class MyListener extends TailerListenerAdapter { + + @Override + public void handle(String line) { + System.out.println("[out] "+line); + } + + @Override + public void handle(Exception exception) { + System.err.println("[err] "+exception.getMessage()); + } + + } +} diff --git a/src/eu/engys/core/executor/QueueTerminalExecutorMonitor.java b/src/eu/engys/core/executor/QueueTerminalExecutorMonitor.java new file mode 100644 index 0000000..9e55c84 --- /dev/null +++ b/src/eu/engys/core/executor/QueueTerminalExecutorMonitor.java @@ -0,0 +1,89 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.input.Tailer; +import org.apache.commons.io.input.TailerListenerAdapter; + +public class QueueTerminalExecutorMonitor extends TerminalExecutorMonitor { + + private File[] outputFiles; + private List tailers; + + public QueueTerminalExecutorMonitor(File... outputFile) { + this.outputFiles = outputFile; + this.tailers = new ArrayList<>(); + } + + @Override + public void start() { + for (File outputFile : outputFiles) { + tailers.add(Tailer.create(outputFile, new MyListener(), 500L)); + } + super.start(); + } + + @Override + public void finish(int returnValue) { + super.finish(returnValue); + for (Tailer tailer : tailers) { + tailer.stop(); + } + } + + @Override + public void error(int returnValue, String msg) { + super.error(returnValue, msg); + for (Tailer tailer : tailers) { + tailer.stop(); + } + // System.err.println(msg); + } + + @Override + public void refresh() { + super.refresh(); + // System.out.print(flushLinesBuffer()); + } + + class MyListener extends TailerListenerAdapter { + + @Override + public void handle(String line) { + area.append("[out] " + line + "\n"); + } + + @Override + public void handle(Exception exception) { + area.append("[err] " + exception.getMessage() + "\n"); + } + + } +} diff --git a/src/eu/engys/core/executor/ScriptExecutor.java b/src/eu/engys/core/executor/ScriptExecutor.java new file mode 100644 index 0000000..db08d71 --- /dev/null +++ b/src/eu/engys/core/executor/ScriptExecutor.java @@ -0,0 +1,58 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +import java.io.File; + +import org.apache.commons.exec.CommandLine; + +public class ScriptExecutor extends AbstractScriptExecutor { + + private File file; + private String[] args; + + public ScriptExecutor(File file, String... args) { + super(); + this.file = file; + this.args = args; + } + + @Override + protected CommandLine getCommandLine() { + CommandLine commandLine = new CommandLine(file.getAbsolutePath()); + if (args != null && args.length > 0) { + commandLine.addArguments(args); + } + return commandLine; + } + + @Override + protected void internalDeleteOnEnd() { + file.delete(); + } + +} diff --git a/src/eu/engys/core/executor/StateMapperHook.java b/src/eu/engys/core/executor/StateMapperHook.java new file mode 100644 index 0000000..8ad94da --- /dev/null +++ b/src/eu/engys/core/executor/StateMapperHook.java @@ -0,0 +1,49 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import eu.engys.core.controller.Command; +import eu.engys.core.controller.StateConnector; +import eu.engys.core.project.SolverState; +import eu.engys.core.project.state.ServerState; + +public class StateMapperHook implements ExecutorHook { + + private StateConnector connector; + private Command command; + private SolverState solverState; + + public StateMapperHook(StateConnector connector, Command command, SolverState solverState) { + this.command = command; + this.connector = connector; + this.solverState = solverState; + } + + @Override + public void run(ExecutorMonitor m) { + connector.offer(new ServerState(command, solverState, new ExecutorError(m.getReturnValue(), m.getErrorMessage()))); + } +} diff --git a/src/eu/engys/core/executor/TerminalExecutorMonitor.java b/src/eu/engys/core/executor/TerminalExecutorMonitor.java new file mode 100644 index 0000000..d948431 --- /dev/null +++ b/src/eu/engys/core/executor/TerminalExecutorMonitor.java @@ -0,0 +1,318 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import static eu.engys.util.ui.UiUtil.createToolBarButton; +import static eu.engys.util.ui.UiUtil.createToolBarToggleButton; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.swing.Box; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JToolBar; +import javax.swing.SwingUtilities; +import javax.swing.text.BadLocationException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.executor.actions.CloseMonitorAction; +import eu.engys.core.executor.actions.CopyMonitorToClipboardAction; +import eu.engys.core.executor.actions.MaximiseMonitorAction; +import eu.engys.core.executor.actions.SaveLogFileAction; +import eu.engys.core.executor.actions.ScrollLockAction; +import eu.engys.core.executor.actions.ShowLogAction; +import eu.engys.core.executor.actions.StopCommandAction; +import eu.engys.util.PrefUtil; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class TerminalExecutorMonitor extends ExecutorTerminal { + + private static final Logger logger = LoggerFactory.getLogger(TerminalExecutorMonitor.class); + + private static final String RUNNING_LABEL = "Running..."; + public static final String TERMINAL_PANEL_AREA = "terminal.panel.area"; + + protected JTextArea area; + private JScrollPane scroll; + private JToolBar toolbar; + private JPanel panel; + + private Date startTime; + + private JLabel stateLabel; + private JLabel debugLabel; + + private ViewAction copyAction; + private ViewAction saveAsAction; + protected ViewAction closeAction; + protected ViewAction maxAction; + + private ShowLogAction logAction; + private ScrollLockAction scrollAction; + private StopCommandAction stopAction; + + private Runnable stopCommand = new Runnable() { + public void run() { + stopExecutor(); + } + }; + + public TerminalExecutorMonitor() { + super(); + layoutComponents(); + } + + public TerminalExecutorMonitor(File logFile) { + this(); + setLogFile(logFile); + } + + private void layoutComponents() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + area = new JTextArea(); + scroll = new JScrollPane(area); + toolbar = new JToolBar(); + panel = new JPanel(new BorderLayout()); + + scroll.setName("terminal.panel.scroll"); + area.setName(TERMINAL_PANEL_AREA); + + stateLabel = new JLabel(); + stateLabel.setFont(new Font(stateLabel.getFont().getName(), Font.ITALIC, stateLabel.getFont().getSize())); + + debugLabel = new JLabel(); + + stopAction = new StopCommandAction(); + stopAction.setStopCommand(stopCommand); + stopAction.setEnabled(false); + + copyAction = new CopyMonitorToClipboardAction(area); + logAction = new ShowLogAction(); + logAction.setEnabled(false); + saveAsAction = new SaveLogFileAction(area); + + scrollAction = new ScrollLockAction(area); + + toolbar.setFloatable(false); + toolbar.setRollover(false); + toolbar.add(createToolBarButton(stopAction)); + toolbar.addSeparator(); + toolbar.add(createToolBarButton(logAction)); + toolbar.add(createToolBarButton(saveAsAction)); + toolbar.add(createToolBarButton(copyAction)); + toolbar.addSeparator(); + toolbar.add(createToolBarToggleButton(scrollAction)); + toolbar.addSeparator(); + toolbar.add(stateLabel); + toolbar.add(debugLabel); + toolbar.add(Box.createHorizontalGlue()); + + configureFrameActions(toolbar); + + panel.add(toolbar, BorderLayout.NORTH); + panel.add(scroll, BorderLayout.CENTER); + setupFont(); + } + }); + } + + protected void configureFrameActions(JToolBar toolbar) { + maxAction = new MaximiseMonitorAction(panel); + closeAction = new CloseMonitorAction(panel); + closeAction.setEnabled(false); + toolbar.add(createToolBarToggleButton(maxAction)); + toolbar.add(createToolBarButton(closeAction)); + + } + + public void setLogFile(File logFile) { + this.logAction.setLogFile(logFile); + this.logAction.setEnabled(logFile != null); + } + + public void setStopCommand(Runnable stopCommand) { + this.stopAction.setStopCommand(stopCommand); + } + + @Override + public void start() { + startTime = new Date(); + ExecUtil.invokeLater(new Runnable() { + + @Override + public void run() { + show(); + _refresh(); + + stateLabel.setText(RUNNING_LABEL); + stopAction.setEnabled(true); + if (closeAction != null) + closeAction.setEnabled(false); + } + }); + } + + public void show() { + TerminalManager.getInstance().addTerminal(panel, TerminalExecutorMonitor.this); + } + + @Override + public String getTitle() { + return super.getTitle() + " " + getTime(); + } + + private String getTime() { + return new SimpleDateFormat("'['HH:mm:ss']'").format(startTime); + } + + private void setupFont() { + Font font = new Font(Font.MONOSPACED, Font.PLAIN, 10); + area.setFont(font); + area.setBackground(Color.BLACK); + area.setForeground(Color.LIGHT_GRAY); + } + + @Override + public void error(final int returnValue, final String msg) { + super.error(returnValue, msg); + refresh(); + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + stateLabel.setText(""); + stopAction.setEnabled(false); + if (closeAction != null) { + closeAction.setEnabled(true); + } + JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(area), ExecutorMonitor.decodeError(returnValue, msg), "Execution Error", JOptionPane.ERROR_MESSAGE); + } + }); + } + + @Override + public void finish(int returnValue) { + super.finish(returnValue); + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + _refresh(); + stateLabel.setText(""); + stopAction.setEnabled(false); + if (closeAction != null) + closeAction.setEnabled(true); + } + }); + } + + @Override + public void refresh() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + _refresh(); + } + }); + } + + protected void _refresh() { + int maxLines = PrefUtil.getInt(PrefUtil.BATCH_MONITOR_DIALOG_MAX_ROW, 10000); + + String lines = getOutputStream().flushLinesBuffer(); + if (!lines.isEmpty()) { + area.append(lines); + } + + String errors = getErrorStream().flushLinesBuffer(); + if (!errors.isEmpty()) { + area.append(errors); + } + + int lineCount = area.getLineCount(); + if (lineCount > maxLines) { + try { + area.replaceRange("", 0, area.getLineEndOffset(lineCount - maxLines)); + } catch (BadLocationException e) { + logger.warn("Error cleaning text area, {}", e.getMessage()); + } + } + + if (!scrollAction.isSelected()) { + area.setCaretPosition(area.getText().length()); + } + } + + private boolean stopExecutor() { + // if (getState() == ExecutorState.START || getState() == ExecutorState.RUNNING) { + if (executor != null) { + int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "Stop execution?", "Close Monitor", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (retVal == JOptionPane.YES_OPTION) { + executor.shutdownNow(); + return true; + } + return false; + } else { + return true; + } + // } else { + // return true; + // } + } + + public JPopupMenu createMenu(Component component) { + JPopupMenu pMenu = new JPopupMenu(); + pMenu.add(UiUtil.createMenuItem(new StopCommandAction(true))); + pMenu.add(UiUtil.createMenuItem(new CloseMonitorAction(panel, true))); + return pMenu; + } + + public boolean canClose() { + return closeAction != null && closeAction.isEnabled(); + } + + public void disconnect() { + } + + public JPanel getPanel() { + return panel; + } + +} diff --git a/src/eu/engys/core/executor/TerminalManager.java b/src/eu/engys/core/executor/TerminalManager.java new file mode 100644 index 0000000..9209a39 --- /dev/null +++ b/src/eu/engys/core/executor/TerminalManager.java @@ -0,0 +1,256 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.GraphicsDevice; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.AbstractButton; +import javax.swing.ImageIcon; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; + +import eu.engys.util.ApplicationInfo; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class TerminalManager { + + private static TerminalManager instance = null; + private Map frames = new HashMap<>(); + private Map monitors = new HashMap<>(); + + public static final String TERMINAL_MANAGER = "terminal.manager"; + + private CollapseManager collapseManager; + private JTabbedPane tabbedPane; + + public static TerminalManager getInstance() { + if (instance == null) { + instance = new TerminalManager(); + } + return instance; + } + + private TerminalManager() { + this.tabbedPane = new JTabbedPane(); + this.tabbedPane.setName(TERMINAL_MANAGER); + this.collapseManager = new CollapseManager(tabbedPane); + } + + public void toggleVisibility() { + collapseManager.toggle(); + } + + public void addTerminal(Component component, TerminalExecutorMonitor monitor) { + if (!contains(component)) { + tabbedPane.addTab(monitor.getTitle(), component); + tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, new TerminalTabComponent(this)); + tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1); + + if (!monitors.containsKey(component)) { + monitors.put(component, monitor); + } + } + } + + public boolean contains(Component component) { + return tabbedPane.indexOfComponent(component) >= 0 || frames.containsKey(component); + } + + public String getTitleFor(TerminalTabComponent tabComponent) { + int i = tabbedPane.indexOfTabComponent(tabComponent); + if (i != -1) { + return tabbedPane.getTitleAt(i); + } + return ""; + } + + public void clear() { + closeAll(true); + clearFrames(); + } + + private void clearFrames() { + for (JFrame frame : frames.values()) { + frame.dispose(); + } + frames.clear(); + } + + public void closeAll(boolean forced) { + for (int i = tabbedPane.getTabCount() - 1; i >= 0; i--) { + close(tabbedPane.getComponentAt(i), forced); + } + } + + public void close(Component component, boolean forced) { + final TerminalExecutorMonitor monitor = monitors.get(component); + if (monitor != null && (forced || monitor.canClose())) { + monitor.disconnect(); + _close(component); + } + } + + private void _close(final Component component) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + int i = tabbedPane.indexOfComponent(component); + if (i >= 0) { + tabbedPane.remove(i); + } else if (frames.containsKey(component)) { + frames.remove(component).dispose(); + } + } + }); + } + + public void toTab(final Component component) { + int index = tabbedPane.indexOfComponent(component); + if (index < 0) { + final TerminalExecutorMonitor monitor = monitors.get(component); + _close(component); + addTerminal(component, monitor); + } + } + + public void toDialog(final Component component) { + int index = tabbedPane.indexOfComponent(component); + if (index >= 0) { + final String title = tabbedPane.getTitleAt(index); + _close(component); + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + final JFrame frame = createTerminalFrame(component, title, true); + frame.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + frame.dispose(); + } + }); + frame.setVisible(true); + frames.put(component, frame); + } + }); + } + } + + private static void removeMinMaxClose(Component comp) { + if (comp instanceof AbstractButton) { + comp.getParent().remove(comp); + } + if (comp instanceof Container) { + Component[] comps = ((Container) comp).getComponents(); + for (int x = 0, y = comps.length; x < y; x++) { + removeMinMaxClose(comps[x]); + } + } + } + + public static JFrame createTerminalFrame(final Component component, final String title, boolean removeMinMax) { + final JFrame frame = new JFrame(title) { + /** + * This method fixes the Synthetica laf bug that causes incorrect fullscreen window size on secondary monitor. + */ + @Override + public void setMaximizedBounds(Rectangle bounds) { + GraphicsDevice currentFrame = getGraphicsConfiguration().getDevice(); + if (UiUtil.isSecondaryScreen(currentFrame) && getExtendedState() == JFrame.NORMAL) { + super.setMaximizedBounds(UiUtil.getCurrentScreenSize(this)); + } else { + super.setMaximizedBounds(bounds); + } + } + + }; + + if (removeMinMax) { + removeMinMaxClose(frame); + } + + frame.setIconImage(((ImageIcon) ResourcesUtil.getIcon(ApplicationInfo.getVendor().toLowerCase() + ".logo")).getImage()); + frame.setAlwaysOnTop(false); + frame.getContentPane().setLayout(new BorderLayout()); + frame.getContentPane().add(component, BorderLayout.CENTER); + frame.setSize(600, 800); + return frame; + } + + public void showPopup(MouseEvent e) { + Component c = e.getComponent(); + if (c instanceof TerminalTabComponent) { + int index = tabbedPane.indexOfTabComponent(c); + tabbedPane.setSelectedIndex(index); + Component component = tabbedPane.getComponentAt(index); + if (SwingUtilities.isRightMouseButton(e)) { + TerminalExecutorMonitor monitor = monitors.get(component); + JPopupMenu pMenu = monitor.createMenu(component); + pMenu.addSeparator(); + pMenu.add(new JMenuItem(new CloseAllAction(true))); + pMenu.show(c, e.getX(), e.getY()); + } + } + } + + class CloseAllAction extends ViewAction { + + public CloseAllAction() { + this(false); + } + + public CloseAllAction(boolean label) { + super(label ? "Close All Monitors" : "", ResourcesUtil.getIcon("console.tab.closeall.icon"), "Close All Monitors"); + } + + @Override + public void actionPerformed(ActionEvent e) { + closeAll(false); + } + } + + public Component getComponent() { + return tabbedPane; + } +} diff --git a/src/eu/engys/core/executor/TerminalOutputStream.java b/src/eu/engys/core/executor/TerminalOutputStream.java new file mode 100644 index 0000000..5c8433e --- /dev/null +++ b/src/eu/engys/core/executor/TerminalOutputStream.java @@ -0,0 +1,68 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor; + +import java.io.IOException; +import java.io.OutputStream; + +public class TerminalOutputStream extends OutputStream { + + public static final char NEW_LINE = '\n'; + + private final StringBuffer charactersBuffer = new StringBuffer(128); + private final StringBuffer linesBuffer = new StringBuffer(); + + @Override + public void write(int c) throws IOException { + // append character to buffer + charactersBuffer.append((char) c); + // and newline appends to textarea + if (c == NEW_LINE) { + flush(); + } + } + + @Override + public void close() { + } + + @Override + public final void flush() { + String str = charactersBuffer.toString(); + linesBuffer.append(str); + charactersBuffer.setLength(0); + } + + public String flushLinesBuffer() { + String s = linesBuffer.toString(); + linesBuffer.setLength(0); + return s; + } + + public String peekLines() { + return linesBuffer.toString(); + } +} diff --git a/src/eu/engys/core/executor/TerminalSupport.java b/src/eu/engys/core/executor/TerminalSupport.java new file mode 100644 index 0000000..445a956 --- /dev/null +++ b/src/eu/engys/core/executor/TerminalSupport.java @@ -0,0 +1,86 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.getTestEnvironment; + +import java.io.File; +import java.io.IOException; + +import eu.engys.core.project.Model; +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; + +public class TerminalSupport { + + private static final String ACTION_NAME = "Open Terminal"; + + public static void openTerminal(Model model) { + if (Util.isWindows()) { + Executor.command("start", "cmd", "/K").inFolder(model.getProject().getBaseDir()).withOpenFoamEnv().env(getEnvironment(model)).description(ACTION_NAME).exec(); + } else { + Executor.command(getTerminal() + "$SHELL").inFolder(model.getProject().getBaseDir()).withOpenFoamEnv().env(getEnvironment(model)).description(ACTION_NAME).exec(); + } + } + + public static void openTerminal(File baseDir) { + if (Util.isWindows()) { + Executor.command("start", "cmd", "/K").inFolder(baseDir).withOpenFoamEnv().env(getTestEnvironment()).description(ACTION_NAME).exec(); + } else { + Executor.command(getTerminal() + "$SHELL").inFolder(baseDir).withOpenFoamEnv().env(getTestEnvironment()).description(ACTION_NAME).exec(); + } + } + + private static String getTerminal() { + String preferredTerminal = PrefUtil.getString(PrefUtil.HELYX_DEFAULT_TERMINAL); + if (preferredTerminal.isEmpty()) { + if (checkTerminal("gnome-terminal")) { + return "gnome-terminal --disable-factory --geometry 80x40 -e "; + } else if (checkTerminal("konsole")) { + return "konsole --geometry 80x40 -e "; + } else if (checkTerminal("xterm")) { + return "xterm -sb -font -*-fixed-medium-r-*-*-18-*-*-*-*-*-iso8859-* -geometry 80x40 -hold -e "; + } else { + System.err.println("No terminal found"); + } + } else { + return preferredTerminal + " -e "; + } + + return ""; + } + + private static boolean checkTerminal(String terminal) { + try { + new ProcessBuilder(terminal, "--help").start().waitFor(); + return true; + } catch (InterruptedException | IOException e) { + return false; + } + } +} diff --git a/src/eu/engys/core/executor/TerminalTabComponent.java b/src/eu/engys/core/executor/TerminalTabComponent.java new file mode 100644 index 0000000..af3ea61 --- /dev/null +++ b/src/eu/engys/core/executor/TerminalTabComponent.java @@ -0,0 +1,82 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.executor; + +import java.awt.FlowLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import eu.engys.util.ui.ResourcesUtil; + +public class TerminalTabComponent extends JPanel { + + private static final Icon CONSOLE_ICON = ResourcesUtil.getIcon("console.tab.icon"); + private final TerminalManager manager; + + public TerminalTabComponent(final TerminalManager terminalManager) { + super(new FlowLayout(FlowLayout.LEFT, 0, 0)); + if (terminalManager == null) { + throw new NullPointerException("TabbedPane is null"); + } + this.manager = terminalManager; + setOpaque(false); + + JLabel label = createTabComponent(); + add(label); + label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); + addMouseListener(showPopupMenuListener); + } + + private JLabel createTabComponent() { + JLabel label = new JLabel() { + @Override + public String getText() { + return manager.getTitleFor(TerminalTabComponent.this); + } + + @Override + public Icon getIcon() { + return CONSOLE_ICON; + } + }; + return label; + } + + private final MouseListener showPopupMenuListener = new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + manager.showPopup(e); + }; + }; +} diff --git a/src/eu/engys/core/executor/actions/CloseMonitorAction.java b/src/eu/engys/core/executor/actions/CloseMonitorAction.java new file mode 100644 index 0000000..1f50e97 --- /dev/null +++ b/src/eu/engys/core/executor/actions/CloseMonitorAction.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.JPanel; + +import eu.engys.core.executor.TerminalManager; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.ViewAction; + +public class CloseMonitorAction extends ViewAction { + + private JPanel panel; + + public CloseMonitorAction(JPanel panel) { + this(panel, false); + } + + public CloseMonitorAction(JPanel panel, boolean label) { + super(label ? "Close Current Monitor" : null, ResourcesUtil.getIcon("console.tab.close.icon"), "Close Current Monitor"); + this.panel = panel; + } + + @Override + public void actionPerformed(ActionEvent e) { + TerminalManager.getInstance().close(panel, false); + } +} diff --git a/src/eu/engys/core/executor/actions/CopyMonitorToClipboardAction.java b/src/eu/engys/core/executor/actions/CopyMonitorToClipboardAction.java new file mode 100644 index 0000000..b6ca06f --- /dev/null +++ b/src/eu/engys/core/executor/actions/CopyMonitorToClipboardAction.java @@ -0,0 +1,56 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor.actions; + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; + +import javax.swing.JTextArea; + +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.ViewAction; + +public class CopyMonitorToClipboardAction extends ViewAction { + + private JTextArea area; + + public CopyMonitorToClipboardAction(JTextArea area) { + this(area, false); + } + + public CopyMonitorToClipboardAction(JTextArea area, boolean label) { + super(label ? "Copy Log to Clipboard" : "", ResourcesUtil.getIcon("console.copy.icon"), "Copy Log to Clipboard"); + this.area = area; + } + + @Override + public void actionPerformed(ActionEvent e) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new StringSelection(area.getText()), null); + } +} diff --git a/src/eu/engys/core/executor/actions/MaximiseMonitorAction.java b/src/eu/engys/core/executor/actions/MaximiseMonitorAction.java new file mode 100644 index 0000000..ed50ec0 --- /dev/null +++ b/src/eu/engys/core/executor/actions/MaximiseMonitorAction.java @@ -0,0 +1,59 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.JPanel; + +import eu.engys.core.executor.TerminalManager; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.ViewAction; + +public class MaximiseMonitorAction extends ViewAction { + + private JPanel panel; + + public MaximiseMonitorAction(JPanel panel) { + this(panel, false); + } + + public MaximiseMonitorAction(JPanel panel, boolean label) { + super(label ? "Maximise Current Monitor" : null, ResourcesUtil.getIcon("console.tab.max.icon"), "Maximise Current Monitor"); + this.panel = panel; + putValue(SMALL_ICON + SELECTED_KEY, ResourcesUtil.getIcon("console.tab.restore.icon")); + putValue(SHORT_DESCRIPTION + SELECTED_KEY, "Restore"); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (isSelected()) { + TerminalManager.getInstance().toDialog(panel); + } else { + TerminalManager.getInstance().toTab(panel); + } + } +} diff --git a/src/eu/engys/core/executor/actions/SaveLogFileAction.java b/src/eu/engys/core/executor/actions/SaveLogFileAction.java new file mode 100644 index 0000000..e8ee606 --- /dev/null +++ b/src/eu/engys/core/executor/actions/SaveLogFileAction.java @@ -0,0 +1,97 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor.actions; + +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.IOException; + +import javax.swing.JOptionPane; +import javax.swing.JTextArea; + +import org.apache.commons.io.FileUtils; + +import eu.engys.util.PrefUtil; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class SaveLogFileAction extends ViewAction { + + private JTextArea area; + + public SaveLogFileAction(JTextArea area) { + this(area, false); + } + + public SaveLogFileAction(JTextArea area, boolean label) { + super(label ? "Save Log to File" : "", ResourcesUtil.getIcon("save.log.file"), "Save Log to File"); + this.area = area; + } + + @Override + public void actionPerformed(ActionEvent e) { + File workDir = PrefUtil.getWorkDir(PrefUtil.LAST_OPEN_EXPORT_DIR); + HelyxFileChooser fc = new HelyxFileChooser(workDir.getAbsolutePath()); + fc.setTitle("Save Log File"); + fc.setSelectionMode(SelectionMode.FILES_ONLY); + ReturnValue retVal = fc.showSaveAsDialog(); + if (retVal.isApprove()) { + File file = fc.getSelectedFile(); + if (file != null) { + if (file.exists()) { + int answer = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "File already exists. Overwrite?", "File Overwrite", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (answer == JOptionPane.YES_OPTION) { + writeToFile(file); + } + } else { + createFile(file); + writeToFile(file); + } + PrefUtil.putFile(PrefUtil.LAST_OPEN_EXPORT_DIR, file.getParentFile()); + } + } + } + + private void createFile(File file) { + try { + file.createNewFile(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + + private void writeToFile(File file) { + try { + FileUtils.writeStringToFile(file, area.getText()); + } catch (IOException e1) { + e1.printStackTrace(); + } + } +} diff --git a/src/eu/engys/core/executor/actions/ScrollLockAction.java b/src/eu/engys/core/executor/actions/ScrollLockAction.java new file mode 100644 index 0000000..ab68c32 --- /dev/null +++ b/src/eu/engys/core/executor/actions/ScrollLockAction.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.JTextArea; +import javax.swing.text.DefaultCaret; + +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.ViewAction; + +public class ScrollLockAction extends ViewAction { + + private JTextArea area; + + public ScrollLockAction(JTextArea area) { + this(area, false); + } + + public ScrollLockAction(JTextArea area, boolean label) { + super(label ? "Scroll Lock" : null, ResourcesUtil.getIcon("console.scroll.icon"), "Scroll Lock"); + this.area = area; + putValue(SMALL_ICON + SELECTED_KEY, ResourcesUtil.getIcon("console.scroll.lock.icon")); + putValue(SHORT_DESCRIPTION + SELECTED_KEY, "Scroll Lock"); + + } + + @Override + public void actionPerformed(ActionEvent e) { + if (isSelected()) { + DefaultCaret caret = (DefaultCaret) area.getCaret(); + caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE); + } else { + DefaultCaret caret = (DefaultCaret) area.getCaret(); + caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); + } + } + +} diff --git a/src/eu/engys/core/executor/actions/ShowLogAction.java b/src/eu/engys/core/executor/actions/ShowLogAction.java new file mode 100644 index 0000000..a291460 --- /dev/null +++ b/src/eu/engys/core/executor/actions/ShowLogAction.java @@ -0,0 +1,65 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor.actions; + +import java.awt.event.ActionEvent; +import java.io.File; + +import javax.swing.JOptionPane; + +import eu.engys.core.executor.FileManagerSupport; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class ShowLogAction extends ViewAction { + + public static final String OPEN_LOG_FILE = "Open Log File"; + + private File logFile; + + public ShowLogAction() { + this(false); + } + + public ShowLogAction(boolean label) { + super(label ? OPEN_LOG_FILE : null, ResourcesUtil.getIcon("console.browse.icon"), OPEN_LOG_FILE); + } + + public void setLogFile(File logFile) { + this.logFile = logFile; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (logFile != null && logFile.exists()) { + FileManagerSupport.open(logFile); + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "No log file has been created.", "File System error", JOptionPane.ERROR_MESSAGE); + } + } + +} diff --git a/src/eu/engys/core/executor/actions/StopCommandAction.java b/src/eu/engys/core/executor/actions/StopCommandAction.java new file mode 100644 index 0000000..4272fe5 --- /dev/null +++ b/src/eu/engys/core/executor/actions/StopCommandAction.java @@ -0,0 +1,57 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.executor.actions; + +import java.awt.event.ActionEvent; + +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.ViewAction; + +public class StopCommandAction extends ViewAction { + + public static final String STOP_EXECUTION = "Stop Execution"; + + private Runnable stopCommand; + + public StopCommandAction() { + this(false); + } + + public StopCommandAction(boolean label) { + super(label ? STOP_EXECUTION : null, ResourcesUtil.getIcon("console.stop.icon"), STOP_EXECUTION); + } + + public void setStopCommand(Runnable stopCommand) { + this.stopCommand = stopCommand; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (stopCommand != null) { + stopCommand.run(); + } + } +} diff --git a/src/eu/engys/core/modules/ApplicationModule.java b/src/eu/engys/core/modules/ApplicationModule.java new file mode 100644 index 0000000..16d5ac6 --- /dev/null +++ b/src/eu/engys/core/modules/ApplicationModule.java @@ -0,0 +1,91 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules; + +import java.util.Set; + +import eu.engys.core.modules.boundaryconditions.BoundaryConditionsView; +import eu.engys.core.modules.cellzones.CellZonesView; +import eu.engys.core.modules.materials.MaterialsView; +import eu.engys.core.modules.solutionmodelling.SolutionView; +import eu.engys.core.modules.tree.TreeView; +import eu.engys.core.project.InvalidProjectException; +import eu.engys.core.project.state.SolverFamily; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; + +public interface ApplicationModule { + + TreeView getTreeView(); + + Set getCaseSetupPanels(); + + SolutionView getSolutionView(); + + MaterialsView getMaterialsView(); + + BoundaryConditionsView getBoundaryConditionsView(); + + CellZonesView getCellZonesView(); + + FieldsInitialisationView getFieldsInitialisationView(); + + String getName(); + + void loadState() throws InvalidProjectException; + + void loadMaterials(); + + void save(); + + void write(); + + void saveDefaultsToProject(); + + void saveDefaultsTurbulenceModelsToProject(); + + void saveMaterialsToProject(); + + Fields loadDefaultsFields(String region); + +// void initialiseFields(Controller controller, ExecutorService service, Server server); + + CaseSetupWriter getCaseSetupWriter(); + + CaseSetupReader getCaseSetupReader(); + + boolean isFieldInitialisationVetoed(Field field); + + boolean isNonNewtonianViscosityModelVetoed(); + + void updateSolver(State state); + + void updateSolverFamilies(State state, Set families); + + boolean checkLicense(); + +} diff --git a/src/eu/engys/core/modules/ApplicationModuleAdapter.java b/src/eu/engys/core/modules/ApplicationModuleAdapter.java new file mode 100644 index 0000000..95d49f4 --- /dev/null +++ b/src/eu/engys/core/modules/ApplicationModuleAdapter.java @@ -0,0 +1,124 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules; + +import java.util.Collections; +import java.util.Set; + +import eu.engys.core.modules.boundaryconditions.BoundaryConditionsView; +import eu.engys.core.modules.cellzones.CellZonesView; +import eu.engys.core.modules.materials.MaterialsView; +import eu.engys.core.modules.tree.TreeView; +import eu.engys.core.project.state.SolverFamily; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.fields.Field; + +public abstract class ApplicationModuleAdapter implements ApplicationModule { + + @Override + public boolean checkLicense() { + return true; + } + + @Override + public void loadMaterials() { + } + + @Override + public void saveDefaultsToProject() { + } + + @Override + public void saveDefaultsTurbulenceModelsToProject() { + } + + @Override + public void saveMaterialsToProject() { + } + +// @Override +// public void initialiseFields(Controller controller, ExecutorService service, Server server) { +// } + + @Override + public void updateSolver(State state) { + } + + @Override + public void updateSolverFamilies(State state, Set families) { + } + + @Override + public TreeView getTreeView() { + return null; + } + + @Override + public MaterialsView getMaterialsView() { + return null; + } + + @Override + public BoundaryConditionsView getBoundaryConditionsView() { + return null; + } + + @Override + public CellZonesView getCellZonesView() { + return null; + } + + @Override + public FieldsInitialisationView getFieldsInitialisationView() { + return null; + } + + @Override + public CaseSetupReader getCaseSetupReader() { + return null; + } + + @Override + public CaseSetupWriter getCaseSetupWriter() { + return null; + } + + @Override + public Set getCaseSetupPanels() { + return Collections. emptySet(); + } + + @Override + public boolean isFieldInitialisationVetoed(Field field) { + return false; + } + + @Override + public boolean isNonNewtonianViscosityModelVetoed() { + return false; + } + +} diff --git a/src/eu/engys/core/modules/CaseSetupReader.java b/src/eu/engys/core/modules/CaseSetupReader.java new file mode 100644 index 0000000..0299813 --- /dev/null +++ b/src/eu/engys/core/modules/CaseSetupReader.java @@ -0,0 +1,41 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; + +public interface CaseSetupReader { + + void readFromState(State state, String stateString); + + void readFromConstant(Model loadedModel, Dictionary constant); + + void readFromSystem(Dictionary system); + + void readMaterials(Model model, Dictionary globals); +} diff --git a/src/eu/engys/core/modules/CaseSetupWriter.java b/src/eu/engys/core/modules/CaseSetupWriter.java new file mode 100644 index 0000000..5adf001 --- /dev/null +++ b/src/eu/engys/core/modules/CaseSetupWriter.java @@ -0,0 +1,39 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; + +public interface CaseSetupWriter { + + void addState(StringBuffer sb); + + void addToMaterials(Model model, Dictionary materialProperties); + void addToConstant(Dictionary constantFolder); + void addToSystem(Dictionary constantFolder); + +} diff --git a/src/eu/engys/core/modules/FieldsInitialisationView.java b/src/eu/engys/core/modules/FieldsInitialisationView.java new file mode 100644 index 0000000..5211ba9 --- /dev/null +++ b/src/eu/engys/core/modules/FieldsInitialisationView.java @@ -0,0 +1,38 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.modules; + +import java.util.List; + +import javax.swing.Action; + + +public interface FieldsInitialisationView { + + void configure(List actions); + +} diff --git a/src/eu/engys/core/modules/ModuleDefaults.java b/src/eu/engys/core/modules/ModuleDefaults.java new file mode 100644 index 0000000..40dbfae --- /dev/null +++ b/src/eu/engys/core/modules/ModuleDefaults.java @@ -0,0 +1,72 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.defaults.AbstractDefaultsProvider; +import eu.engys.core.project.defaults.DefaultsProvider; + +public class ModuleDefaults extends AbstractDefaultsProvider { + + private ApplicationModule module; + private DefaultsProvider parent; + private Dictionary fieldsData; + private Dictionary stateData; + private Dictionary turbulenceProperties; + + public ModuleDefaults(ApplicationModule module, DefaultsProvider parent, Dictionary linkResolver) { + this.module = module; + this.parent = parent; + this.fieldsData = ModulesUtil.readDictionary(module, linkResolver, module.getName() + ".fields"); + this.stateData = ModulesUtil.readDictionary(module, linkResolver, module.getName() + ".stateData"); + this.turbulenceProperties = ModulesUtil.readDictionary(module, linkResolver, module.getName() + ".turbulenceProperties"); + } + + @Override + public String getName() { + return module.getName() + " module"; + } + + @Override + public Dictionary getDefaultFieldsData() { + return fieldsData; + } + + @Override + public Dictionary getDefaultStateData() { + return stateData; + } + + @Override + public Dictionary getDefaultTurbulenceProperties() { + return turbulenceProperties; + } + + @Override + public Dictionary getStates() { + return stateData.found("states") ? stateData.subDict("states") : parent.getStates(); + } +} diff --git a/src/eu/engys/core/modules/ModulePanel.java b/src/eu/engys/core/modules/ModulePanel.java new file mode 100644 index 0000000..2e0e850 --- /dev/null +++ b/src/eu/engys/core/modules/ModulePanel.java @@ -0,0 +1,40 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules; + +import javax.swing.JComponent; + + +public interface ModulePanel { + + String getTitle(); + String getKey(); + + JComponent getPanel(); + + int getIndex(); + +} diff --git a/src/eu/engys/core/modules/ModulesUtil.java b/src/eu/engys/core/modules/ModulesUtil.java new file mode 100644 index 0000000..c24148e --- /dev/null +++ b/src/eu/engys/core/modules/ModulesUtil.java @@ -0,0 +1,275 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.swing.Action; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryLinkResolver; +import eu.engys.core.dictionary.parser.DictionaryReader2; +import eu.engys.core.modules.boundaryconditions.BoundaryConditionsView; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.modules.boundaryconditions.IBoundaryConditionsPanel; +import eu.engys.core.modules.cellzones.CellZonesView; +import eu.engys.core.modules.materials.MaterialsView; +import eu.engys.core.modules.tree.ModuleElementPanel; +import eu.engys.core.modules.tree.TreeView; +import eu.engys.core.project.InvalidProjectException; +import eu.engys.core.project.state.SolverFamily; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.cellzones.CellZoneType; +import eu.engys.core.project.zero.cellzones.CellZones; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.util.ui.builder.PanelBuilder; + +public class ModulesUtil { + + private static final Logger logger = LoggerFactory.getLogger(ModulesUtil.class); + public static final String EXCEPTION_MESSAGE = "You need a valid license for %s add-on module to open this case!"; + + public static Dictionary readDictionary(ApplicationModule module, Dictionary linkResolver, String resource) { + String resourcePath = module.getClass().getPackage().getName().replace(".", "/") + "/resources" + "/" + resource; + InputStream is = ModulesUtil.class.getClassLoader().getResourceAsStream(resourcePath); + if (is != null) { + if (linkResolver != null) { + return new Dictionary(resource, is, new DictionaryLinkResolver(linkResolver)); + } else { + return new Dictionary(resource, is); + } + } else { + logger.warn("FILE NOT FOUND: {}", resourcePath); + return null; + } + } + + public static Dictionary readDictionary2(ApplicationModule module, String resource) { + String resourcePath = module.getClass().getPackage().getName().replace(".", "/") + "/resources" + "/" + resource; + InputStream is = ModulesUtil.class.getClassLoader().getResourceAsStream(resourcePath); + if (is != null) { + + Dictionary dictionary = new Dictionary(resource); + DictionaryReader2 reader = new DictionaryReader2(dictionary); + reader.read(is); + + return dictionary; + } else { + logger.warn("FILE NOT FOUND: {}", resourcePath); + return null; + } + } + + public static Dictionary extractRelativeToStateSettings(String encodedPrimalState, Dictionary mDict) { + if (mDict.found("requirements")) { + Dictionary requirements = (Dictionary) mDict.remove("requirements"); + if (requirements.found("conditional")) { + if (requirements.subDict("conditional").found(encodedPrimalState)) { + Dictionary conditional = requirements.subDict("conditional").subDict(encodedPrimalState); + return conditional; + } + } + } + return null; + } + + public static void updateStateFromGUI(Set modules) { + for (ApplicationModule module : modules) { + module.getSolutionView().updateStateFromGUI(); + } + } + + public static void loadState(Set modules) throws InvalidProjectException { + for (ApplicationModule module : modules) { + module.loadState(); + } + } + + public static void updateSolver(Set modules, State state) { + for (ApplicationModule module : modules) { + module.updateSolver(state); + } + } + + public static void updateSolverFamilies(Set modules, State state, Set families) { + for (ApplicationModule module : modules) { + module.updateSolverFamilies(state, families); + } + } + + public static void loadMaterials(Set modules) { + for (ApplicationModule module : modules) { + module.loadMaterials(); + } + } + + public static void saveDefaultsToProject(Set modules) { + for (ApplicationModule module : modules) { + module.saveDefaultsToProject(); + } + } + + public static void saveDefaultsTurbulenceModelsToProject(Set modules) { + for (ApplicationModule module : modules) { + module.saveDefaultsTurbulenceModelsToProject(); + } + } + + public static void saveDefaultMaterialsToProject(Set modules) { + for (ApplicationModule module : modules) { + module.saveMaterialsToProject(); + } + } + + public static void save(Set modules) { + for (ApplicationModule module : modules) { + module.save(); + } + } + +// public static void initaliseFields(Set modules, Controller controller, ExecutorService service, Server server) { +// for (ApplicationModule module : modules) { +// module.initialiseFields(controller, service, server); +// } +// } + + public static Fields loadFieldsFromDefaults(Set modules, String region) { + Fields fields = new Fields(); + for (ApplicationModule module : modules) { + fields.merge(module.loadDefaultsFields(region)); + } + return fields; + } + + public static void configureMaterialsView(Set modules, PanelBuilder parametersBuilder) { + for (ApplicationModule module : modules) { + MaterialsView materialsView = module.getMaterialsView(); + if (materialsView == null) { + continue; + } + materialsView.configure(parametersBuilder); + } + } + + public static void configureFieldsInitialization(Set modules, List actions) { + for (ApplicationModule module : modules) { + FieldsInitialisationView fieldsView = module.getFieldsInitialisationView(); + if (fieldsView == null) { + continue; + } + fieldsView.configure(actions); + } + } + + public static void configureBoundaryConditionsView(Set modules, IBoundaryConditionsPanel panel) { + for (ApplicationModule module : modules) { + BoundaryConditionsView boundaryConditionsView = module.getBoundaryConditionsView(); + if (boundaryConditionsView == null) + continue; + boundaryConditionsView.configure(panel); + } + } + + public static void configureBoundaryConditionsView(Set modules, BoundaryTypePanel typePanel) { + for (ApplicationModule module : modules) { + BoundaryConditionsView boundaryConditionsView = module.getBoundaryConditionsView(); + if (boundaryConditionsView == null) + continue; + boundaryConditionsView.configure(typePanel); + } + } + + public static List getCellZoneTypes(Set modules) { + List moduleCellZoneTypes = new ArrayList(); + for (ApplicationModule module : modules) { + CellZonesView cellZonesView = module.getCellZonesView(); + if (cellZonesView != null){ + moduleCellZoneTypes.addAll(cellZonesView.getCellZoneTypes()); + } + } + return moduleCellZoneTypes; + } + + public static void updateCellZonesFromModel(Set modules, CellZones cellZones) { + for (ApplicationModule module : modules) { + CellZonesView cellZonesView = module.getCellZonesView(); + if (cellZonesView == null) + continue; + cellZonesView.updateCellZonesFromModel(cellZones); + } + } + + public static void updateModelFromCellZones(Set modules) { + for (ApplicationModule module : modules) { + CellZonesView cellZonesView = module.getCellZonesView(); + if (cellZonesView == null) + continue; + cellZonesView.updateModelFromCellZones(); + } + } + + public static boolean isFieldInitialisationVetoed(Field field, Set modules) { + for (ApplicationModule module : modules) { + if (module.isFieldInitialisationVetoed(field)) + return true; + } + return false; + } + + public static boolean isNonNewtonianViscosityModelVetoed(Set modules) { + for (ApplicationModule module : modules) { + if (module.isNonNewtonianViscosityModelVetoed()) + return true; + } + return false; + } + + public static Set getCaseSetupPanels(Set modules) { + Set panels = new HashSet<>(); + for (ApplicationModule module : modules) { + panels.addAll(module.getCaseSetupPanels()); + } + return panels; + } + + public static void updateTree(Set modules, ModuleElementPanel viewElementPanel) { + for (ApplicationModule module : modules) { + TreeView treeView = module.getTreeView(); + if (treeView == null) + continue; + treeView.updateTree(viewElementPanel); + } + } + +} diff --git a/src/eu/engys/core/modules/boundaryconditions/BoundaryConditionsView.java b/src/eu/engys/core/modules/boundaryconditions/BoundaryConditionsView.java new file mode 100644 index 0000000..4233824 --- /dev/null +++ b/src/eu/engys/core/modules/boundaryconditions/BoundaryConditionsView.java @@ -0,0 +1,38 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules.boundaryconditions; + +public interface BoundaryConditionsView { + + // to be removed once the names are fixed + public static final String SINGLE_SPACE = " "; + public static final String DOUBLE_SPACE = " "; + + void configure(BoundaryTypePanel typePanel); + + void configure(IBoundaryConditionsPanel panel); + +} diff --git a/src/eu/engys/core/modules/boundaryconditions/BoundaryTypePanel.java b/src/eu/engys/core/modules/boundaryconditions/BoundaryTypePanel.java new file mode 100644 index 0000000..cb6ea78 --- /dev/null +++ b/src/eu/engys/core/modules/boundaryconditions/BoundaryTypePanel.java @@ -0,0 +1,68 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.modules.boundaryconditions; + +import java.awt.Component; + +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.core.project.zero.patches.Patch; + +public interface BoundaryTypePanel { + + public static final String MOMENTUM = "Momentum"; + + public static final String TURBULENCE = "Turbulence"; + public static final String THERMAL = "Thermal"; + public static final String PASSIVE_SCALARS = "Passive Scalars"; + public static final String PHASE_FRACTION = "Phase Fraction"; + + void layoutPanel(); + + void loadFromPatches(Patch... patches); + + void saveToPatch(Patch patch); + + BoundaryType getType(); + Component getPanel(); + + ParametersPanel getMomentumPanel(); + ParametersPanel getTurbulencePanel(); + ParametersPanel getThermalPanel(); + ParametersPanel getPanel(String name); + + void stateChanged(); + void materialsChanged(); + + void addMomentumPanel(ParametersPanel momentumPanel); + void addTurbulencePanel(ParametersPanel momentumPanel); + void addThermalPanel(ParametersPanel momentumPanel); + + void addPanel(String name, ParametersPanel pPanel); + void addPanel(String name, ParametersPanel pPanel, int index); + + void resetToDefault(); +} diff --git a/src/eu/engys/core/modules/boundaryconditions/IBoundaryConditionsPanel.java b/src/eu/engys/core/modules/boundaryconditions/IBoundaryConditionsPanel.java new file mode 100644 index 0000000..81978c3 --- /dev/null +++ b/src/eu/engys/core/modules/boundaryconditions/IBoundaryConditionsPanel.java @@ -0,0 +1,34 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules.boundaryconditions; + + +public interface IBoundaryConditionsPanel { + + void addTypePanel(BoundaryTypePanel panel); + void removeTypePanel(BoundaryTypePanel panel); + +} diff --git a/src/eu/engys/core/modules/boundaryconditions/ParametersPanel.java b/src/eu/engys/core/modules/boundaryconditions/ParametersPanel.java new file mode 100644 index 0000000..bebd08b --- /dev/null +++ b/src/eu/engys/core/modules/boundaryconditions/ParametersPanel.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.modules.boundaryconditions; + +import javax.swing.JPanel; + +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryConditions; + +public interface ParametersPanel { + + public String getTitle(); + public JPanel getComponent(); + public void tabChanged(Model model); + public void stateChanged(Model model); + public void materialsChanged(Model model); + public DictionaryModel getDictionaryModel(); + + public void loadFromBoundaryConditions(String patchName, BoundaryConditions bc); + public void saveToBoundaryConditions(String patchName, BoundaryConditions bc); + + public void setMultipleEditing(boolean multipleSelection); + public boolean canEdit(); + public boolean isEnabled(Model model); + public void resetToDefault(Model model); +} diff --git a/src/eu/engys/core/modules/cellzones/CellZonePanel.java b/src/eu/engys/core/modules/cellzones/CellZonePanel.java new file mode 100644 index 0000000..138231b --- /dev/null +++ b/src/eu/engys/core/modules/cellzones/CellZonePanel.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.modules.cellzones; + +import static eu.engys.util.Symbols.KELVIN; +import static eu.engys.util.Symbols.SQUARE; + +import javax.swing.JComponent; + +import eu.engys.core.dictionary.Dictionary; + +public interface CellZonePanel { + + public static final String MODEL_LABEL = "Model"; + + /* + * MRF + */ + public static final String ORIGIN_LABEL = "Origin"; + public static final String AXIS_LABEL = "Axis"; + public static final String OMEGA_RAD_S_LABEL = "Omega [rad/s]"; + + /* + * Porous + */ + public static final String C1_LABEL = "C1"; + public static final String C0_LABEL = "C0"; + public static final String POWER_LAW = "Power-law"; + public static final String DARCY_FORCHHEIMER = "Darcy-Forchheimer"; + public static final String INERTIAL_LOSS_LABEL = "Inertial Loss Coefficient [1/m]"; + public static final String VISCOUS_LOSS_LABEL = "Viscous Loss Coefficient [1/m" + SQUARE + "]"; + public static final String E2_LABEL = "e2 [m]"; + public static final String E1_LABEL = "e1 [m]"; + + /* + * Thermal + */ + public static final String FIXED_TEMPERATURE_LABEL = "Fixed Temperature"; + public static final String FIXED_TEMPERATURE_K_LABEL = "Fixed Temperature " + KELVIN; + + // CellZoneType getType(); + + JComponent getPanel(); + + void stateChanged(); + + void loadFromDictionary(Dictionary cellZoneDictionary); + + Dictionary saveToDictionary(); + + // Dictionary getDefault(); + + void layoutPanel(); + + // boolean isEnabled(); + +} diff --git a/src/eu/engys/core/modules/cellzones/CellZonesView.java b/src/eu/engys/core/modules/cellzones/CellZonesView.java new file mode 100644 index 0000000..2669ecb --- /dev/null +++ b/src/eu/engys/core/modules/cellzones/CellZonesView.java @@ -0,0 +1,41 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules.cellzones; + +import java.util.List; + +import eu.engys.core.project.zero.cellzones.CellZoneType; +import eu.engys.core.project.zero.cellzones.CellZones; + +public interface CellZonesView { + + public List getCellZoneTypes(); + + public void updateCellZonesFromModel(CellZones cellZones); + + public void updateModelFromCellZones(); + +} diff --git a/src/eu/engys/core/modules/materials/MaterialsBuilder.java b/src/eu/engys/core/modules/materials/MaterialsBuilder.java new file mode 100644 index 0000000..cd710c0 --- /dev/null +++ b/src/eu/engys/core/modules/materials/MaterialsBuilder.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.modules.materials; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; + +public interface MaterialsBuilder { + + Dictionary saveCompressible(Model model, Dictionary materialGUIDict); + + Dictionary saveIncompressible(Model model, Dictionary materialDict); + + Dictionary toGUIFormat(Dictionary defaultMaterialDict); + + Dictionary loadCompressible(Model model); + +} diff --git a/src/eu/engys/core/modules/materials/MaterialsDatabase.java b/src/eu/engys/core/modules/materials/MaterialsDatabase.java new file mode 100644 index 0000000..1e9dac8 --- /dev/null +++ b/src/eu/engys/core/modules/materials/MaterialsDatabase.java @@ -0,0 +1,93 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules.materials; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.defaults.Defaults; + +public class MaterialsDatabase { + + private Map compressibleMaterialsMap = new HashMap<>(); + private Map incompressibleMaterialsMap = new HashMap<>(); + public static final String AIR = "air"; + public static final String MERCURY = "mercury"; + public static final String WATER = "water"; + public static final String OIL = "oil"; + + @Inject + public MaterialsDatabase(Defaults defaults) { + load(defaults); + } + + private void load(Defaults defaults) { + compressibleMaterialsMap.clear(); + incompressibleMaterialsMap.clear(); + + Dictionary compressibleMaterials = defaults.getCompressibleMaterials(); + Dictionary incompressibleMaterials = defaults.getIncompressibleMaterials(); + + for (Dictionary matDict : compressibleMaterials.getDictionaries()) { + matDict.add("materialName", matDict.getName()); + compressibleMaterialsMap.put(matDict.getName(), matDict); + } + for (Dictionary matDict : incompressibleMaterials.getDictionaries()) { + matDict.add("materialName", matDict.getName()); + incompressibleMaterialsMap.put(matDict.getName(), matDict); + } + } + + public Map getCompressibleMaterialsMap() { + return compressibleMaterialsMap; + } + + public Map getIncompressibleMaterialsMap() { + return incompressibleMaterialsMap; + } + + public Collection getCompressibleMaterials() { + return Collections.unmodifiableCollection(compressibleMaterialsMap.values()); + } + + public Collection getIncompressibleMaterials() { + return Collections.unmodifiableCollection(incompressibleMaterialsMap.values()); + } + + public Dictionary getCompressibleMaterial(String materialName) { + return new Dictionary(compressibleMaterialsMap.get(materialName)); + } + + public Dictionary getIncompressibleMaterial(String materialName) { + return new Dictionary(incompressibleMaterialsMap.get(materialName)); + } + +} diff --git a/src/eu/engys/core/modules/materials/MaterialsView.java b/src/eu/engys/core/modules/materials/MaterialsView.java new file mode 100644 index 0000000..ac7a191 --- /dev/null +++ b/src/eu/engys/core/modules/materials/MaterialsView.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.modules.materials; + +import eu.engys.core.project.materials.Material; +import eu.engys.util.ui.builder.PanelBuilder; + +public interface MaterialsView { + + void updateGUIFromModel(Material material); + + void updateModelFromGUI(Material material); + + void configure(PanelBuilder builder); + + void updateDefaultMaterial(Material material); + +} diff --git a/src/eu/engys/core/modules/solutionmodelling/AbstractSolutionView.java b/src/eu/engys/core/modules/solutionmodelling/AbstractSolutionView.java new file mode 100644 index 0000000..d84f361 --- /dev/null +++ b/src/eu/engys/core/modules/solutionmodelling/AbstractSolutionView.java @@ -0,0 +1,86 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules.solutionmodelling; + +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.ThermalState; +import eu.engys.util.ui.ChooserPanel; +import eu.engys.util.ui.builder.PanelBuilder; + +public class AbstractSolutionView implements SolutionView { + + @Override + public void buildSolution(ChooserPanel solutionPanel) { + } + + @Override + public void buildMultiphase(MultiphaseBuilder builder) { + } + + @Override + public void buildScalar(SolutionModellingPanel solutionPanel) { + } + + @Override + public void buildDynamic(PanelBuilder builder) { + } + + @Override + public void buildThermal(PanelBuilder builder) { + } + + @Override + public void updateGUIFromState(State state) { + SolutionState ss = new SolutionState(state); + fixSolutionState(ss); + fixMultiphase(state.getMultiphaseModel()); + fixThermal(ss, new ThermalState(state)); + } + + @Override + public void updateStateFromGUI() { + } + + @Override + public boolean hasChanged() { + return false; + } + + @Override + public void fixSolutionState(SolutionState ss) { + } + + @Override + public void fixMultiphase(MultiphaseModel mm) { + } + + @Override + public void fixThermal(SolutionState ss, ThermalState ts) { + } + +} diff --git a/src/eu/engys/core/modules/solutionmodelling/MultiphaseBuilder.java b/src/eu/engys/core/modules/solutionmodelling/MultiphaseBuilder.java new file mode 100644 index 0000000..de060de --- /dev/null +++ b/src/eu/engys/core/modules/solutionmodelling/MultiphaseBuilder.java @@ -0,0 +1,41 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules.solutionmodelling; + +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.util.ui.textfields.SpinnerField; + +public interface MultiphaseBuilder { + + void addMultiphaseChoice(MultiphaseModel vofModel); + + SpinnerField getPhasesField(); + + void enableChoice(MultiphaseModel eulerEulerModel); + + void disableChoice(MultiphaseModel eulerEulerModel); + +} diff --git a/src/eu/engys/core/modules/solutionmodelling/SolutionModellingPanel.java b/src/eu/engys/core/modules/solutionmodelling/SolutionModellingPanel.java new file mode 100644 index 0000000..d598907 --- /dev/null +++ b/src/eu/engys/core/modules/solutionmodelling/SolutionModellingPanel.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.modules.solutionmodelling; + +import eu.engys.util.ui.ChooserPanel; +import eu.engys.util.ui.builder.PanelBuilder; + +public interface SolutionModellingPanel { + + PanelBuilder getDynamicBuilder(); + + MultiphaseBuilder getMultiphasePanel(); + + ChooserPanel getSolverTypePanel(); + + PanelBuilder getScalarsBuilderLeft(); + + PanelBuilder getScalarsBuilderRight(); + +} diff --git a/src/eu/engys/core/modules/solutionmodelling/SolutionView.java b/src/eu/engys/core/modules/solutionmodelling/SolutionView.java new file mode 100644 index 0000000..2aac1d4 --- /dev/null +++ b/src/eu/engys/core/modules/solutionmodelling/SolutionView.java @@ -0,0 +1,59 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules.solutionmodelling; + +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.ThermalState; +import eu.engys.util.ui.ChooserPanel; +import eu.engys.util.ui.builder.PanelBuilder; + +public interface SolutionView { + + void buildSolution(ChooserPanel solutionPanel); + + void buildThermal(PanelBuilder builder); + + void buildMultiphase(MultiphaseBuilder builder); + + void buildDynamic(PanelBuilder builder); + + void buildScalar(SolutionModellingPanel solutionPanel); + + void updateGUIFromState(State state); + + void updateStateFromGUI(); + + boolean hasChanged(); + + void fixSolutionState(SolutionState ss); + + void fixMultiphase(MultiphaseModel mm); + + void fixThermal(SolutionState ss, ThermalState ts); + +} diff --git a/src/eu/engys/core/modules/tree/ModuleElementPanel.java b/src/eu/engys/core/modules/tree/ModuleElementPanel.java new file mode 100644 index 0000000..de1c024 --- /dev/null +++ b/src/eu/engys/core/modules/tree/ModuleElementPanel.java @@ -0,0 +1,35 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules.tree; + +import eu.engys.core.modules.ModulePanel; + +public interface ModuleElementPanel { + + void addPanel(ModulePanel phasesPanel); + void removePanel(ModulePanel phasesPanel); + +} diff --git a/src/eu/engys/core/modules/tree/TreeView.java b/src/eu/engys/core/modules/tree/TreeView.java new file mode 100644 index 0000000..fdb848a --- /dev/null +++ b/src/eu/engys/core/modules/tree/TreeView.java @@ -0,0 +1,32 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.modules.tree; + +public interface TreeView { + + void updateTree(ModuleElementPanel viewElementPanel); + +} diff --git a/src/eu/engys/core/parameters/Parameter.java b/src/eu/engys/core/parameters/Parameter.java new file mode 100644 index 0000000..8c34f6d --- /dev/null +++ b/src/eu/engys/core/parameters/Parameter.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.parameters; + +import java.io.Serializable; + +import eu.engys.util.ui.builder.PanelBuilder; + +public interface Parameter extends Serializable { + + public interface ParameterKey extends Serializable { + void generateKey(); + } + + public interface ParameterKeyArgument extends Serializable { + String getArgument(); + } + + ParameterKey getKey(); + + void setName(String name); + String getName(); + + void populate(PanelBuilder builder); + + Number getValue(int component); + + void setValue(Number value, int component); + + Parameter cloneParameter(); + +} diff --git a/src/eu/engys/core/parameters/Parameters.java b/src/eu/engys/core/parameters/Parameters.java new file mode 100644 index 0000000..55a0228 --- /dev/null +++ b/src/eu/engys/core/parameters/Parameters.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.parameters; + +import java.io.Serializable; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import eu.engys.core.parameters.Parameter.ParameterKey; +import eu.engys.util.ui.builder.PanelBuilder; + +public class Parameters implements Serializable { + + private Map delegate = new HashMap<>(); + + public Parameters(Parameters parameters) { + for (ParameterKey key : parameters.delegate.keySet()) { + Parameter parameter = parameters.get(key).cloneParameter(); + add(parameter); + } + } + + public Parameters() { + } + + public void add(Parameter p) { + delegate.put(p.getKey(), p); + } + + public Parameter get(ParameterKey key) { + return delegate.get(key); + } + + public int getSize() { + return delegate.size(); + } + + public void clear() { + delegate.clear(); + } + + public void populate(PanelBuilder builder) { + for (ParameterKey key : delegate.keySet()) { + Parameter p = delegate.get(key); + p.populate(builder); + } + } + + public Collection values() { + return delegate.values(); + } + + public Parameter get(String keyString) { + for (ParameterKey key : delegate.keySet()) { + if (key.toString().equals(keyString)) { + return delegate.get(key); + } + } + return null; + } + + public void print() { + for (ParameterKey key : delegate.keySet()) { + System.out.println("[print] " + key.getClass().getSimpleName()); + } + } + + public Map toMap() { + return delegate; + } + +} diff --git a/src/eu/engys/core/presentation/Action.java b/src/eu/engys/core/presentation/Action.java new file mode 100644 index 0000000..90a937f --- /dev/null +++ b/src/eu/engys/core/presentation/Action.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.presentation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import com.google.inject.BindingAnnotation; + +@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME) +public @interface Action { + String key(); + boolean checkLicense() default false; + boolean checkEnv() default false; +} diff --git a/src/eu/engys/core/presentation/ActionContainer.java b/src/eu/engys/core/presentation/ActionContainer.java new file mode 100644 index 0000000..7bb2052 --- /dev/null +++ b/src/eu/engys/core/presentation/ActionContainer.java @@ -0,0 +1,31 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.presentation; + +public interface ActionContainer { + + boolean isDemo(); +} diff --git a/src/eu/engys/core/presentation/ActionManager.java b/src/eu/engys/core/presentation/ActionManager.java new file mode 100644 index 0000000..d95fb93 --- /dev/null +++ b/src/eu/engys/core/presentation/ActionManager.java @@ -0,0 +1,140 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.presentation; + +import java.awt.event.ActionEvent; +import java.lang.reflect.Method; + +import javax.swing.ActionMap; +import javax.swing.Icon; + +import eu.engys.core.OpenFOAMEnvironment; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class ActionManager { + + private static ActionManager instance; + private ActionMap map = new ActionMap(); + + public static ActionManager getInstance() { + if (instance == null) + instance = new ActionManager(); + return instance; + } + + public void parseActions(final ActionContainer o) { + Class klass = o.getClass(); + + for (final Method m : klass.getMethods()) { + Action action = m.getAnnotation(Action.class); + if (action != null) { + String key = action.key(); + final boolean checkEnv = action.checkEnv(); + final boolean checkLic = action.checkLicense(); + +// System.out.println("ActionManager.parseActions() FOUND: "+key); + + String label = ResourcesUtil.getString(key+".label"); + String tooltip = ResourcesUtil.getString(key+".tooltip"); + Icon icon = ResourcesUtil.getIcon(key+".icon"); + + map.put(key, new ViewAction(label, icon, tooltip) { + @Override + public void actionPerformed(ActionEvent e) { + try { + if (checkLic) { + if (o.isDemo()) { + UiUtil.showDemoMessage(); + return; + } + } + if (checkEnv) { + if (!OpenFOAMEnvironment.isEnvironementLoaded()) { + UiUtil.showCoreEnvironmentNotLoadedWarning(); + return; + } + } + + m.invoke(o); + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + }); + } + ActionToggle actionToggle = m.getAnnotation(ActionToggle.class); + if (actionToggle != null) { + Class[] parameterTypes = m.getParameterTypes(); + if (parameterTypes.length != 1 || (parameterTypes.length == 1 && !parameterTypes[0].equals(boolean.class)) ) { + throw new RuntimeException("'ActionToggle' annotation: the method must have 1 boolean parameter"); + } + String key = actionToggle.key(); + String normal = actionToggle.normal(); + String selected = actionToggle.selected(); +// System.out.println("ActionManager.pa1rseActions() FOUND: "+key); + + String labelNormal = ResourcesUtil.getString(key+"."+normal+".label"); + String tooltipNormal = ResourcesUtil.getString(key+"."+normal+".tooltip"); + Icon iconNormal = ResourcesUtil.getIcon(key+"."+normal+".icon"); + + String labelSelected = ResourcesUtil.getString(key+"."+selected+".label"); + final String tooltipSelected = ResourcesUtil.getString(key+"."+selected+".tooltip"); + final Icon iconSelected = ResourcesUtil.getIcon(key+"."+selected+".icon"); + + map.put(key, new ViewAction(labelNormal, iconNormal, tooltipNormal) { + { + putValue(SMALL_ICON + SELECTED_KEY, iconSelected); + putValue(SHORT_DESCRIPTION + SELECTED_KEY, tooltipSelected); + } + @Override + public void actionPerformed(ActionEvent e) { + try { + m.invoke(o, isSelected()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + }); + } + } + } + public void invoke(String string) { + get(string).actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, string)); + } + + public ViewAction get(String string) { + return (ViewAction) map.get(string); + } + + public boolean contains(String string) { + return map.get(string) != null; + } + +} diff --git a/src/eu/engys/core/presentation/ActionToggle.java b/src/eu/engys/core/presentation/ActionToggle.java new file mode 100644 index 0000000..786b8ab --- /dev/null +++ b/src/eu/engys/core/presentation/ActionToggle.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.presentation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import com.google.inject.BindingAnnotation; + +@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME) +public @interface ActionToggle { + String key(); + String normal(); + String selected(); +} diff --git a/src/eu/engys/core/project/AbstractProjectReader.java b/src/eu/engys/core/project/AbstractProjectReader.java new file mode 100644 index 0000000..b77e9ec --- /dev/null +++ b/src/eu/engys/core/project/AbstractProjectReader.java @@ -0,0 +1,59 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import java.util.ArrayList; +import java.util.List; + +import eu.engys.util.progress.ProgressMonitor; + +public abstract class AbstractProjectReader implements ProjectReader { + + protected final ProgressMonitor monitor; + protected final Model model; + + protected List readers = new ArrayList<>(); + + public AbstractProjectReader(Model model, ProgressMonitor monitor) { + this.model = model; + this.monitor = monitor; + } + + public Model getModel() { + return model; + } + + public ProgressMonitor getMonitor() { + return monitor; + } + + @Override + public void registerReader(ProjectReader reader) { + if (reader != null) + readers.add(reader); + } +} diff --git a/src/eu/engys/core/project/AbstractProjectWriter.java b/src/eu/engys/core/project/AbstractProjectWriter.java new file mode 100644 index 0000000..e4fcbdc --- /dev/null +++ b/src/eu/engys/core/project/AbstractProjectWriter.java @@ -0,0 +1,64 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.util.progress.ProgressMonitor; + +public abstract class AbstractProjectWriter implements ProjectWriter { + + protected static final Logger logger = LoggerFactory.getLogger(ProjectWriter.class); + + protected final Model model; + protected final ProgressMonitor monitor; + protected final Set modules; + + protected List writers = new ArrayList<>(); + + @Inject + public AbstractProjectWriter(Model model, Set modules, ProgressMonitor monitor) { + this.model = model; + this.modules = modules; + this.monitor = monitor; + } + + @Override + public void registerWriter(ProjectWriter writer) { + if (writer != null) + writers.add(writer); + } + +} diff --git a/src/eu/engys/core/project/CaseParameters.java b/src/eu/engys/core/project/CaseParameters.java new file mode 100644 index 0000000..5016c85 --- /dev/null +++ b/src/eu/engys/core/project/CaseParameters.java @@ -0,0 +1,73 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import java.io.File; + +public class CaseParameters { + private File baseDir; + private boolean isParallel; + private int nProcessors; + private int[] nHierarchy; + + @Override + public String toString() { + return String.format("New %s case (%s processors [%s, %s, %s] ) - ", isParallel() ? "parallel" : "serial", getnProcessors(), getnHierarchy()[0], getnHierarchy()[1], getnHierarchy()[2], getBaseDir().getAbsolutePath()); + } + + public File getBaseDir() { + return baseDir; + } + + public void setBaseDir(File baseDir) { + this.baseDir = baseDir; + } + + public boolean isParallel() { + return isParallel; + } + + public void setParallel(boolean isParallel) { + this.isParallel = isParallel; + } + + public int getnProcessors() { + return nProcessors; + } + + public void setnProcessors(int nProcessors) { + this.nProcessors = nProcessors; + } + + public int[] getnHierarchy() { + return nHierarchy; + } + + public void setnHierarchy(int[] nHierarchy) { + this.nHierarchy = nHierarchy; + } +} diff --git a/src/eu/engys/core/project/CreateCase.java b/src/eu/engys/core/project/CreateCase.java new file mode 100644 index 0000000..98544cc --- /dev/null +++ b/src/eu/engys/core/project/CreateCase.java @@ -0,0 +1,160 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +import static eu.engys.core.project.system.DecomposeParDict.HIERARCHICAL_COEFFS_KEY; +import static eu.engys.core.project.system.DecomposeParDict.NUMBER_OF_SUBDOMAINS_KEY; +import static eu.engys.core.project.system.DecomposeParDict.N_KEY; + +import java.io.File; +import java.io.FileFilter; + +import org.apache.commons.io.FileUtils; + +import eu.engys.core.controller.AbstractScriptFactory; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.project.constant.ConstantFolder; +import eu.engys.core.project.defaults.Defaults; +import eu.engys.core.project.system.SystemFolder; +import eu.engys.util.Util; +import eu.engys.util.progress.ProgressMonitor; + +public class CreateCase { + + public static final int OK = 0; + public static final int CANCEL = 1; + + private ProgressMonitor monitor; + private Defaults defaults; + + public CreateCase(Defaults defaults, ProgressMonitor monitor) { + this.defaults = defaults; + this.monitor = monitor; + } + + public openFOAMProject create(CaseParameters params) { + File baseDir = params.getBaseDir(); + boolean isParallel = params.isParallel(); + int nProcessors = params.getnProcessors(); + int[] nHierarchy = params.getnHierarchy(); + + if (baseDir.exists()) { + deleteAll(baseDir, isParallel, nProcessors); + } else { + baseDir.mkdirs(); + } + + openFOAMProject prj = isParallel ? openFOAMProject.newParallelProject(baseDir, nProcessors) : openFOAMProject.newSerialProject(baseDir); + + SystemFolder systemFolder = prj.getSystemFolder(); + try { + systemFolder.setBlockMeshDict(defaults.getDefaultBlockMeshDict()); + systemFolder.setSnappyHexMeshDict(defaults.getDefaultSnappyHexMeshDict()); + systemFolder.setControlDict(defaults.getDefaultControlDict()); + systemFolder.setFvSchemes(defaults.getDefaultFvSchemes()); + systemFolder.setFvSolution(defaults.getDefaultFvSolution()); + systemFolder.setFvOptions(defaults.getDefaultFvOptions()); + // systemFolder.setRunDict(defaults.getDefaultRunDict()); + systemFolder.setMapFieldsDict(defaults.getDefaultMapFieldsDict()); + systemFolder.setDecomposeParDict(defaults.getDefaultDecomposeParDict()); + systemFolder.setCustomNodeDict(defaults.getDefaultCustomNodeDict()); + systemFolder.getDecomposeParDict().add(NUMBER_OF_SUBDOMAINS_KEY, Integer.toString(nProcessors)); + if (systemFolder.getDecomposeParDict().found(HIERARCHICAL_COEFFS_KEY)) { + String x = Integer.toString(nHierarchy[0]); + String y = Integer.toString(nHierarchy[1]); + String z = Integer.toString(nHierarchy[2]); + // Y X Z + systemFolder.getDecomposeParDict().subDict(HIERARCHICAL_COEFFS_KEY).add(N_KEY, "(" + y + " " + x + " " + z + ")"); + } + } catch (DictionaryException e) { + e.printStackTrace(); + monitor.error(e.getMessage()); + } + + return prj; + } + + public static void deleteAll(File baseDir, boolean isParallel, int nProcessors) { + deleteFile(baseDir, ConstantFolder.CONSTANT); + deleteFile(baseDir, SystemFolder.SYSTEM); + deleteFile(baseDir, "0"); + deleteFile(baseDir, openFOAMProject.LOG); + deleteFile(baseDir, openFOAMProject.POST_PROC); + deleteFile(baseDir, openFOAMProject.HOSTFILE); + deleteFile(baseDir, openFOAMProject.MACHINEFILE); + + if (isParallel) { + for (File processorDir : baseDir.listFiles(new ProcessorDirectoryFileFilter())) { + FileUtils.deleteQuietly(processorDir); + } + } + + if (Util.isWindows()) { + deleteFile(baseDir, AbstractScriptFactory.MESH_SERIAL_BAT); + deleteFile(baseDir, AbstractScriptFactory.MESH_PARALLEL_BAT); + + deleteFile(baseDir, AbstractScriptFactory.CHECK_MESH_SERIAL_BAT); + deleteFile(baseDir, AbstractScriptFactory.CHECK_MESH_PARALLEL_BAT); + + deleteFile(baseDir, AbstractScriptFactory.SOLVER_SERIAL_BAT); + deleteFile(baseDir, AbstractScriptFactory.SOLVER_PARALLEL_BAT); + + deleteFile(baseDir, AbstractScriptFactory.INITIALISE_FIELDS_SERIAL_BAT); + deleteFile(baseDir, AbstractScriptFactory.INITIALISE_FIELDS_PARALLEL_BAT); + + } else { + deleteFile(baseDir, AbstractScriptFactory.MESH_SERIAL_RUN); + deleteFile(baseDir, AbstractScriptFactory.MESH_PARALLEL_RUN); + + deleteFile(baseDir, AbstractScriptFactory.CHECK_MESH_SERIAL_RUN); + deleteFile(baseDir, AbstractScriptFactory.CHECK_MESH_PARALLEL_RUN); + + deleteFile(baseDir, AbstractScriptFactory.SOLVER_SERIAL_RUN); + deleteFile(baseDir, AbstractScriptFactory.SOLVER_PARALLEL_RUN); + + deleteFile(baseDir, AbstractScriptFactory.INITIALISE_FIELDS_SERIAL_RUN); + deleteFile(baseDir, AbstractScriptFactory.INITIALISE_FIELDS_PARALLEL_RUN); + + } + + } + + private static void deleteFile(File baseDir, String name) { + File file = new File(baseDir, name); + if (file.exists()) + FileUtils.deleteQuietly(file); + } + + private static class ProcessorDirectoryFileFilter implements FileFilter { + + @Override + public boolean accept(File pathname) { + boolean isDir = pathname.isDirectory(); + boolean isProcessor = pathname.getName().startsWith("processor"); + return isDir && isProcessor; + } + } +} diff --git a/src/eu/engys/core/project/DefaultProjectReader.java b/src/eu/engys/core/project/DefaultProjectReader.java new file mode 100644 index 0000000..e7b5d24 --- /dev/null +++ b/src/eu/engys/core/project/DefaultProjectReader.java @@ -0,0 +1,159 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +import java.io.File; +import java.util.Set; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.project.geometry.factory.DefaultGeometryFactory; +import eu.engys.core.project.materials.MaterialsReader; +import eu.engys.core.project.state.StateBuilder; +import eu.engys.core.project.state.Table15; +import eu.engys.core.project.system.ControlDict; +import eu.engys.core.project.system.fieldmanipulationfunctionobjects.FieldManipulationFunctionObjectType; +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObjectType; +import eu.engys.core.project.zero.cellzones.CellZonesBuilder; +import eu.engys.core.project.zero.fields.Initialisations; +import eu.engys.util.progress.ProgressMonitor; + +public class DefaultProjectReader extends AbstractProjectReader { + + private static final Logger logger = LoggerFactory.getLogger(ProjectReader.class); + private Set modules; + private Set ffoTypes; + private Set mfoTypes; + private final Initialisations initialisation; + private MaterialsReader materialsReader; + private Table15 solversTable; + private CellZonesBuilder cellZoneBuilder; + + @Inject + public DefaultProjectReader(Model model, Table15 solversTable, MaterialsReader materialsReader, CellZonesBuilder cellZoneBuilder, Set modules, Set ffoTypes, Set mfoTypes, Initialisations initialisation, ProgressMonitor monitor) { + super(model, monitor); + this.solversTable = solversTable; + this.materialsReader = materialsReader; + this.cellZoneBuilder = cellZoneBuilder; + this.modules = modules; + this.initialisation = initialisation; + this.ffoTypes = ffoTypes; + this.mfoTypes = mfoTypes; + } + + @Override + public void read() throws InvalidProjectException { + File baseDir = model.getProject().getBaseDir(); + logger.info("################## Read '{}' ################## ", baseDir.getName()); + if (baseDir.exists() && baseDir.isDirectory()) { + defaultRead(); + for (ProjectReader reader : readers) { + reader.read(); + } + DefaultGeometryFactory.clearSTLCache(); + } else { + monitor.error(baseDir + " not found"); + } + logger.info("################## End Read ################## "); + } + + @Override + public void readMesh() { + File baseDir = model.getProject().getBaseDir(); + if (baseDir.exists() && baseDir.isDirectory()) { + openFOAMProject prj = model.getProject(); + ControlDict controlDict = prj.getSystemFolder().getControlDict(); + if (controlDict != null) { + if (controlDict.isBinary()) { + monitor.error("Binary fields format not supported"); + } else { + logger.info("### Read mesh: '{}' ### ", prj.getZeroFolder().getFileManager().getFile()); + prj.getZeroFolder().read(model, cellZoneBuilder, modules, initialisation, monitor); + } + } + + if (!model.getPatches().isEmpty()) { + model.getGeometry().hideSurfaces(); + } + } else { + monitor.error(baseDir + " not found"); + } + } + + protected void defaultRead() throws InvalidProjectException { + monitor.info(""); + monitor.info("Reading Project"); + openFOAMProject project = model.getProject(); + + monitor.info("-> Reading Constant Folder"); + project.getConstantFolder().load(model, monitor); + + monitor.info("-> Reading System Folder"); + project.getSystemFolder().read(model, ffoTypes, mfoTypes, monitor); + + new SolverModelReader(model).load(); + + monitor.info("-> Reading Geometry"); + model.getGeometry().loadGeometry(model, monitor); + + monitor.info("-> Reading State"); + StateBuilder.loadState(model, solversTable, monitor); + solversTable.updateSolver(model.getState()); + + /* + * Call updateSolver after loadState because some module may need some other module state in order to select the correct solver (e.g. Dynamic and VOF) + */ + monitor.info("-> Reading Modules State"); + ModulesUtil.loadState(modules); + ModulesUtil.updateSolver(modules, model.getState()); + + monitor.info("-> Reading Materials"); + model.getMaterials().loadMaterials(model, materialsReader, monitor); + ModulesUtil.loadMaterials(modules); + + monitor.info("-> Reading Zero Folder"); + ControlDict controlDict = project.getSystemFolder().getControlDict(); + if (controlDict != null) { + if (controlDict.isBinary()) { + monitor.error("Binary fields format not supported", 1); + } else { + project.getZeroFolder().read(model, cellZoneBuilder, modules, initialisation, monitor); + } + } else { + monitor.error("No control dict found", 1); + } + + if (!model.getPatches().isEmpty()) { + model.getGeometry().hideSurfaces(); + } + } + +} diff --git a/src/eu/engys/core/project/DefaultProjectWriter.java b/src/eu/engys/core/project/DefaultProjectWriter.java new file mode 100644 index 0000000..ba1202d --- /dev/null +++ b/src/eu/engys/core/project/DefaultProjectWriter.java @@ -0,0 +1,182 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.Set; + +import javax.inject.Inject; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.materials.MaterialsWriter; +import eu.engys.core.project.zero.cellzones.CellZonesBuilder; +import eu.engys.core.project.zero.fields.Initialisations; +import eu.engys.util.progress.ProgressMonitor; + +public class DefaultProjectWriter extends AbstractProjectWriter { + + protected static final Logger logger = LoggerFactory.getLogger(ProjectWriter.class); + private MaterialsWriter materialsWriter; + private Initialisations initialisations; + private CellZonesBuilder cellZoneBuilder; + + @Inject + public DefaultProjectWriter(Model model, MaterialsWriter materialsWriter, CellZonesBuilder cellZoneBuilder, Set modules, Initialisations initialisations, ProgressMonitor monitor) { + super(model, modules, monitor); + this.materialsWriter = materialsWriter; + this.cellZoneBuilder = cellZoneBuilder; + this.initialisations = initialisations; + } + + @Override + public void create(CaseParameters params) { + openFOAMProject project = new CreateCase(model.getDefaults(), monitor).create(params); + model.setProject(project); + if (params.isParallel()) { + model.getFields().newParallelFields(project.getProcessors()); + model.getPatches().newParallelPatches(project.getProcessors()); + } + + write(project.getBaseDir()); + for (ProjectWriter writer : writers) { + writer.create(params); + } + } + + @Override + public void write(File baseDir) { + logger.info("################## Write '{}' ################## ", baseDir.getName()); + monitor.info(""); + monitor.info("Saving Project"); + if (!baseDir.exists()) { + baseDir.mkdirs(); + } + + openFOAMProject oldProject = model.getProject(); + boolean isSaveAs = !baseDir.getAbsoluteFile().equals(oldProject.getBaseDir().getAbsoluteFile()); + if (isSaveAs) { + CreateCase.deleteAll(baseDir, oldProject.isParallel(), oldProject.getProcessors()); + makeACopy(baseDir); + setNewProject(baseDir); + } + + writeFoamFile(baseDir); + + model.getGeometry().writeGeometry(model, monitor); + + model.getCustom().saveCustomDict(model); + + new SolverModelWriter(model).save(); + + openFOAMProject project = model.getProject(); + + monitor.info("-> Saving Zero Folder"); + project.getZeroFolder().write(model, cellZoneBuilder, modules, initialisations, monitor); + + monitor.info("-> Saving Constant Folder"); + project.getConstantFolder().write(model, materialsWriter, monitor); + + monitor.info("-> Saving System Folder"); + project.getSystemFolder().write(model, monitor); + + monitor.info("-> Saving Modules"); + for (ApplicationModule m : modules) { + monitor.info(m.getName(), 1); + m.write(); + } + + for (ProjectWriter writer : writers) { + writer.write(baseDir); + } + + File logFolder = new File(baseDir, "log"); + if (!logFolder.exists()) { + logFolder.mkdir(); + } + + monitor.info("-> Saving Custom"); + model.getCustom().write(model, monitor); + + logger.info("################## End Write ############################## "); + } + + private void makeACopy(File baseDir) { + File srcDir = model.getProject().getBaseDir(); + + boolean indeterminate = monitor.isIndeterminate(); + monitor.setIndeterminate(true); + + monitor.info(String.format("Copy: %s -> %s", srcDir.getName(), baseDir.getName())); + logger.info("Copy: {} -> {}", srcDir.getName(), baseDir.getName()); + + try { + FileUtils.copyDirectory(srcDir, baseDir); + } catch (IOException e) { + monitor.error("Error copying folder"); + monitor.error(e.getMessage()); + } + + if (!indeterminate) { + monitor.setIndeterminate(false); + } + + } + + private void setNewProject(File baseDir) { + openFOAMProject prj = openFOAMProject.newCopy(baseDir, model.getProject()); + model.setProject(prj); + } + + private void writeFoamFile(File baseDir) { + FilenameFilter filter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".foam"); + } + }; + File[] foamFiles = baseDir.listFiles(filter); + + if (foamFiles.length > 0) { + for (int i = 0; i < foamFiles.length; i++) { + FileUtils.deleteQuietly(foamFiles[i]); + } + } + + File foamFile = new File(baseDir, baseDir.getName() + ".foam"); + try { + foamFile.createNewFile(); + } catch (IOException e) { + } + } + +} diff --git a/src/eu/engys/core/project/InvalidProjectException.java b/src/eu/engys/core/project/InvalidProjectException.java new file mode 100644 index 0000000..1c47ca1 --- /dev/null +++ b/src/eu/engys/core/project/InvalidProjectException.java @@ -0,0 +1,34 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +public class InvalidProjectException extends RuntimeException { + + public InvalidProjectException(String message) { + super(message); + } + +} diff --git a/src/eu/engys/core/project/Model.java b/src/eu/engys/core/project/Model.java new file mode 100644 index 0000000..f777c29 --- /dev/null +++ b/src/eu/engys/core/project/Model.java @@ -0,0 +1,342 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +import java.util.Observable; + +import javax.inject.Inject; + +import eu.engys.core.modules.materials.MaterialsDatabase; +import eu.engys.core.project.custom.Custom; +import eu.engys.core.project.custom.CustomFile; +import eu.engys.core.project.defaults.Defaults; +import eu.engys.core.project.geometry.Geometry; +import eu.engys.core.project.geometry.factory.GeometryFactory; +import eu.engys.core.project.materials.Materials; +import eu.engys.core.project.mesh.Mesh; +import eu.engys.core.project.runtimefields.RuntimeFields; +import eu.engys.core.project.state.State; +import eu.engys.core.project.system.fieldmanipulationfunctionobjects.FieldManipulationFunctionObjects; +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObjects; +import eu.engys.core.project.zero.cellzones.CellZones; +import eu.engys.core.project.zero.facezones.FaceZones; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.patches.Patches; + +public class Model extends Observable { + + private State state; + private openFOAMProject project; + private Geometry geometry; + private Defaults defaults; + private MaterialsDatabase materialsDatabase; + + private Fields fields; + private RuntimeFields runtimeFields; + private Patches patches; + private CellZones cellZones; + private FaceZones faceZones; + private FieldManipulationFunctionObjects fieldManipulationFunctionObjects; + private MonitoringFunctionObjects monitoringFunctionObjects; + private Mesh mesh; + + private Materials materials; + private TurbulenceModels turbulenceModels; + private SolverModel solverModel; + private Custom custom; + + private GeometryFactory geometryFactory; + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + public openFOAMProject getProject() { + return project; + } + + public void setProject(openFOAMProject project) { + this.project = project; + } + + public Fields getFields() { + return fields; + } + + public void setFields(Fields fields) { + this.fields = fields; + } + + public RuntimeFields getRuntimeFields() { + return runtimeFields; + } + + public void setRuntimeFields(RuntimeFields runtimeFields) { + this.runtimeFields = runtimeFields; + } + + public Patches getPatches() { + return patches; + } + + public void setPatches(Patches patches) { + this.patches = patches; + } + + public CellZones getCellZones() { + return cellZones; + } + + public void setCellZones(CellZones cellZones) { + this.cellZones = cellZones; + } + + public FaceZones getFaceZones() { + return faceZones; + } + + public void setFaceZones(FaceZones faceZones) { + this.faceZones = faceZones; + } + + public Materials getMaterials() { + return materials; + } + + public void setMaterials(Materials materials) { + this.materials = materials; + } + + public Geometry getGeometry() { + return geometry; + } + + public void setGeometry(Geometry geometry) { + this.geometry = geometry; + } + + @Inject + public void setGeometryFactory(GeometryFactory geometryFactory) { + this.geometryFactory = geometryFactory; + } + + public Defaults getDefaults() { + return defaults; + } + + @Inject + public void setDefaults(Defaults defaults) { + this.defaults = defaults; + } + + public MaterialsDatabase getMaterialsDatabase() { + return materialsDatabase; + } + + @Inject + public void setMaterialsDatabase(MaterialsDatabase materialsDatabase) { + this.materialsDatabase = materialsDatabase; + } + + public FieldManipulationFunctionObjects getFieldManipulationFunctionObjects() { + return fieldManipulationFunctionObjects; + } + + public void setFieldManipulationFunctionObjects(FieldManipulationFunctionObjects fieldManipulationFunctionObjects) { + this.fieldManipulationFunctionObjects = fieldManipulationFunctionObjects; + } + + public MonitoringFunctionObjects getMonitoringFunctionObjects() { + return monitoringFunctionObjects; + } + + public void setMonitoringFunctionObjects(MonitoringFunctionObjects monitoringFunctionObjects) { + this.monitoringFunctionObjects = monitoringFunctionObjects; + } + + public TurbulenceModels getTurbulenceModels() { + return turbulenceModels; + } + + @Inject + public void setTurbulenceModels(TurbulenceModels turbulenceModels) { + this.turbulenceModels = turbulenceModels; + } + + public SolverModel getSolverModel() { + return solverModel; + } + + public void setSolverModel(SolverModel solverModel) { + this.solverModel = solverModel; + } + + public Mesh getMesh() { + return mesh; + } + + public void setMesh(Mesh mesh) { + this.mesh = mesh; + } + + public Custom getCustom() { + return custom; + } + + public void setCustom(Custom custom) { + this.custom = custom; + } + + public void init() { + setState(new State()); + setGeometry(new Geometry(geometryFactory)); + setMesh(new Mesh()); + setCellZones(new CellZones()); + setFaceZones(new FaceZones()); + setFields(new Fields()); + setRuntimeFields(new RuntimeFields()); + setPatches(new Patches()); + setFieldManipulationFunctionObjects(new FieldManipulationFunctionObjects()); + setMonitoringFunctionObjects(new MonitoringFunctionObjects()); + setMaterials(new Materials()); + setSolverModel(new SolverModel()); + setCustom(new Custom()); + + geometryChanged(); + materialsChanged(); + patchesChanged(); + cellZonesChanged(); + fieldManipulationFunctionObjectsChanged(); + monitoringFunctionObjectsChanged(); + customChanged(); + } + + public boolean hasProject() { + return project != null; + } + + public void stateChanged() { + setChanged(); + notifyObservers(state); + } + + public void patchesChanged() { + setChanged(); + notifyObservers(patches); + } + + public void fieldsChanged() { + setChanged(); + notifyObservers(fields); + } + + public void runtimeFieldsChanged() { + setChanged(); + notifyObservers(runtimeFields); + } + + public void materialsChanged() { + setChanged(); + notifyObservers(materials); + } + + public void cellZonesChanged() { + setChanged(); + notifyObservers(cellZones); + } + + public void faceZonesChanged() { + setChanged(); + notifyObservers(faceZones); + } + + public void monitoringFunctionObjectsChanged() { + setChanged(); + notifyObservers(monitoringFunctionObjects); + } + + public void fieldManipulationFunctionObjectsChanged() { + setChanged(); + notifyObservers(fieldManipulationFunctionObjects); + } + + public void projectChanged() { + setChanged(); + notifyObservers(project); + } + + public void solverChanged() { + setChanged(); + notifyObservers(state.getSolver()); + } + + public void geometryChanged() { + setChanged(); + notifyObservers(geometry); + } + + public void geometryChanged(Object obj) { + setChanged(); + notifyObservers(obj); + } + + public void blockChanged() { + setChanged(); + notifyObservers(geometry.getBlock()); + } + + // public void solverChanged() { + // setChanged(); + // notifyObservers(this); + // } + + public void customFileChanged(CustomFile file) { + setChanged(); + notifyObservers(file); + } + + public void customChanged() { + setChanged(); + notifyObservers(custom); + } + + @Deprecated + @Override + public void notifyObservers() { + super.notifyObservers(); + } + + @Deprecated + @Override + public void notifyObservers(Object arg) { + super.notifyObservers(arg); + } + +} diff --git a/src/eu/engys/core/project/NullProjectReader.java b/src/eu/engys/core/project/NullProjectReader.java new file mode 100644 index 0000000..e5653b7 --- /dev/null +++ b/src/eu/engys/core/project/NullProjectReader.java @@ -0,0 +1,47 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import javax.inject.Inject; + +import eu.engys.util.progress.ProgressMonitor; + +public class NullProjectReader extends AbstractProjectReader { + + @Inject + public NullProjectReader(Model model, ProgressMonitor monitor) { + super(model, monitor); + } + + @Override + public void read() { + } + + @Override + public void readMesh() { + } +} diff --git a/src/eu/engys/core/project/NullProjectWriter.java b/src/eu/engys/core/project/NullProjectWriter.java new file mode 100644 index 0000000..6f20943 --- /dev/null +++ b/src/eu/engys/core/project/NullProjectWriter.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import java.io.File; +import java.util.Set; + +import javax.inject.Inject; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.util.progress.ProgressMonitor; + +public class NullProjectWriter extends AbstractProjectWriter { + + @Inject + public NullProjectWriter(Model model, Set modules, ProgressMonitor monitor) { + super(model, modules, monitor); + } + + @Override + public void write(File baseDir) { + } + + @Override + public void create(CaseParameters params) { + } + +} diff --git a/src/eu/engys/core/project/Project200To210Converter.java b/src/eu/engys/core/project/Project200To210Converter.java new file mode 100644 index 0000000..9531715 --- /dev/null +++ b/src/eu/engys/core/project/Project200To210Converter.java @@ -0,0 +1,438 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +import static eu.engys.core.controller.AbstractScriptFactory.MESH_PARALLEL_BAT; +import static eu.engys.core.controller.AbstractScriptFactory.MESH_PARALLEL_RUN; +import static eu.engys.core.controller.AbstractScriptFactory.MESH_SERIAL_BAT; +import static eu.engys.core.controller.AbstractScriptFactory.MESH_SERIAL_RUN; +import static eu.engys.core.controller.AbstractScriptFactory.SOLVER_PARALLEL_BAT; +import static eu.engys.core.controller.AbstractScriptFactory.SOLVER_PARALLEL_RUN; +import static eu.engys.core.controller.AbstractScriptFactory.SOLVER_SERIAL_BAT; +import static eu.engys.core.controller.AbstractScriptFactory.SOLVER_SERIAL_RUN; +import static eu.engys.core.project.openFOAMProject.HOSTFILE; +import static eu.engys.core.project.openFOAMProject.MACHINEFILE; +import static eu.engys.core.project.system.ControlDict.CONTROL_DICT; +import static eu.engys.core.project.system.ControlDict.FUNCTIONS_KEY; +import static eu.engys.core.project.system.RunDict.HOSTFILE_PATH; +import static eu.engys.core.project.system.RunDict.LOG_FILE; +import static eu.engys.core.project.system.RunDict.RMI_PORT; +import static eu.engys.core.project.system.RunDict.RUN_DICT; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.core.dictionary.ListField; +import eu.engys.core.project.constant.ConstantFolder; +import eu.engys.core.project.constant.ThermophysicalProperties; +import eu.engys.core.project.materials.Materials200To210Converter; +import eu.engys.core.project.system.CustomNodeDict; +import eu.engys.core.project.system.SnappyHexMeshDict; +import eu.engys.core.project.system.SystemFolder; +import eu.engys.core.project.zero.cellzones.CellZones; +import eu.engys.core.project.zero.cellzones.CellZones200To210Converter; +import eu.engys.core.project.zero.cellzones.CellZonesBuilder; +import eu.engys.util.Util; +import eu.engys.util.progress.SilentMonitor; + +public class Project200To210Converter { + + private static final Logger logger = LoggerFactory.getLogger(Project200To210Converter.class); + + private final SilentMonitor monitor = new SilentMonitor(); + + public static final String POROUS_ZONES = "porousZones"; + public static final String MRF_ZONES = "MRFZones"; + + private openFOAMProject project; + private CellZonesBuilder cellZonesBuilder; + + public Project200To210Converter(openFOAMProject project, CellZonesBuilder cellZonesBuilder) { + this.project = project; + this.cellZonesBuilder = cellZonesBuilder; + } + + public void convert() { + ConstantFolder constantFolder = project.getConstantFolder(); + SystemFolder systemFolder = project.getSystemFolder(); + + convertCellZones(cellZonesBuilder, constantFolder, systemFolder); + convertThermophysicalProperties(constantFolder); + convertSnappyHexMeshDict(systemFolder); + convertRunDict(project); + convertHELYXDict(project); + convertForcesPostProcMapEntry(project); + convertMeshAndSolverScriptName(project); + moveFunctionObjectLogs(project); + } + + private void convertHELYXDict(openFOAMProject project) { + SystemFolder systemFolder = project.getSystemFolder(); + File helyxDictFile = systemFolder.getFileManager().getFile("HELYXDict"); + if (helyxDictFile.exists()) { + CustomNodeDict customDict = new CustomNodeDict(helyxDictFile); + DictionaryUtils.writeDictionary(systemFolder.getFileManager().getFile(), DictionaryUtils.header("system", customDict), monitor); + FileUtils.deleteQuietly(helyxDictFile); + } + } + + private void convertRunDict(openFOAMProject project) { + SystemFolder systemFolder = project.getSystemFolder(); + File runDictFile = systemFolder.getFileManager().getFile(RUN_DICT); + if (runDictFile.exists()) { + Dictionary runDict = DictionaryUtils.readDictionary(runDictFile, monitor); + + boolean writeNeed = false; + // BAD STRUCTURE + if (runDict.isDictionary(RUN_DICT)) { + runDict = new Dictionary(runDict.subDict(RUN_DICT)); + writeNeed = true; + } + // DELETE OLD FUNCTION OBJECTS MAP + if (runDict.found("logFileMap")) { + runDict.remove("logFileMap"); + writeNeed = true; + } + if (runDict.found("postProcFileMap")) { + runDict.remove("postProcFileMap"); + writeNeed = true; + } + // RMI PORT FIX + if (runDict.found(RMI_PORT)) { + int rmiPort = runDict.lookupInt(RMI_PORT); + if (rmiPort < 20000) { + runDict.add(RMI_PORT, String.valueOf(20001)); + writeNeed = true; + } + } + // LOG FILE NAME FIX + if (runDict.found(RMI_PORT)) { + String logName = runDict.lookup(LOG_FILE); + if (logName != null) { + File logFile = new File(logName); + if (!logName.isEmpty() && logFile.isAbsolute()) { + runDict.add(LOG_FILE, logFile.getName()); + writeNeed = true; + } + } + } + String hostfilePath = runDict.lookup(HOSTFILE_PATH); + if (hostfilePath == null || hostfilePath.isEmpty()) { + fixHostFilePath(project, runDict); + writeNeed = true; + } + if (writeNeed) { + DictionaryUtils.writeDictionary(systemFolder.getFileManager().getFile(), DictionaryUtils.header("system", runDict), monitor); + } + } + } + + private void fixHostFilePath(openFOAMProject project, Dictionary runDict) { + File baseDir = project.getBaseDir(); + if (new File(baseDir, HOSTFILE).exists()) { + runDict.add(HOSTFILE_PATH, HOSTFILE); + } else if (new File(baseDir, MACHINEFILE).exists()) { + runDict.add(HOSTFILE_PATH, MACHINEFILE); + } else if (new File(project.getSystemFolder().getFileManager().getFile(), HOSTFILE).exists()) { + runDict.add(HOSTFILE_PATH, SystemFolder.SYSTEM + "/" + HOSTFILE); + } else if (new File(project.getSystemFolder().getFileManager().getFile(), MACHINEFILE).exists()) { + runDict.add(HOSTFILE_PATH, SystemFolder.SYSTEM + "/" + MACHINEFILE); + } else { + runDict.add(HOSTFILE_PATH, HOSTFILE); + } + } + + private void convertForcesPostProcMapEntry(openFOAMProject project) { + File runDictFile = project.getSystemFolder().getFileManager().getFile(RUN_DICT); + if (runDictFile.exists()) { + Dictionary runDict = DictionaryUtils.readDictionary(runDictFile, monitor); + boolean writeNeed = false; + + if (writeNeed) { + DictionaryUtils.writeDictionary(project.getSystemFolder().getFileManager().getFile(), DictionaryUtils.header("system", runDict), monitor); + } + } + } + + private void convertMeshAndSolverScriptName(openFOAMProject project) { + File baseDir = project.getBaseDir(); + + String parallelIdentifier = Util.isWindows() ? "mpiexec -n" : "mpirun -np"; + + try { + File solverScript = new File(baseDir, Util.isWindows() ? "solver.bat" : "solver.run"); + if (solverScript.exists()) { + if (FileUtils.readFileToString(solverScript).contains(parallelIdentifier)) { + solverScript.renameTo(new File(baseDir, Util.isWindows() ? SOLVER_PARALLEL_BAT : SOLVER_PARALLEL_RUN)); + } else { + solverScript.renameTo(new File(baseDir, Util.isWindows() ? SOLVER_SERIAL_BAT : SOLVER_SERIAL_RUN)); + } + } + + File meshScript = new File(baseDir, Util.isWindows() ? "mesh.bat" : "mesh.run"); + if (meshScript.exists()) { + if (FileUtils.readFileToString(meshScript).contains(parallelIdentifier)) { + meshScript.renameTo(new File(baseDir, Util.isWindows() ? MESH_PARALLEL_BAT : MESH_PARALLEL_RUN)); + } else { + meshScript.renameTo(new File(baseDir, Util.isWindows() ? MESH_SERIAL_BAT : MESH_SERIAL_RUN)); + } + } + } catch (IOException e) { + logger.error("Could not rename script files"); + } + } + + private void moveFunctionObjectLogs(openFOAMProject project) { + setupPostProcFolder(project); + File controlDictFile = project.getSystemFolder().getFileManager().getFile(CONTROL_DICT); + if (controlDictFile.exists()) { + Dictionary controlDict = DictionaryUtils.readDictionary(controlDictFile, monitor); + boolean hasFunctionObjects = controlDict.isList(FUNCTIONS_KEY); + if (hasFunctionObjects) { + ListField fos = controlDict.getList(FUNCTIONS_KEY); + String baseDirPath = project.getBaseDir().getAbsolutePath(); + for (DefaultElement element : fos.getListElements()) { + if (element instanceof Dictionary) { + Dictionary foDict = (Dictionary) element; + if (foDict.found(Dictionary.TYPE)) { + String type = foDict.lookup(Dictionary.TYPE); + switch (type) { + case "liftDrag": + moveLiftDragFunctionObject(baseDirPath, foDict); + break; + case "volumeReport": + moveVolumeReportFunctionObject(baseDirPath, foDict); + break; + case "forces": + moveForcesFunctionObject(baseDirPath, foDict); + break; + default: + break; + } + } + + } + } + } + } + } + + private void moveLiftDragFunctionObject(String baseDirPath, Dictionary foDict) { + String foName = foDict.getName(); + File logFolder = Paths.get(baseDirPath, openFOAMProject.LOG).toFile(); + if (logFolder.exists()) { + for (File child : logFolder.listFiles()) { + String fileName = child.getName(); + if (fileName.startsWith(foName) && fileName.endsWith(".dat")) { + File postProcFolder = Paths.get(baseDirPath, openFOAMProject.POST_PROC).toFile(); + File functionObjectFolder = new File(postProcFolder, foName); + try { + FileUtils.moveFileToDirectory(child, functionObjectFolder, true); + } catch (IOException e) { + logger.error("Could not move " + child + " to " + functionObjectFolder); + } + } + } + } + } + + private void moveVolumeReportFunctionObject(String baseDirPath, Dictionary foDict) { + String foName = foDict.getName(); + File logFolder = Paths.get(baseDirPath, openFOAMProject.LOG).toFile(); + if (logFolder.exists()) { + for (File child : logFolder.listFiles()) { + String fileName = child.getName(); + if (fileName.startsWith(foName + "_volumeStatistics.")) { + File postProcFolder = Paths.get(baseDirPath, openFOAMProject.POST_PROC).toFile(); + File functionObjectFolder = new File(postProcFolder, foName); + try { + FileUtils.moveFileToDirectory(child, functionObjectFolder, true); + } catch (IOException e) { + logger.error("Could not move " + child + " to " + functionObjectFolder); + } + } + } + } + } + + private void moveForcesFunctionObject(String baseDirPath, Dictionary foDict) { + String foName = foDict.getName(); + File foFolder = Paths.get(baseDirPath, foName).toFile(); + if (foFolder.exists() && foFolder.isDirectory()) { + File postProcFolder = Paths.get(baseDirPath, openFOAMProject.POST_PROC).toFile(); + try { + FileUtils.moveDirectoryToDirectory(foFolder, postProcFolder, true); + } catch (IOException e) { + logger.error("Could not move " + foFolder + " to " + postProcFolder); + } + } + } + + private void setupPostProcFolder(openFOAMProject project) { + File postProcFolder = Paths.get(project.getBaseDir().getAbsolutePath(), openFOAMProject.POST_PROC).toFile(); + if (!postProcFolder.exists()) { + postProcFolder.mkdir(); + } + } + + private void convertSnappyHexMeshDict(SystemFolder systemFolder) { + File snappyFile = systemFolder.getFileManager().getFile(SnappyHexMeshDict.SNAPPY_DICT); + if (snappyFile.exists()) { + Dictionary snappy = DictionaryUtils.readDictionary(snappyFile, monitor); + if (snappy.isDictionary("castellatedMeshControls")) { + Dictionary castellated = snappy.subDict("castellatedMeshControls"); + Dictionary layers = snappy.subDict("addLayersControls"); + + boolean needWrite = false; + /* LOCATIONS IN MESH */ + if (castellated.isField("locationsInMesh")) { + try { + String[][] matrix = castellated.lookupMatrix("locationsInMesh"); + castellated.remove("locationsInMesh"); + castellated.add("locationInMesh", "(" + matrix[0][0] + " " + matrix[0][1] + " " + matrix[0][2] + ")"); + } catch (DictionaryException e) { + castellated.remove("locationsInMesh"); + if (!castellated.isField("locationInMesh")) { + castellated.add("locationInMesh", "(0 0 0)"); + } + } + needWrite = true; + } + + /* FEATURE LINES */ + if (castellated.isList("features")) { + for (DefaultElement el : castellated.getList("features").getListElements()) { + if (el instanceof Dictionary) { + Dictionary d = (Dictionary) el; + // System.out.println("Project200To210Converter.Project200To210Converter() "+d); + if (d.isField("level")) { + d.add("levels", "( 0.0 " + d.lookup("level") + ")"); + d.remove("level"); + needWrite = true; + } + } + } + } + + /* LAYERS OPTIONS */ + if (layers != null) { + if (!layers.found("writeVTK")) { + layers.add("writeVTK", "false"); + needWrite = true; + } + if (!layers.found("noErrors")) { + layers.add("noErrors", "false"); + needWrite = true; + } + if (!layers.found("layerRecovery")) { + layers.add("layerRecovery", "1"); + needWrite = true; + } + if (!layers.found("growZoneLayers")) { + layers.add("growZoneLayers", "false"); + needWrite = true; + } + if (!layers.found("projectGrownUp")) { + layers.add("projectGrownUp", "0.0"); + needWrite = true; + } + } + + if (needWrite) { + DictionaryUtils.writeDictionary(systemFolder.getFileManager().getFile(), DictionaryUtils.header("system", snappy), monitor); + } + } + } + } + + private void convertThermophysicalProperties(ConstantFolder constantFolder) { + File thermoPhysicalPropertiesFile = constantFolder.getFileManager().getFile(ThermophysicalProperties.THERMOPHYSICAL_PROPERTIES); + if (thermoPhysicalPropertiesFile.exists()) { + Dictionary thermophysicalPropertiesOLD = DictionaryUtils.readDictionary(thermoPhysicalPropertiesFile, monitor); + if (thermophysicalPropertiesOLD.isField("thermoType")) { + Materials200To210Converter converter = new Materials200To210Converter(); + Dictionary thermophysicalPropertiesNEW = converter.convert(thermophysicalPropertiesOLD); + DictionaryUtils.writeDictionary(constantFolder.getFileManager().getFile(), DictionaryUtils.header("constant", thermophysicalPropertiesNEW), monitor); + } + } + } + + private void convertCellZones(CellZonesBuilder cellZonesBuilder, ConstantFolder constantFolder, SystemFolder systemFolder) { + CellZones zones = new CellZones(); + + File MRFZonesFile = constantFolder.getFileManager().getFile(MRF_ZONES); + if (MRFZonesFile.exists()) { + MRFZones mrfZones = getMRFZones(DictionaryUtils.readDictionary(MRFZonesFile, monitor)); + zones.addAll(CellZones200To210Converter.loadMRFDictionary(mrfZones)); + } + File porousZonesFile = constantFolder.getFileManager().getFile(POROUS_ZONES); + if (porousZonesFile.exists()) { + PorousZones porousZones = getPorousZones(DictionaryUtils.readDictionary(porousZonesFile, monitor)); + zones.addAll(CellZones200To210Converter.loadPorousDictionary(porousZones)); + } + + cellZonesBuilder.saveMRFDictionary(zones, systemFolder.getFvOptions()); + cellZonesBuilder.savePorousDictionary(zones, systemFolder.getFvOptions()); + + DictionaryUtils.writeDictionary(systemFolder.getFileManager().getFile(), systemFolder.getFvOptions(), monitor); + } + + private PorousZones getPorousZones(Dictionary dict) { + PorousZones porousZones = new PorousZones(); + porousZones.merge(dict); + return porousZones; + } + + private MRFZones getMRFZones(Dictionary dict) { + MRFZones MRFZones = new MRFZones(); + MRFZones.merge(dict); + return MRFZones; + } + + public class PorousZones extends Dictionary { + public PorousZones() { + super(POROUS_ZONES); + setFoamFile(FoamFile.getDictionaryFoamFile(ConstantFolder.CONSTANT, POROUS_ZONES)); + } + } + + public class MRFZones extends Dictionary { + public MRFZones() { + super(MRF_ZONES); + setFoamFile(FoamFile.getDictionaryFoamFile(ConstantFolder.CONSTANT, MRF_ZONES)); + } + } +} diff --git a/src/eu/engys/core/project/ProjectFolderAnalyzer.java b/src/eu/engys/core/project/ProjectFolderAnalyzer.java new file mode 100644 index 0000000..6d03ec7 --- /dev/null +++ b/src/eu/engys/core/project/ProjectFolderAnalyzer.java @@ -0,0 +1,276 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import static eu.engys.core.project.constant.ConstantFolder.CONSTANT; +import static eu.engys.core.project.system.ControlDict.CONTROL_DICT; +import static eu.engys.core.project.system.FvSchemes.FV_SCHEMES; +import static eu.engys.core.project.system.FvSolution.FV_SOLUTION; +import static eu.engys.core.project.system.SystemFolder.SYSTEM; + +import java.awt.Window; +import java.io.File; +import java.io.FileFilter; + +import javax.swing.JOptionPane; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.Arguments; +import eu.engys.core.Arguments.CaseType; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.project.system.DecomposeParDict; +import eu.engys.core.project.system.SystemFolder; +import eu.engys.core.project.zero.ParallelZeroFileManager; +import eu.engys.core.project.zero.SerialZeroFileManager; +import eu.engys.core.project.zero.ZeroFolderStructure; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.progress.SilentMonitor; +import eu.engys.util.ui.UiUtil; + +public class ProjectFolderAnalyzer { + + private static final Logger logger = LoggerFactory.getLogger(ProjectFolderAnalyzer.class); + +// parallel parallel serial serial +// zero constant zero constant +// +// T T T T -> A +// T T T F -> A +// T T F T -> P +// T T F F -> P +// +// T F T T -> A +// T F T F -> A +// T F F T -> P +// T F F F -> P +// +// F T T T -> S +// F T T F -> S +// F T F T -> A +// F T F F -> P +// +// F F T T -> S +// F F T F -> S +// F F F T -> S +// F F F F -> N + + + private static final String PROCESSOR = "processor"; + + private final File baseDir; + + private int processors; + + private boolean parallel_constant;/* whether boudary is in 0 or in constant */ + private boolean parallel_zero;/* whether boudary is in 0 or in constant */ + + private boolean serial_constant;/* whether boudary is in 0 or in constant */ + private boolean serial_zero;/* whether boudary is in 0 or in constant */ + + private final ProgressMonitor monitor; + + public ProjectFolderAnalyzer(File baseDir, ProgressMonitor monitor) { + this.baseDir = baseDir; + this.monitor = monitor; + } + + public ProjectFolderStructure checkAll() { + checkSerialOrParallel(); + return populateStructure(); + } + + private ProjectFolderStructure populateStructure() { + ProjectFolderStructure structure = new ProjectFolderStructure(); + if (parallel_zero) { + if (serial_zero) { + logger.debug("Case is PARALLEL {} proc, mesh is BOTH on parallel_and_serial_zero folder", processors); + askToUser(structure); + } else { + logger.debug("Case is PARALLEL {} proc, mesh is ONLY on parallel_zero folder", processors); + structure.setParallel(true); + structure.setProcessors(processors); + } + } else { + if (parallel_constant) { + if (serial_zero) { + logger.debug("Case is SERIAL, mesh is BOTH on parallel_constant folder and serial_zero folder"); + structure.setParallel(false); + structure.setProcessors(-1); + } else { + if (serial_constant) { + logger.debug("Case is PARALLEL {} proc, mesh is BOTH on parallel_and_serial_constant folder", processors); + askToUser(structure); + } else { + logger.debug("Case is PARALLEL {} proc, mesh is on parallel_constant folder", processors); + structure.setParallel(true); + structure.setProcessors(processors); + } + } + } else { + if (serial_zero) { + logger.debug("Case is SERIAL, mesh is on serial_zero folder"); + structure.setParallel(false); + structure.setProcessors(-1); + } else { + if (serial_constant) { + logger.debug("Case is SERIAL, mesh is both on serial zero and constant folder"); + structure.setParallel(false); + structure.setProcessors(-1); + } else { + logger.debug("Looking into decomposeParDict"); + checkIntoDecomposePar(structure); + } + } + } + } + logger.debug(structure.toString()); + return structure; + } + + public ProjectFolderAnalyzer checkSerialOrParallel() { + if (baseDir.exists() && baseDir.isDirectory()) { + processors = findProcessorsFolders(); + if (processors > 0) { + checkParallelBoundary(); + } + + checkSerialBoundary(); + } + return this; + } + + public int findProcessorsFolders() { + File[] processorFiles = baseDir.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + return file.isDirectory() && file.getName().startsWith(PROCESSOR); + } + }); + int numberOfProcessors = -1; + for (File file : processorFiles) { + String processorIndexString = file.getName().replace(PROCESSOR, ""); + int processorIndex = Integer.parseInt(processorIndexString); + numberOfProcessors = Math.max(numberOfProcessors, processorIndex); + } + return numberOfProcessors + 1; + } + + void checkParallelBoundary() { + ParallelZeroFileManager fileManager = new ParallelZeroFileManager(baseDir, processors); + ZeroFolderStructure structure = fileManager.checkFileSystem(); + + parallel_zero = structure.isBoundaryFieldInZero(); + parallel_constant = structure.isBoundaryFieldInConstant(); + } + + void checkSerialBoundary() { + SerialZeroFileManager fileManager = new SerialZeroFileManager(baseDir); + ZeroFolderStructure structure = fileManager.checkFileSystem(); + + serial_zero = structure.isBoundaryFieldInZero(); + serial_constant = structure.isBoundaryFieldInConstant(); + } + + private void askToUser(ProjectFolderStructure checkList) { + if (Arguments.isBatch()) { + if (Arguments.caseType == CaseType.SERIAL) { + logger.debug("Is Batch, case type is SERIAL"); + checkList.setParallel(false); + checkList.setProcessors(-1); + } else if (Arguments.caseType == CaseType.PARALLEL) { + logger.debug("Is Batch, case type is PARALLEL"); + checkList.setParallel(true); + checkList.setProcessors(processors); + } else { + System.err.println("Case folder contains a serial AND a parallel case.\nPlease select which case to load: use '-serial' or '-parallel' option"); + System.exit(-1); + } + } else { + Object[] options = { "Serial", "Parallel" }; + Window parentComponent = monitor != null ? monitor.getDialog() : UiUtil.getActiveWindow(); + int answer = JOptionPane.showOptionDialog(parentComponent, "Project contains serial AND parallel case.\nPlease select which case to load", "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]); + logger.debug("Asking user"); + if (answer == 0) { + checkList.setParallel(false); + checkList.setProcessors(-1); + } else { + checkList.setParallel(true); + checkList.setProcessors(processors); + } + } + } + + void checkIntoDecomposePar(ProjectFolderStructure checkList) { + File decomposePar = new File(new File(baseDir, SystemFolder.SYSTEM), DecomposeParDict.DECOMPOSE_PAR_DICT); + if (decomposePar.exists()) { + Dictionary dPar = DictionaryUtils.readDictionary(decomposePar, new SilentMonitor()); + String nPar = dPar.lookup(DecomposeParDict.NUMBER_OF_SUBDOMAINS_KEY); + + try { + int n = Integer.parseInt(nPar); + checkList.setParallel(n > 1); + checkList.setProcessors(n); + } catch (Exception e) { + } + } + } + + public boolean isParallel_constant() { + return parallel_constant; + } + + public boolean isParallel_zero() { + return parallel_zero; + } + + public boolean isSerial_constant() { + return serial_constant; + } + + public boolean isSerial_zero() { + return serial_zero; + } + + public static boolean isSuitable(File file) { + if (file != null && file.exists() && file.isDirectory()) { + File constant = new File(file, CONSTANT); + File system = new File(file, SYSTEM); + + if (constant.exists() && constant.isDirectory() && system.exists() && system.isDirectory()) { + File controlDict = new File(system, CONTROL_DICT); + File fvSchemes = new File(system, FV_SCHEMES); + File fvSolution = new File(system, FV_SOLUTION); + return fvSchemes.exists() && controlDict.exists() && fvSolution.exists(); + } + return false; + } + return false; + } +} diff --git a/src/eu/engys/core/project/ProjectFolderStructure.java b/src/eu/engys/core/project/ProjectFolderStructure.java new file mode 100644 index 0000000..ab87db4 --- /dev/null +++ b/src/eu/engys/core/project/ProjectFolderStructure.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +public class ProjectFolderStructure { + + private boolean parallel; + private int processors; + + public boolean isParallel() { + return parallel; + } + + public void setParallel(boolean parallel) { + this.parallel = parallel; + } + + public int getProcessors() { + return processors; + } + + public void setProcessors(int processors) { + this.processors = processors; + } + + @Override + public String toString() { + return "Project Structure: " + (isParallel() ? ("parallel with " + processors + " processors") : "serial"); + } + +} diff --git a/src/eu/engys/core/project/ProjectReader.java b/src/eu/engys/core/project/ProjectReader.java new file mode 100644 index 0000000..36f4d7a --- /dev/null +++ b/src/eu/engys/core/project/ProjectReader.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +public interface ProjectReader { + + public void read() throws InvalidProjectException; + + public void readMesh(); + + public void registerReader(ProjectReader reader); +} diff --git a/src/eu/engys/core/project/ProjectWriter.java b/src/eu/engys/core/project/ProjectWriter.java new file mode 100644 index 0000000..6e8113a --- /dev/null +++ b/src/eu/engys/core/project/ProjectWriter.java @@ -0,0 +1,38 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import java.io.File; + + +public interface ProjectWriter { + + public void write(File baseDir); + public void create(CaseParameters params); + public void registerWriter(ProjectWriter writer); + +} diff --git a/src/eu/engys/core/project/SolverModel.java b/src/eu/engys/core/project/SolverModel.java new file mode 100644 index 0000000..4ae6e9c --- /dev/null +++ b/src/eu/engys/core/project/SolverModel.java @@ -0,0 +1,156 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +import static eu.engys.core.project.system.RunDict.RUN_DICT; + +import java.io.File; +import java.io.Serializable; +import java.util.Observable; + +import eu.engys.core.controller.Command; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.project.state.ServerState; +import eu.engys.util.connection.QueueParameters; +import eu.engys.util.connection.SshParameters; +import eu.engys.util.progress.SilentMonitor; + +public class SolverModel extends Observable implements Serializable { + + private String logFile = ""; + private String hostfilePath = ""; +// private int rmiPort = 20001; +// private int logPort = 21001; + private boolean multiMachine = false; + + private ServerState serverState = new ServerState(Command.NONE, SolverState.FINISHED); + + private SshParameters sshParameters = new SshParameters(); + private QueueParameters queueParameters = new QueueParameters(); + private boolean remote = false; + private boolean queue = false; + + private String serverID; + + public String getHostfilePath() { + return hostfilePath; + } + public void setHostfilePath(String hostfilePath) { + this.hostfilePath = hostfilePath; + } + + public boolean getMultiMachine() { + return multiMachine; + } + public void setMultiMachine(boolean multiMachine) { + this.multiMachine = multiMachine; + } + + public String getServerID() { + return serverID; + } + public void setServerID(String serverID) { + this.serverID = serverID; + } + + public String getLogFile() { + return logFile; + } + public void setLogFile(String logFile) { + this.logFile = logFile; + } + + public ServerState getServerState() { + return serverState; + } + + public void setServerState(ServerState serverState) { + this.serverState = serverState; + setChanged(); + notifyObservers(); + } + + public SshParameters getSshParameters() { + return sshParameters; + } + + public void setSshParameters(SshParameters sshParameters) { + this.sshParameters = sshParameters; + } + + public QueueParameters getQueueParameters() { + return queueParameters; + } + + public void setQueueParameters(QueueParameters queueParameters) { + this.queueParameters = queueParameters; + } + + public void setQueue(boolean queue) { + this.queue = queue; + } + + public boolean isQueue() { + return queue; + } + + public void setRemote(boolean remote) { + this.remote = remote; + } + + public boolean isRemote() { + return remote; + } + + private void read(Model model) { + File file = model.getProject().getSystemFolder().getFileManager().getFile(RUN_DICT); + new SolverModelReader(model).loadFromRunDict(new Dictionary(file), this); + } + + // Called from Server, so you need to load runDict from disk + public void writeState(ServerState state, Model model) { + read(model); + setServerState(state); + write(model); + } + + public void writeServerID(String serverID, Model model) { + setServerID(serverID); + write(model); + } + + private void write(Model model) { + new SolverModelWriter(model).save(); + DictionaryUtils.writeDictionary(model.getProject().getSystemFolder().getFileManager().getFile(), model.getProject().getSystemFolder().getRunDict(), new SilentMonitor()); + } + + @Override + public String toString() { + return "SolverModel [" + "state=" + serverState + ", " + "logFile=" + logFile + ", " + "serverID=" + serverID + ", " + "sshParameters=" + sshParameters + ", " + "queueParameters=" + queueParameters + "]"; + } + +} diff --git a/src/eu/engys/core/project/SolverModelReader.java b/src/eu/engys/core/project/SolverModelReader.java new file mode 100644 index 0000000..1e8eb21 --- /dev/null +++ b/src/eu/engys/core/project/SolverModelReader.java @@ -0,0 +1,230 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +import static eu.engys.util.connection.SshParameters.APPLICATION_DIR; +import static eu.engys.util.connection.SshParameters.AUTHENTICATION; +import static eu.engys.util.connection.SshParameters.HOST; +import static eu.engys.util.connection.SshParameters.OPENFOAM_DIR; +import static eu.engys.util.connection.SshParameters.PARAVIEW_DIR; +import static eu.engys.util.connection.SshParameters.PORT; +import static eu.engys.util.connection.SshParameters.REMOTE_BASEDIR; +import static eu.engys.util.connection.SshParameters.REMOTE_BASEDIR_PARENT; +import static eu.engys.util.connection.SshParameters.SSH_KEY; +import static eu.engys.util.connection.SshParameters.SSH_PWD; +import static eu.engys.util.connection.SshParameters.USER; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.BeanToDict; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.system.RunDict; +import eu.engys.util.Util; +import eu.engys.util.connection.SshParameters; +import eu.engys.util.connection.SshParameters.AuthType; + +public class SolverModelReader { + + private static final Logger logger = LoggerFactory.getLogger(SolverModelReader.class); + private Model model; + + public SolverModelReader(Model model) { + this.model = model; + } + + void load() { + RunDict runDict = model.getProject().getSystemFolder().getRunDict(); + populateSolverModel(runDict); + } + + private void populateSolverModel(Dictionary runDict) { + SolverModel solverModel = model.getSolverModel(); + if (runDict != null) { + loadFromRunDict(runDict, solverModel); + } + } + + void loadFromRunDict(Dictionary runDict, SolverModel solverModel) { + BeanToDict.dictToBean(runDict, solverModel); + SolverModelWriter.decryptPassword(solverModel.getSshParameters()); +//// readRMIPort(runDict, solverModel); +//// readLOGPort(runDict, solverModel); +// readServerID(runDict, solverModel); +// readRemote(runDict, solverModel); +// readQueue(runDict, solverModel); +// readLogFile(runDict, solverModel); +// readState(runDict, solverModel); +// readSSHParameters(runDict, solverModel); +// readQueueParameters(runDict, solverModel); +// readMultiMachine(runDict, solverModel); +// readHostfilePath(runDict, solverModel); + } + +// private void readRemote(Dictionary runDict, SolverModel solverModel) { +// if (runDict.found(REMOTE)) { +// solverModel.setRemote(Boolean.valueOf(runDict.lookup(REMOTE))); +// } +// } +// +// private void readQueue(Dictionary runDict, SolverModel solverModel) { +// if (runDict.found(QUEUE)) { +// solverModel.setQueue(Boolean.valueOf(runDict.lookup(QUEUE))); +// } +// } +// +// private void readMultiMachine(Dictionary runDict, SolverModel solverModel) { +// if (runDict.found(MULTI_MACHINE)) { +// Boolean value = Boolean.valueOf(runDict.lookup(MULTI_MACHINE)); +// solverModel.setMultiMachine(value && !Util.isWindows()); +// } +// } +// +// private void readHostfilePath(Dictionary runDict, SolverModel solverModel) { +// if (runDict.found(HOSTFILE_PATH)) { +// solverModel.setHostfilePath(runDict.lookup(HOSTFILE_PATH)); +// } +// } +// +// private void readLogFile(Dictionary runDict, SolverModel solverModel) { +// if (runDict.found(LOG_FILE)) { +// solverModel.setLogFile(runDict.lookup(LOG_FILE)); +// } +// } + +// private void readRMIPort(Dictionary runDict, SolverModel solverModel) { +// if (runDict.found(RMI_PORT)) { +// solverModel.setRmiPort(runDict.lookupInt(RMI_PORT)); +// } +// } +// +// private void readLOGPort(Dictionary runDict, SolverModel solverModel) { +// if (runDict.found(LOG_PORT)) { +// solverModel.setLogPort(runDict.lookupInt(LOG_PORT)); +// } +// } + +// private void readServerID(Dictionary runDict, SolverModel solverModel) { +// if (runDict.found(SERVER_ID)) { +// solverModel.setServerID(runDict.lookup(SERVER_ID)); +// } +// } +// +// private void readState(Dictionary runDict, SolverModel solverModel) { +// Dictionary serverStateDict = runDict.found(SERVER_STATE) ? runDict.subDict(SERVER_STATE) : new Dictionary(SERVER_STATE); +// +// ServerState serverState = readServerStateFromDictionary(serverStateDict); +// solverModel.setServerState(serverState); +// } + +// public static ServerState readServerStateFromDictionary(Dictionary serverStateDict) { +// ServerState serverState = new ServerState(); +// +// if (serverStateDict.found(ServerState.COMMAND)) { +// serverState.setCommand(Command.valueOf(serverStateDict.lookup(ServerState.COMMAND))); +// } +// if (serverStateDict.found(ServerState.SOLVER_STATE)) { +// serverState.setSolverState(SolverState.valueOf(serverStateDict.lookup(ServerState.SOLVER_STATE))); +// } +// if (serverStateDict.found(ServerState.ERROR)) { +// serverState.setError(new ServerError(1, "message")); +// } +// return serverState; +// } + +// private void readSSHParameters(Dictionary runDict, SolverModel solverModel) { +// Dictionary sshParametersDict = runDict.found(SSH_PARAMETERS) ? runDict.subDict(SSH_PARAMETERS) : new Dictionary(SSH_PARAMETERS); +// +// SshParameters parameters = readSshParametersFromDictionary(sshParametersDict); +// solverModel.setSshParameters(parameters); +// } + + public static SshParameters readSshParametersFromDictionary(Dictionary sshParametersDict) { + SshParameters parameters = new SshParameters(); + if (sshParametersDict.found(USER)) { + parameters.setUser(sshParametersDict.lookup(USER)); + } + if (sshParametersDict.found(SSH_PWD)) { + parameters.setSshpwd(Util.decrypt(sshParametersDict.lookup(SSH_PWD))); + } + if (sshParametersDict.found(SSH_KEY)) { + parameters.setSshkey(sshParametersDict.lookup(SSH_KEY)); + } + if (sshParametersDict.found(HOST)) { + parameters.setHost(sshParametersDict.lookup(HOST)); + } + if (sshParametersDict.found(PORT)) { + parameters.setPort(Integer.parseInt(sshParametersDict.lookup(PORT))); + } + if (sshParametersDict.found(AUTHENTICATION)) { + parameters.setSshauth(AuthType.valueOf(sshParametersDict.lookup(AUTHENTICATION))); + } + if (sshParametersDict.found(REMOTE_BASEDIR)) { + parameters.setRemoteBaseDir(sshParametersDict.lookup(REMOTE_BASEDIR)); + } + if (sshParametersDict.found(REMOTE_BASEDIR_PARENT)) { + parameters.setRemoteBaseDirParent(sshParametersDict.lookup(REMOTE_BASEDIR_PARENT)); + } + if (sshParametersDict.found(APPLICATION_DIR)) { + parameters.setApplicationDir(sshParametersDict.lookup(APPLICATION_DIR)); + } + if (sshParametersDict.found(OPENFOAM_DIR)) { + parameters.setOpenFoamDir(sshParametersDict.lookup(OPENFOAM_DIR)); + } + if (sshParametersDict.found(PARAVIEW_DIR)) { + parameters.setParaviewDir(sshParametersDict.lookup(PARAVIEW_DIR)); + } + return parameters; + } + +// private void readQueueParameters(Dictionary runDict, SolverModel solverModel) { +// QueueParameters parameters = new QueueParameters(); +// Dictionary queueParametersDict = runDict.found(QUEUE_PARAMETERS) ? runDict.subDict(QUEUE_PARAMETERS) : new Dictionary(QUEUE_PARAMETERS); +// +// if (queueParametersDict.found(QUEUE_NODES)) { +// String nodes = queueParametersDict.lookup(QUEUE_NODES); +// parameters.setNumberOfNodes(Integer.parseInt(nodes)); +// } +// if (queueParametersDict.found(QUEUE_CPUS)) { +// String cpus = queueParametersDict.lookup(QUEUE_CPUS); +// parameters.setCpuPerNode(Integer.parseInt(cpus)); +// } +// if (queueParametersDict.found(QUEUE_TIMEOUT)) { +// String timeout = queueParametersDict.lookup(QUEUE_TIMEOUT); +// parameters.setTimeout(Integer.parseInt(timeout)); +// } +// if (queueParametersDict.found(QUEUE_FEATURE)) { +// String feature = queueParametersDict.lookup(QUEUE_FEATURE); +// parameters.setFeature(feature); +// } +// if (queueParametersDict.found(QUEUE_NAMES)) { +// String names = queueParametersDict.lookup(QUEUE_NAMES); +// parameters.setNodeNames(names); +// } +// +// solverModel.setQueueParameters(parameters); +// } +} diff --git a/src/eu/engys/core/project/SolverModelWriter.java b/src/eu/engys/core/project/SolverModelWriter.java new file mode 100644 index 0000000..10d1210 --- /dev/null +++ b/src/eu/engys/core/project/SolverModelWriter.java @@ -0,0 +1,61 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import eu.engys.core.project.system.RunDict; +import eu.engys.util.Util; +import eu.engys.util.connection.SshParameters; + +public class SolverModelWriter { + + private Model model; + + public SolverModelWriter(Model model) { + this.model = model; + } + + void save() { + SshParameters sshParameters = model.getSolverModel().getSshParameters(); + encryptPassword(sshParameters); + RunDict runDict = new RunDict(model.getSolverModel()); + model.getProject().getSystemFolder().setRunDict(runDict); + decryptPassword(sshParameters); + } + + public static void encryptPassword(SshParameters sshParameters) { + if (sshParameters != null) { + sshParameters.setSshpwd(Util.encrypt(sshParameters.getSshpwd())); + } + } + + public static void decryptPassword(SshParameters sshParameters) { + if (sshParameters != null) { + sshParameters.setSshpwd(Util.decrypt(sshParameters.getSshpwd())); + } + } + +} diff --git a/src/eu/engys/core/project/SolverState.java b/src/eu/engys/core/project/SolverState.java new file mode 100644 index 0000000..ec6ed83 --- /dev/null +++ b/src/eu/engys/core/project/SolverState.java @@ -0,0 +1,68 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +public enum SolverState { + + STARTED, RUNNING, FINISHED, MESHING, MESHED, INITIALISING, INITIALISED, ERROR; + + public boolean isStarted() { + return this == STARTED; + } + + public boolean isRunning() { + return this == RUNNING; + } + + public boolean isFinished() { + return this == FINISHED; + } + + public boolean isMeshed() { + return this == MESHED; + } + + public boolean isMeshing() { + return this == MESHING; + } + + public boolean isInitialising() { + return this == INITIALISING; + } + + public boolean isInitialised() { + return this == INITIALISED; + } + + public boolean isError() { + return this == ERROR; + } + + public boolean isDoingSomething() { + return this == STARTED || this == RUNNING || this == MESHING || this == INITIALISING; + } + +} diff --git a/src/eu/engys/core/project/TurbulenceModel.java b/src/eu/engys/core/project/TurbulenceModel.java new file mode 100644 index 0000000..501569e --- /dev/null +++ b/src/eu/engys/core/project/TurbulenceModel.java @@ -0,0 +1,125 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +public class TurbulenceModel { + + private String name; + private String description; + private boolean steady; + private boolean trans; + private boolean compressible; + private boolean incompressible; + + private TurbulenceModelType type; + + public TurbulenceModel() { + } + + public TurbulenceModel(String name) { + this.name = name; + } + + public TurbulenceModel(String name, String description) { + this.name = name; + this.description = description; + } + + public TurbulenceModel(String name, TurbulenceModelType type) { + this.name = name; + this.type = type; + } + + public boolean isTrans() { + return trans; + } + + public void setTrans(boolean trans) { + this.trans = trans; + } + + public boolean isIncompressible() { + return incompressible; + } + + public void setIncompressible(boolean incompressible) { + this.incompressible = incompressible; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isSteady() { + return steady; + } + + public void setSteady(boolean steady) { + this.steady = steady; + } + + public boolean isCompressible() { + return compressible; + } + + public void setCompressible(boolean compressible) { + this.compressible = compressible; + } + + public void setType(TurbulenceModelType type) { + this.type = type; + } + + public TurbulenceModelType getType() { + return type; + } + + @Override + public String toString() { + return getName(); + } + + public boolean equals(Object obj) { + if (obj instanceof TurbulenceModel) { + TurbulenceModel tm = (TurbulenceModel) obj; + return name == null? tm.name == null : name.equals(tm.name); + } else + return super.equals(obj); + }; +} diff --git a/src/eu/engys/core/project/TurbulenceModelType.java b/src/eu/engys/core/project/TurbulenceModelType.java new file mode 100644 index 0000000..85a49b6 --- /dev/null +++ b/src/eu/engys/core/project/TurbulenceModelType.java @@ -0,0 +1,50 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project; + +public enum TurbulenceModelType { + K_Epsilon, K_Omega, Spalart_Allmaras, K_Equation_Eddy, LAMINAR; + + public boolean isSpalartAllmaras() { + return equals(Spalart_Allmaras); + } + + public boolean isKepsilon() { + return equals(K_Epsilon); + } + + public boolean isKomega() { + return equals(K_Omega); + } + + public boolean isKEquationeddy() { + return equals(K_Equation_Eddy); + } + + public boolean isLaminar() { + return equals(LAMINAR); + } +} diff --git a/src/eu/engys/core/project/TurbulenceModels.java b/src/eu/engys/core/project/TurbulenceModels.java new file mode 100644 index 0000000..e18cd31 --- /dev/null +++ b/src/eu/engys/core/project/TurbulenceModels.java @@ -0,0 +1,214 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.commons.lang.ArrayUtils; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.defaults.Defaults; +import eu.engys.core.project.state.Flow; +import eu.engys.core.project.state.Method; +import eu.engys.core.project.state.SolverType; +import eu.engys.core.project.zero.fields.Fields; + +public class TurbulenceModels { + + private final List compressibleRAS = new ArrayList<>(); + private final List incompressibleRAS = new ArrayList<>(); + private final List incompressibleLES = new ArrayList<>(); + private final List compressibleLES = new ArrayList<>(); + + private final Map> moduleModels = new HashMap<>(); + + @Inject + public TurbulenceModels(Defaults defaults) { + loadModelsFromDefaults(defaults.getDefaultTurbulenceProperties()); + } + + public Map> getModuleModels() { + return moduleModels; + } + + private void loadModelsFromDefaults(Dictionary turbulenceProperties) { + if (turbulenceProperties.isDictionary("compressibleRAS")) { + Dictionary d = turbulenceProperties.subDict("compressibleRAS"); + for (Dictionary m : d.getDictionaries()) { + compressibleRAS.add(dictToTurbulenceModel(m)); + } + } + if (turbulenceProperties.isDictionary("incompressibleRAS")) { + Dictionary d = turbulenceProperties.subDict("incompressibleRAS"); + for (Dictionary m : d.getDictionaries()) { + incompressibleRAS.add(dictToTurbulenceModel(m)); + } + } + if (turbulenceProperties.isDictionary("compressibleLES")) { + Dictionary d = turbulenceProperties.subDict("compressibleLES"); + for (Dictionary m : d.getDictionaries()) { + compressibleLES.add(dictToTurbulenceModel(m)); + } + } + if (turbulenceProperties.isDictionary("incompressibleLES")) { + Dictionary d = turbulenceProperties.subDict("incompressibleLES"); + for (Dictionary m : d.getDictionaries()) { + incompressibleLES.add(dictToTurbulenceModel(m)); + } + } + } + + public static TurbulenceModel dictToTurbulenceModel(Dictionary m) { + TurbulenceModel tm = new TurbulenceModel(); + tm.setName(nameFromDictionary(m)); + tm.setDescription(descriptionFromDictionary(m)); + tm.setType(typeFromDictionary(m)); + + return tm; + } + + private static String nameFromDictionary(Dictionary m) { + return m.getName().replace("Coeffs", ""); + } + + private static String descriptionFromDictionary(Dictionary m) { + return m.found("label") ? fromUnicode(m.lookup("label").replace("\"", "")) : m.getName(); + } + + private static TurbulenceModelType typeFromDictionary(Dictionary m) { + Dictionary fieldMaps = m.subDict("fieldMaps"); + if (fieldMaps == null) { + return TurbulenceModelType.LAMINAR; + } else if (fieldMaps.isField(Fields.K) && fieldMaps.isField(Fields.OMEGA)) { + return TurbulenceModelType.K_Omega; + } else if (fieldMaps.isField(Fields.K) && fieldMaps.isField(Fields.EPSILON)) { + return TurbulenceModelType.K_Epsilon; + } else if (fieldMaps.isField(Fields.NU_TILDA)) { + return TurbulenceModelType.Spalart_Allmaras; + } else if (fieldMaps.isField(Fields.K) && fieldMaps.isField(Fields.NU_SGS)) { + return TurbulenceModelType.K_Equation_Eddy; + } else { + return TurbulenceModelType.LAMINAR; + } + } + + public List getModelsForState(SolverType solverType, Method method, Flow flow) { + if (solverType.isCoupled()) { + if (moduleModels.containsKey("coupled")) { + return moduleModels.get("coupled"); + } else { + return Collections.emptyList(); + } + } else if (solverType.isSegregated()) { + if (flow.isCompressible()) { + if (method.isRans()) { + return compressibleRAS; + } else if (method.isLes()) { + return compressibleLES; + } else { + return Collections.emptyList(); + } + } else if (flow.isIncompressible()) { + if (method.isRans()) { + return incompressibleRAS; + } else if (method.isLes()) { + return incompressibleLES; + } else { + return Collections.emptyList(); + } + } else { + return Collections.emptyList(); + } + } else { + return Collections.emptyList(); + } + + } + + private static final char[] NUMBERS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + private static final char[] letters = { 'a', 'b', 'c', 'd', 'e', 'f' }; + private static final char[] LETTERS = { 'A', 'B', 'C', 'D', 'E', 'F' }; + private static final char U = 'u'; + private static final char BS = '\\'; + private static final char ZERO = '0'; + private static final char AL = 'a'; + private static final char AU = 'A'; + private static final char T = 't'; + private static final char R = 'r'; + private static final char N = 'n'; + private static final char F = 'f'; + private static final char TAB = '\t'; + private static final char FORM_FEED = '\f'; + private static final char RETURN = '\r'; + private static final char NEW_LINE = '\n'; + + private static String fromUnicode(String text) { + char c; + int lenght = text.length(); + StringBuffer buffer = new StringBuffer(lenght); + + for (int x = 0; x < lenght;) { + c = text.charAt(x++); + if (c == BS) { + c = text.charAt(x++); + if (c == U) { + int value = 0; + for (int i = 0; i < 4; i++) { + c = text.charAt(x++); + if (ArrayUtils.contains(NUMBERS, c)) { + value = (value << 4) + c - ZERO; + } else if (ArrayUtils.contains(letters, c)) { + value = (value << 4) + 10 + c - AL; + } else if (ArrayUtils.contains(LETTERS, c)) { + value = (value << 4) + 10 + c - AU; + } + } + buffer.append((char) value); + } else { + if (c == T) + c = TAB; + else if (c == R) + c = RETURN; + else if (c == N) + c = NEW_LINE; + else if (c == F) + c = FORM_FEED; + buffer.append(c); + } + } else + buffer.append(c); + } + return buffer.toString(); + } + +} diff --git a/src/eu/engys/core/project/constant/ConstantFolder.java b/src/eu/engys/core/project/constant/ConstantFolder.java new file mode 100644 index 0000000..a58dbd3 --- /dev/null +++ b/src/eu/engys/core/project/constant/ConstantFolder.java @@ -0,0 +1,217 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.constant; + +import java.io.File; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.files.DefaultFileManager; +import eu.engys.core.project.files.FileManager; +import eu.engys.core.project.files.Folder; +import eu.engys.core.project.materials.MaterialsWriter; +import eu.engys.core.project.state.State; +import eu.engys.util.progress.ProgressMonitor; + +public class ConstantFolder implements Folder { + + public static final String CONSTANT = "constant"; + + public static final String POLY_MESH = "polyMesh"; + public static final String TRISURFACE = "triSurface"; + public static final String G = "g"; + public static final String RADIATION_PROPERTIES = "radiationProperties"; + public static final String REGION_PROPERTIES = "regionProperties"; + public static final String LES_PROPERTIES = "LESProperties"; + public static final String RAS_PROPERTIES = "RASProperties"; + + //ECOMARINE + public static final String UFS_KEY = "Ufs"; + public static final String BEACH_KEY = "beach"; + public static final String FREE_SURFACE_PROPERTIES = "freeSurfaceProperties"; + + private final TriSurfaceFolder triSurface; + private final PolyMeshFolder polyMesh; + + private Dictionary g; + + private TurbulenceProperties turbulenceProperties; + private Dictionary RASProperties; + private Dictionary LESProperties; + private TransportProperties transportProperties; + private ThermophysicalProperties thermophysicalProperties; + + private final FileManager fileManager; + + public ConstantFolder(openFOAMProject prj) { + File constant = new File(prj.getBaseDir(), CONSTANT); + fileManager = new DefaultFileManager(constant); + triSurface = new TriSurfaceFolder(constant); + polyMesh = new PolyMeshFolder(constant); + } + + public ConstantFolder(File baseDir, ConstantFolder constantFolder) { + File constant = new File(baseDir, CONSTANT); + fileManager = new DefaultFileManager(constant); + triSurface = new TriSurfaceFolder(constant); + polyMesh = new PolyMeshFolder(constant); + + setG(constantFolder.g); + setTurbulenceProperties(constantFolder.turbulenceProperties); + setRASProperties(constantFolder.RASProperties); + setLESProperties(constantFolder.LESProperties); + setTransportProperties(constantFolder.transportProperties); + setThermophysicalProperties(constantFolder.thermophysicalProperties); + + // setPorousZones(constantFolder.porousZones); + // setMRFZones(constantFolder.MRFZones); + } + + @Override + public FileManager getFileManager() { + return fileManager; + } + + public Dictionary getG() { + return g; + } + + public void setG(Dictionary g) { + this.g = g; + } + + public TurbulenceProperties getTurbulenceProperties() { + return turbulenceProperties; + } + + public void setTurbulenceProperties(Dictionary turbulenceProperties) { + this.turbulenceProperties = new TurbulenceProperties(turbulenceProperties); + } + + public Dictionary getRASProperties() { + return RASProperties; + } + + public void setRASProperties(Dictionary rASProperties) { + RASProperties = rASProperties; + } + + public Dictionary getLESProperties() { + return LESProperties; + } + + public void setLESProperties(Dictionary lESProperties) { + LESProperties = lESProperties; + } + + public TransportProperties getTransportProperties() { + return transportProperties; + } + + public void setTransportProperties(Dictionary transportProperties) { + this.transportProperties = new TransportProperties(transportProperties); + } + + public ThermophysicalProperties getThermophysicalProperties() { + return thermophysicalProperties; + } + + public void setThermophysicalProperties(Dictionary thermophysicalProperties) { + this.thermophysicalProperties = new ThermophysicalProperties(thermophysicalProperties); + } + + public TriSurfaceFolder getTriSurface() { + return triSurface; + } + + public PolyMeshFolder getPolyMesh() { + return polyMesh; + } + + public List getAllDictionaries() { + List dictionaries = new ArrayList<>(); + dictionaries.add(getG()); + dictionaries.add(getLESProperties()); + dictionaries.add(getRASProperties()); + dictionaries.add(getThermophysicalProperties()); + dictionaries.add(getTransportProperties()); + dictionaries.add(getTurbulenceProperties()); + return dictionaries; + } + + public void write(Model model, MaterialsWriter materialsWriter, ProgressMonitor monitor) { + model.getMaterials().saveMaterials(model, materialsWriter); + + File constDir = fileManager.getFile(); + if (!constDir.exists()) + constDir.mkdir(); + + DictionaryUtils.writeDictionary(constDir, DictionaryUtils.header(CONSTANT, turbulenceProperties), monitor); + + State state = model.getState(); + if (state.isLES()) { + DictionaryUtils.writeDictionary(constDir, DictionaryUtils.header(CONSTANT, LESProperties), monitor); + DictionaryUtils.removeDictionary(constDir, DictionaryUtils.header(CONSTANT, RASProperties), monitor); + } else if (state.isRANS()) { + DictionaryUtils.writeDictionary(constDir, DictionaryUtils.header(CONSTANT, RASProperties), monitor); + DictionaryUtils.removeDictionary(constDir, DictionaryUtils.header(CONSTANT, LESProperties), monitor); + } + + if (state.isCompressible() && !state.getMultiphaseModel().isMultiphase()) { + DictionaryUtils.writeDictionary(constDir, DictionaryUtils.header(CONSTANT, thermophysicalProperties), monitor); + DictionaryUtils.removeDictionary(constDir, DictionaryUtils.header(CONSTANT, transportProperties), monitor); + } else if (state.isIncompressible() || (state.isCompressible() && state.getMultiphaseModel().isMultiphase())) { + DictionaryUtils.writeDictionary(constDir, DictionaryUtils.header(CONSTANT, transportProperties), monitor); + DictionaryUtils.removeDictionary(constDir, DictionaryUtils.header(CONSTANT, thermophysicalProperties), monitor); + } + + if (g == null && Files.exists(constDir.toPath().resolve(G))) { + DictionaryUtils.removeDictionary(constDir, DictionaryUtils.header(CONSTANT, new Dictionary(G)), monitor); + } else if (g != null && g.isEmpty()) { + DictionaryUtils.removeDictionary(constDir, DictionaryUtils.header(CONSTANT, g), monitor); + } else { + DictionaryUtils.writeDictionary(constDir, DictionaryUtils.header(CONSTANT, g), monitor); + } + + } + + public void load(Model model, ProgressMonitor monitor) { + if (fileManager.getFile().exists() && fileManager.getFile().isDirectory()) { + setTurbulenceProperties(DictionaryUtils.readDictionary(fileManager.getFile(TurbulenceProperties.TURBULENCE_PROPERTIES), monitor)); + setRASProperties(DictionaryUtils.readDictionary(fileManager.getFile(RAS_PROPERTIES), monitor)); + setLESProperties(DictionaryUtils.readDictionary(fileManager.getFile(LES_PROPERTIES), monitor)); + setThermophysicalProperties(DictionaryUtils.readDictionary(fileManager.getFile(ThermophysicalProperties.THERMOPHYSICAL_PROPERTIES), monitor)); + setTransportProperties(DictionaryUtils.readDictionary(fileManager.getFile(TransportProperties.TRANSPORT_PROPERTIES), monitor)); + setG(DictionaryUtils.readDictionary(fileManager.getFile(G), monitor)); + } + } +} diff --git a/src/eu/engys/core/project/constant/PolyMeshFolder.java b/src/eu/engys/core/project/constant/PolyMeshFolder.java new file mode 100644 index 0000000..69c9a5c --- /dev/null +++ b/src/eu/engys/core/project/constant/PolyMeshFolder.java @@ -0,0 +1,48 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.constant; + +import java.io.File; + +import eu.engys.core.project.files.DefaultFileManager; +import eu.engys.core.project.files.FileManager; +import eu.engys.core.project.files.Folder; + +public class PolyMeshFolder implements Folder { + + private FileManager fileManager; + + public PolyMeshFolder(File baseDir) { + fileManager = new DefaultFileManager(new File(baseDir, "polyMesh")); + } + + @Override + public FileManager getFileManager() { + return fileManager; + } + +} diff --git a/src/eu/engys/core/project/constant/ThermophysicalProperties.java b/src/eu/engys/core/project/constant/ThermophysicalProperties.java new file mode 100644 index 0000000..1eb7401 --- /dev/null +++ b/src/eu/engys/core/project/constant/ThermophysicalProperties.java @@ -0,0 +1,117 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.constant; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FoamFile; + +public class ThermophysicalProperties extends Dictionary { + + public static final String THERMOPHYSICAL_PROPERTIES = "thermophysicalProperties"; + + // Thermophysical Model + public static final String MATERIAL_NAME_KEY = "materialName"; + public static final String DEFAULT_MATERIAL_KEY = "defaultMaterial"; + public static final String MOL_WEIGHT_KEY = "molWeight"; + public static final String N_MOLES_KEY = "nMoles"; + + public static final String SENSIBLE_INTERNAL_ENERGY_KEY = "sensibleInternalEnergy"; + public static final String SENSIBLE_ENTHALPY_KEY = "sensibleEnthalpy"; + + + // Equation of State + public static final String EQUATION_OF_STATE_KEY = "equationOfState"; + public static final String ADIABATIC_PERFECT_FLUID_KEY = "adiabaticPerfectFluid"; + public static final String RHO_CONSTANT_KEY = "rhoConst"; + public static final String PERFECT_GAS_KEY = "perfectGas"; + public static final String PERFECT_FLUID_KEY = "perfectFluid"; + public static final String ICO_POLYNOMIAL_KEY = "icoPolynomial"; + public static final String INCOMPRESSIBLE_KEY = "incompressiblePerfectGas"; + public static final String P_REF_KEY = "pRef"; + public static final String RHO_COEFFS_KEY = "rhoCoeffs"; + public static final String R_KEY = "R"; + public static final String RHO_KEY = "rho"; + public static final String GAMMA_KEY = "gamma"; + public static final String P0_KEY = "p0"; + public static final String B_KEY = "B"; + public static final String RHO0_KEY = "rho0"; + + // Transport Properties + public static final String TS_KEY = "Ts"; + public static final String AS_KEY = "As"; + public static final String PR_KEY = "Pr"; + public static final String PRT_KEY = "Prt"; + public static final String MU_KEY = "mu"; + public static final String NU_KEY = "nu"; + public static final String TRANSPORT_KEY = "transport"; + public static final String TRANSPORT_MODEL_KEY = "transportModel"; + public static final String MIXTURE_KEY = "mixture"; + public static final String PURE_MIXTURE_KEY = "pureMixture"; + public static final String THERMODYNAMICS_KEY = "thermodynamics"; + public static final String SPECIE_KEY = "specie"; + public static final String ENERGY_KEY = "energy"; + public static final String MU_COEFFS_KEY = "muCoeffs"; + public static final String KAPPA_COEFFS_KEY = "kappaCoeffs"; + + // Thermodynamic Model + public static final String THERMO_TYPE_KEY = "thermoType"; + public static final String THERMO_MODEL_KEY = "thermoModel"; + public static final String HE_PSI_THERMO_KEY = "hePsiThermo"; + public static final String HE_RHO_THERMO_KEY = "heRhoThermo"; + public static final String LOW_CP_COEFFS_KEY = "lowCpCoeffs"; + public static final String HIGH_CP_COEFFS_KEY = "highCpCoeffs"; + public static final String CP_COEFFS_KEY = "CpCoeffs"; + public static final String TCOMMON_KEY = "Tcommon"; + public static final String THIGH_KEY = "Thigh"; + public static final String TLOW_KEY = "Tlow"; + public static final String HF_KEY = "Hf"; + public static final String SF_KEY = "Sf"; + public static final String CP_KEY = "Cp"; + public static final String T_REF_KEY = "TRef"; + public static final String BETA_OS_KEY = "beta"; + public static final String BETA_KEY = "Beta"; + public static final String LAMBDA_KEY = "lambda"; + + public static final String THERMO_KEY = "thermo"; + public static final String CONST_KEY = "const"; + public static final String POLYNOMIAL_KEY = "polynomial"; + public static final String SUTHERLAND_KEY = "sutherland"; + public static final String CONSTANT_CP_KEY = "hConst"; + public static final String JANAF_KEY = "janaf"; + public static final String H_POLYNOMIAL_KEY = "hPolynomial"; + public static final String[] A_KEYS = new String[] { "a0", "a1", "a2", "a3", "a4", "a5", "a6" }; + + public ThermophysicalProperties() { + super(THERMOPHYSICAL_PROPERTIES); + setFoamFile(FoamFile.getDictionaryFoamFile(ConstantFolder.CONSTANT, THERMOPHYSICAL_PROPERTIES)); + } + + public ThermophysicalProperties(Dictionary d) { + this(); + merge(d); + setFoamFile(FoamFile.getDictionaryFoamFile(ConstantFolder.CONSTANT, THERMOPHYSICAL_PROPERTIES)); + } +} diff --git a/src/eu/engys/core/project/constant/TransportProperties.java b/src/eu/engys/core/project/constant/TransportProperties.java new file mode 100644 index 0000000..c1da958 --- /dev/null +++ b/src/eu/engys/core/project/constant/TransportProperties.java @@ -0,0 +1,119 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.constant; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FoamFile; + +public class TransportProperties extends Dictionary { + + public static final String TRANSPORT_PROPERTIES = "transportProperties"; + + public static final String MATERIAL_NAME_KEY = "materialName"; + + public static final String NEWTONIAN_KEY = "Newtonian"; + public static final String CROSS_POWER_LAW_KEY = "CrossPowerLaw"; + public static final String BIRD_CARREAU_KEY = "BirdCarreau"; + public static final String HERSCHEL_BULKLEY_KEY = "HerschelBulkley"; + public static final String POWER_LAW_KEY = "powerLaw"; + + public static final String NEWTONIAN_COEFFS_KEY = "NewtonianCoeffs"; + public static final String CROSS_POWER_LAW_COEFFS_KEY = "CrossPowerLawCoeffs"; + public static final String BIRD_CARREAU_COEFFS_KEY = "BirdCarreauCoeffs"; + public static final String HERSCHEL_BULKLEY_COEFFS_KEY = "HerschelBulkleyCoeffs"; + public static final String POWER_LAW_COEFFS_KEY = "powerLawCoeffs"; + + public static final String SIGMAS_KEY = "sigmas"; + public static final String INTERFACE_COMPRESSION_KEY = "interfaceCompression"; + public static final String DRAG_KEY = "drag"; + public static final String VIRTUAL_MASS_KEY = "virtualMass"; + + public static final String PHASES_KEY = "phases"; + public static final String PHASE1_KEY = "phase1"; + public static final String PHASE2_KEY = "phase2"; + public static final String TRANSPORT_MODEL_KEY = "transportModel"; + public static final String SIGMA_KEY = "sigma"; + public static final String MU_KEY = "mu"; + public static final String NU_KEY = "nu"; + public static final String CP_KEY = "Cp"; + public static final String CP0_KEY = "Cp0"; + public static final String RHO_KEY = "rho"; + public static final String RHO_CP0_KEY = "rhoCp0"; + public static final String KAPPA_KEY = "kappa"; + public static final String PR_KEY = "Pr"; + public static final String PRT_KEY = "Prt"; + public static final String LAMBDA_KEY = "lambda"; + public static final String T_REF_KEY = "TRef"; + public static final String BETA_OS_KEY = "beta"; + public static final String BETA_KEY = "Beta"; + public static final String P_REF_KEY = "pRef"; + + + //Non newtonian coeffs + public static final String NU_0_KEY = "nu0"; + public static final String NU_INF_KEY = "nuInf"; + public static final String M_KEY = "m"; + public static final String N_KEY = "n"; + public static final String K_KEY = "k"; + public static final String TAU_0_KEY = "tau0"; + public static final String NU_MIN_KEY = "nuMin"; + public static final String NU_MAX_KEY = "nuMax"; + + + //Phases Euler + public static final String DIAMETER_MODEL_KEY = "diameterModel"; + public static final String CONSTANT_KEY = "constant"; + public static final String CONSTANT_COEFFS_KEY = "constantCoeffs"; + public static final String ISOTHERMAL_KEY = "isothermal"; + public static final String ISOTHERMAL_COEFFS_KEY = "isothermalCoeffs"; + public static final String P0_KEY = "p0"; + public static final String D0_KEY = "d0"; + public static final String D_KEY = "d"; + + public static final String ERGUN_KEY = "Ergun"; + public static final String GIBILARO_KEY = "Gibilaro"; + public static final String GIDASPOW_EEGUNWENYU_KEY = "GidasporEegunWenYu"; + public static final String GIDASPOW_SCHILLERNAUMANN_KEY = "GidaspowSchillerNaumann"; + public static final String SCHILLERNAUMANN_KEY = "SchillerNaumann"; + public static final String SYAMLAL_OBRIEN_KEY = "SyamlalOBrien"; + public static final String WENYU_KEY = "WenYu"; + public static final String BLENDED_KEY = "blended"; + public static final String INTERFACE_KEY = "interface"; + + public static final String RESIDUAL_PHASE_FRACTION_KEY = "residualPhaseFraction"; + public static final String RESIDUAL_SLIP_KEY = "residualSlip"; + + public TransportProperties() { + super(TRANSPORT_PROPERTIES); + setFoamFile(FoamFile.getDictionaryFoamFile(ConstantFolder.CONSTANT, TRANSPORT_PROPERTIES)); + } + + public TransportProperties(Dictionary d) { + this(); + merge(d); + setFoamFile(FoamFile.getDictionaryFoamFile(ConstantFolder.CONSTANT, TRANSPORT_PROPERTIES)); + } +} diff --git a/src/eu/engys/core/project/constant/TriSurfaceFolder.java b/src/eu/engys/core/project/constant/TriSurfaceFolder.java new file mode 100644 index 0000000..a15ad75 --- /dev/null +++ b/src/eu/engys/core/project/constant/TriSurfaceFolder.java @@ -0,0 +1,48 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.constant; + +import java.io.File; + +import eu.engys.core.project.files.DefaultFileManager; +import eu.engys.core.project.files.FileManager; +import eu.engys.core.project.files.Folder; + +public class TriSurfaceFolder implements Folder { + + public static final String TRISURFACE = "triSurface"; + private final FileManager fileManager; + + public TriSurfaceFolder(File baseDir) { + fileManager = new DefaultFileManager(new File(baseDir, TRISURFACE)); + } + + @Override + public FileManager getFileManager() { + return fileManager; + } +} diff --git a/src/eu/engys/core/project/constant/TurbulenceProperties.java b/src/eu/engys/core/project/constant/TurbulenceProperties.java new file mode 100644 index 0000000..35a74ca --- /dev/null +++ b/src/eu/engys/core/project/constant/TurbulenceProperties.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.constant; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FoamFile; + +public class TurbulenceProperties extends Dictionary { + + public static final String TURBULENCE_PROPERTIES = "turbulenceProperties"; + + public static final String SIMULATION_TYPE = "simulationType"; + public static final String RAS = "RAS"; + public static final String LES = "LES"; + public static final String LAMINAR = "laminar"; + + public static final String FIELD_MAPS_KEY = "fieldMaps"; + + public TurbulenceProperties() { + super(TURBULENCE_PROPERTIES); + setFoamFile(FoamFile.getDictionaryFoamFile(ConstantFolder.CONSTANT, TURBULENCE_PROPERTIES)); + } + + public TurbulenceProperties(Dictionary turbulenceProperties) { + this(); + merge(turbulenceProperties); + setFoamFile(FoamFile.getDictionaryFoamFile(ConstantFolder.CONSTANT, TURBULENCE_PROPERTIES)); + } +} diff --git a/src/eu/engys/core/project/custom/Custom.java b/src/eu/engys/core/project/custom/Custom.java new file mode 100644 index 0000000..71f6acf --- /dev/null +++ b/src/eu/engys/core/project/custom/Custom.java @@ -0,0 +1,225 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.custom; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.CustomNodeDict; +import eu.engys.util.progress.ProgressMonitor; + +public class Custom { + + public static final String HELYX_INTERNAL_TYPE = "helyx_type"; + + private static final Logger logger = LoggerFactory.getLogger(Custom.class); + + private final RootDirectory root = new RootDirectory(); + private final ZeroDirectory zero = new ZeroDirectory(); + private final ConstantDirectory constant = new ConstantDirectory(); + private final SystemDirectory system = new SystemDirectory(); + + private List files = new ArrayList<>(); + + public Custom() { + clear(); + add(root); + add(zero); + add(constant); + add(system); + } + + public void add(CustomFile file) { + CustomFile parent = file.getParent(); + if (parent != null) { + if (files.contains(parent) && parent.getType().isDirectory()) { + parent.add(file); + } + } + files.add(file); + } + + public void clear() { + zero.clear(); + constant.clear(); + system.clear(); + files.clear(); + } + + public void remove(CustomFile file) { + if (file.getType().isDirectory()) { + for (CustomFile child : new ArrayList(file.getChildren())) { + remove(child); + } + } + files.remove(file); + file.getParent().remove(file); + } + + public RootDirectory getRoot() { + return root; + } + + public ZeroDirectory getZero() { + return zero; + } + + public ConstantDirectory getConstant() { + return constant; + } + + public SystemDirectory getSystem() { + return system; + } + + public List getParentFiles() { + List parents = new ArrayList<>(); + for (CustomFile file : files) { + if (file != root && file.getType().isDirectory()) + parents.add(file); + } + return parents; + } + + public void read(Model model, CustomNodeDict customDict, ProgressMonitor monitor) { + if (customDict.found("system")) + readFromCustomDict(model, system, customDict.subDict("system")); + if (customDict.found("0")) + readFromCustomDict(model, zero, customDict.subDict("0")); + if (customDict.found("constant")) + readFromCustomDict(model, constant, customDict.subDict("constant")); + } + + private void readFromCustomDict(Model model, CustomFile parentFile, Dictionary dict) { + for (Dictionary d : dict.getDictionaries()) { + CustomFile customFile = null; + Dictionary copyDict = new Dictionary(d); + String type = copyDict.lookup(HELYX_INTERNAL_TYPE); + copyDict.remove(HELYX_INTERNAL_TYPE); + if (CustomFileType.DIRECTORY.getKey().equals(type)) { + customFile = new CustomFile(parentFile, CustomFileType.DIRECTORY, copyDict.getName()); + readFromCustomDict(model, customFile, copyDict); + } else if (CustomFileType.DICTIONARY.getKey().equals(type)) { + customFile = new CustomFile(parentFile, CustomFileType.DICTIONARY, copyDict.getName()); + customFile.getDictionary().merge(copyDict); + } else if (CustomFileType.FIELD.getKey().equals(type)) { + customFile = new CustomFile(parentFile, CustomFileType.FIELD, copyDict.getName()); + customFile.getDictionary().merge(copyDict); + } else if (CustomFileType.RAW.getKey().equals(type)) { + customFile = new CustomFile(parentFile, CustomFileType.RAW, copyDict.getName()); + File file = CustomUtils.getFiles(model, customFile).get(0); + customFile.getRawFileContent().clear(); + try { + customFile.getRawFileContent().addAll(FileUtils.readLines(file)); + } catch (IOException e) { + logger.error(e.getMessage()); + } + } else { + logger.error("Wrong dictionary type found: " + type); + } + if (customFile != null) { + parentFile.add(customFile); + } + } + } + + public void write(Model model, ProgressMonitor monitor) { + logger.info("--- Customise ---"); + system.write(model, monitor); + constant.write(model, monitor); + zero.write(model, monitor); + logger.info("-----------------"); + } + + public void saveCustomDict(Model model) { + CustomNodeDict customDict = new CustomNodeDict(); + saveCustomDict(root, customDict); + model.getProject().getSystemFolder().setCustomNodeDict(customDict); + } + + private void saveCustomDict(CustomFile file, Dictionary customDict) { + if (file.getType().isDirectory()) { + if (file instanceof RootDirectory) { + saveChildrenOf(file, customDict); + } else { + Dictionary subdict = new Dictionary(file.getName()); + subdict.add(HELYX_INTERNAL_TYPE, CustomFileType.DIRECTORY.getKey()); + customDict.add(subdict); + saveChildrenOf(file, subdict); + } + } else if (file.getType().isRaw()) { + Dictionary subdict = new Dictionary(file.getName()); + subdict.add(Custom.HELYX_INTERNAL_TYPE, file.getType().getKey()); + customDict.add(subdict); + } else { + Dictionary subdict = new Dictionary(file.getName(), file.getDictionary()); + subdict.add(Custom.HELYX_INTERNAL_TYPE, file.getType().getKey()); + customDict.add(subdict); + } + } + + private void saveChildrenOf(CustomFile file, Dictionary customDict) { + for (CustomFile child : file.getChildren()) { + if (child != null) { + saveCustomDict(child, customDict); + } else { + logger.error("NULL CHILD FOR: " + file.getName()); + } + } + } + + public class RootDirectory extends CustomFile { + public RootDirectory() { + super(null, CustomFileType.DIRECTORY, null); + } + } + + public class ZeroDirectory extends CustomFile { + public ZeroDirectory() { + super(root, CustomFileType.DIRECTORY, "0"); + } + } + + public class ConstantDirectory extends CustomFile { + public ConstantDirectory() { + super(root, CustomFileType.DIRECTORY, "constant"); + } + } + + public class SystemDirectory extends CustomFile { + public SystemDirectory() { + super(root, CustomFileType.DIRECTORY, "system"); + } + } +} diff --git a/src/eu/engys/core/project/custom/CustomFile.java b/src/eu/engys/core/project/custom/CustomFile.java new file mode 100644 index 0000000..60a20e0 --- /dev/null +++ b/src/eu/engys/core/project/custom/CustomFile.java @@ -0,0 +1,261 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.custom; + +import static eu.engys.core.project.system.ControlDict.CONTROL_DICT; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.JOptionPane; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.ControlDict; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.util.LineSeparator; +import eu.engys.util.Util; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.UiUtil; + +public class CustomFile { + + private static final Logger logger = LoggerFactory.getLogger(CustomFile.class); + + private final CustomFile parent; + private Dictionary dictionary; + private List rawFileContent; + private CustomFileType type = CustomFileType.DICTIONARY; + private List children = new ArrayList<>(); + + private String name; + + private boolean changed; + + public CustomFile(CustomFile parent, CustomFileType type, String name) { + this.parent = parent; + this.type = type; + this.name = name; + this.rawFileContent = new LinkedList(); + if (CONTROL_DICT.equals(name)) { + this.dictionary = new ControlDict(); + } else { + this.dictionary = new Dictionary(name); + this.dictionary.setFoamFile(getFOAMFile(parent, name)); + } + } + + private FoamFile getFOAMFile(CustomFile parent, String name) { + if (type.isField()) { + return FoamFile.getFieldFoamFile(name); + } else if (type.isDictionary()) { + return FoamFile.getDictionaryFoamFile(parent != null ? parent.getName() : "", name); + } else { + return null; + } + } + + public void add(CustomFile child) { + children.add(child); + } + + public void clear() { + children.clear(); + dictionary.clear(); + rawFileContent.clear(); + } + + public void remove(CustomFile child) { + children.remove(child); + } + + public void remove(String childName) { + CustomFile child = getChildByName(childName); + if (child != null) { + children.remove(child); + } + } + + public Dictionary getDictionary() { + return dictionary; + } + + public List getRawFileContent() { + return rawFileContent; + } + + public CustomFileType getType() { + return type; + } + + public CustomFile getParent() { + return parent; + } + + public List getChildren() { + return children; + } + + public List getChildrenNames() { + List names = new ArrayList<>(); + for (CustomFile c : getChildren()) { + names.add(c.getName()); + } + return names; + } + + public CustomFile getChildByName(String name) { + for (CustomFile c : getChildren()) { + if (c.getName().equals(name)) { + return c; + } + } + return null; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } + + public void setChanged(boolean changed) { + this.changed = changed; + } + + public boolean hasChanged(){ + return changed; + } + + public void write(Model model, ProgressMonitor monitor) { + if (getType().isDirectory()) { + writeDirectory(model, monitor); + } else if (getType().isDictionary()) { + writeDictionary(model, monitor); + } else if (getType().isField()) { + writeField(model, monitor); + } else if (getType().isRaw()) { + writeRaw(model, monitor); + } + changed = false; + } + + private void writeRaw(Model model, ProgressMonitor monitor) { + for (File f : CustomUtils.getFiles(model, this)) { + try { + if (!f.exists()) { + f.createNewFile(); + } + String lineEnding = Util.isWindowsScriptStyle() ? LineSeparator.DOS.getSeparator() : LineSeparator.UNIX.getSeparator(); + FileUtils.writeLines(f, null, rawFileContent, lineEnding); + } catch (IOException e) { + logger.error("Cannot create new raw file: " + f); + return; + } + } + } + + private void writeDictionary(Model model, ProgressMonitor monitor) { + for (File f : CustomUtils.getFiles(model, this)) { + if (f.exists()) { + Dictionary existingDictionary = null; + if (CONTROL_DICT.equals(f.getName())) { + existingDictionary = new ControlDict(f); + } else { + existingDictionary = new Dictionary(f); + } + existingDictionary.merge(dictionary); + existingDictionary.setFoamFile(dictionary.getFoamFile()); + DictionaryUtils.writeDictionary(f.getParentFile(), existingDictionary, monitor); + } else { + DictionaryUtils.writeDictionary(f.getParentFile(), dictionary, monitor); + } + } + } + + private void writeDirectory(Model model, ProgressMonitor monitor) { + if (!children.isEmpty()) { + for (File f : CustomUtils.getFiles(model, this)) { + _writeDirectory(f); + } + for (CustomFile child : getChildren()) { + if (child != null) { + child.write(model, monitor); + } else { + logger.error("CustomNodeDict is currupted " + getName() + " has a NULL child!"); + } + } + } + } + + private void _writeDirectory(File f) { + try { + f.mkdirs(); + } catch (Exception e) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "No writing permissions on " + parent, "File System error", JOptionPane.ERROR_MESSAGE); + } + } + + private void writeField(Model model, ProgressMonitor monitor) { + monitor.info(getName(), 1); + for (File f : CustomUtils.getFiles(model, this)) { + if (f.exists()) { + writeExistingField(f, monitor); + } else { + DictionaryUtils.writeDictionary(f.getParentFile(), getDictionary(), monitor); + } + } + } + + private void writeExistingField(File f, ProgressMonitor monitor) { + Dictionary existingDictionary = new Dictionary(f); + if (getDictionary().found(Field.BOUNDARY_FIELD)) { + Dictionary customBoundaryField = getDictionary().subDict(Field.BOUNDARY_FIELD); + if (existingDictionary.found(Field.BOUNDARY_FIELD)) { + Dictionary existingBoundaryField = existingDictionary.subDict(Field.BOUNDARY_FIELD); + existingBoundaryField.merge(customBoundaryField); + } else { + existingDictionary.add(customBoundaryField); + } + + } + existingDictionary.setFoamFile(getDictionary().getFoamFile()); + DictionaryUtils.writeDictionary(f.getParentFile(), existingDictionary, null); + } + +} diff --git a/src/eu/engys/core/project/custom/CustomFileType.java b/src/eu/engys/core/project/custom/CustomFileType.java new file mode 100644 index 0000000..b087a6e --- /dev/null +++ b/src/eu/engys/core/project/custom/CustomFileType.java @@ -0,0 +1,82 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.custom; + +public enum CustomFileType { + + DICTIONARY("dictionary", "Dictionary"), FIELD("field", "Field"), DIRECTORY("directory", "Directory"), RAW("raw", "Raw File"); + + private String key; + private String label; + + private CustomFileType(String key, String label) { + this.key = key; + this.label = label; + } + + public String getLabel() { + return label; + } + + public String getKey() { + return key; + } + + public boolean isDirectory() { + return key.equals(DIRECTORY.getKey()); + } + + public boolean isField() { + return key.equals(FIELD.getKey()); + } + + public boolean isDictionary() { + return key.equals(DICTIONARY.getKey()); + } + + public boolean isRaw() { + return key.equals(RAW.getKey()); + } + + public static String[] keys() { + CustomFileType[] all = values(); + String[] keys = new String[all.length]; + for (int i = 0; i < keys.length; i++) { + keys[i] = all[i].getKey(); + } + return keys; + } + + public static String[] labels() { + CustomFileType[] all = values(); + String[] labels = new String[all.length]; + for (int i = 0; i < labels.length; i++) { + labels[i] = all[i].getLabel(); + } + return labels; + } + +} diff --git a/src/eu/engys/core/project/custom/CustomUtils.java b/src/eu/engys/core/project/custom/CustomUtils.java new file mode 100644 index 0000000..d4e63b7 --- /dev/null +++ b/src/eu/engys/core/project/custom/CustomUtils.java @@ -0,0 +1,143 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.custom; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.custom.Custom.ConstantDirectory; +import eu.engys.core.project.custom.Custom.RootDirectory; +import eu.engys.core.project.custom.Custom.SystemDirectory; +import eu.engys.core.project.custom.Custom.ZeroDirectory; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.FieldReader; + +public class CustomUtils { + + private static final Logger logger = LoggerFactory.getLogger(CustomUtils.class); + + public static List getFiles(Model model, CustomFile customFile) { + openFOAMProject project = model.getProject(); + List files = new ArrayList<>(); + Path basePath = Paths.get(project.getBaseDir().getAbsolutePath()); + if (isInAVirtualPath(customFile) && project.isParallel()) { + for (int i = 0; i < project.getProcessors(); i++) { + Path initialPath = basePath.resolve("processor" + i); + files.add(getFile(model, customFile, initialPath)); + } + } else { + files.add(getFile(model, customFile, basePath)); + } + return files; + } + + private static File getFile(Model model, CustomFile customFile, Path initialPath) { + List path = new ArrayList<>(); + addParentsToList(path, customFile); + path.add(customFile.getName()); + + for (String p : path) { + initialPath = initialPath.resolve(p); + } + return initialPath.toFile(); + } + + private static void addParentsToList(List path, CustomFile file) { + CustomFile parentFile = file.getParent(); + if (parentFile instanceof RootDirectory) { + return; + } + boolean hasToStop = (parentFile instanceof ConstantDirectory) || (parentFile instanceof SystemDirectory) || (parentFile instanceof ZeroDirectory); + if (!hasToStop) { + addParentsToList(path, file.getParent()); + } + path.add(parentFile.getName()); + } + + private static boolean isInAVirtualPath(CustomFile file) { + if (file instanceof RootDirectory) { + return false; + } + if (isVirtualFolder(file)) { + return true; + } + return isInAVirtualPath(file.getParent()); + } + + public static boolean isVirtualFolder(CustomFile customFile) { + boolean isParentZeroDirectory = customFile instanceof ZeroDirectory; + boolean isParentPolyMeshOfConstantFolder = customFile.getType().isDirectory() && "polyMesh".equals(customFile.getName()) && (customFile.getParent() instanceof ConstantDirectory); + return isParentZeroDirectory || isParentPolyMeshOfConstantFolder; + } + + public static void loadFromDisk(String name, CustomFile customFile, File file) { + if (customFile.getType().isDictionary()) { + customFile.getDictionary().merge(new Dictionary(file)); + } else if (customFile.getType().isField()) { + Field field = new Field(name); + new FieldReader(field).read(file); + Dictionary dict = new Dictionary(name); + dict.add(getCleanBoundaryField(field)); + customFile.getDictionary().merge(dict); + } else if (customFile.getType().isRaw()) { + customFile.getRawFileContent().clear(); + try { + customFile.getRawFileContent().addAll(FileUtils.readLines(file)); + } catch (IOException e) { + } + } + } + + private static Dictionary getCleanBoundaryField(Field field) { + Dictionary boundaryField = field.getBoundaryField(); + List toRemoveList = new ArrayList<>(); + if (boundaryField != null) { + for (Dictionary dict : boundaryField.getDictionaries()) { + if (dict.getName().startsWith("procBoundary")) { + toRemoveList.add(dict); + } else { + dict.clear(); + } + } + } + for (Dictionary d : toRemoveList) { + boundaryField.remove(d.getName()); + } + return boundaryField; + } + +} diff --git a/src/eu/engys/core/project/defaults/AbstractDefaultsProvider.java b/src/eu/engys/core/project/defaults/AbstractDefaultsProvider.java new file mode 100644 index 0000000..5a56a81 --- /dev/null +++ b/src/eu/engys/core/project/defaults/AbstractDefaultsProvider.java @@ -0,0 +1,140 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.defaults; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.state.State; +import eu.engys.util.Util; + +public abstract class AbstractDefaultsProvider implements DefaultsProvider { + + private static final Logger logger = LoggerFactory.getLogger(AbstractDefaultsProvider.class); + + @Override + public Dictionary getDefaultsFor(State state) { + String primalState = toPrimalState(state); + if (primalState == null) { + String msg = "[ {} provider ]: No defaults for state: {}"; + logger.warn(msg, getName(), state.state2String()); + return new Dictionary(""); + } else { + logger.info("[ {} provider ]: Defaults FOUND for state: {}", getName(), state.state2String()); + } + + return mergeBase(primalState); + } + + @Override + public Dictionary getDefaultsFieldMapsFor(State state, String region) { + if (region != null) { + return getDefaultsFor(state).subDict("fieldMaps"+"."+region); + } else { + return getDefaultsFor(state).subDict("fieldMaps"); + } + + } + + /** + * + * @param stringOfState + * for example "(steady incompressible ras)" + * @return for example "simpleFoam" + */ + public String toPrimalState(State state) { + String state2String = state.state2String(); + + Dictionary statesDict = getStates(); + + // System.out.println("AbstractDefaultsProvider.toPrimalState() "+statesDict); + + if (statesDict != null) { + Map STATES = Util.invertMap(statesDict.getFieldsMap()); + + if (STATES.containsKey(state2String)) { + return STATES.get(state2String); + } else { + logger.warn("[ {} Provider ]: State '{}' NOT AVAILABLE", getName(), state2String); + return null; + } + } else { + logger.warn("[ {} Provider ]: State '{}' NOT AVAILABLE", getName(), state2String); + return null; + } + } + + private Dictionary mergeBase(String subDictID) { + Dictionary baseDict = new Dictionary(subDictID); + Dictionary stateData = getDefaultStateData(); + + if (stateData != null && stateData.found(subDictID)) { + baseDict.merge(stateData.subDict(subDictID)); + } else { + logger.warn("'" + subDictID + "' NOT FOUND"); + } + + // System.out.println("AbstractDefaultsProvider.mergeBase() "+baseDict); + + if (baseDict.found("base")) { + String baseName = baseDict.lookup("base"); + Dictionary bd = mergeBase(baseName); + bd.merge(baseDict); + return bd; + } + + return baseDict; + } + + static Dictionary extractModule(DefaultsProvider defaults, String encodedPrimalState, String moduleName) { + if (defaults.getDefaultStateData().found(moduleName)) { + Dictionary defaultModule = new Dictionary(defaults.getDefaultStateData().subDict(moduleName)); + Dictionary relativeToStateModule = extractRelativeToStateModule(encodedPrimalState, defaultModule); + if (relativeToStateModule != null) { + defaultModule.merge(relativeToStateModule); + } + return defaultModule; + } + return null; + } + + private static Dictionary extractRelativeToStateModule(String encodedPrimalState, Dictionary mDict) { + if (mDict.found("requirements")) { + Dictionary requirements = (Dictionary) mDict.remove("requirements"); + if (requirements.found("conditional")) { + if (requirements.subDict("conditional").found(encodedPrimalState)) { + Dictionary conditional = requirements.subDict("conditional").subDict(encodedPrimalState); + return conditional; + } + } + } + return null; + } + +} diff --git a/src/eu/engys/core/project/defaults/DefaultDictDataFolder.java b/src/eu/engys/core/project/defaults/DefaultDictDataFolder.java new file mode 100644 index 0000000..999c917 --- /dev/null +++ b/src/eu/engys/core/project/defaults/DefaultDictDataFolder.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.defaults; + +import java.io.File; + +import javax.inject.Inject; +import javax.inject.Named; + +import eu.engys.util.ApplicationInfo; + +public class DefaultDictDataFolder implements DictDataFolder { + + private final File dictDataFolder; + + @Inject + public DefaultDictDataFolder(@Named("Application") String applicationFolder) { + this.dictDataFolder = new File(new File(ApplicationInfo.getRootPath(), "dictData"), applicationFolder); + } + + public File getFile(String fileName) { + return new File(dictDataFolder, fileName); + } + + @Override + public File toFile() { + return dictDataFolder; + } +} diff --git a/src/eu/engys/core/project/defaults/Defaults.java b/src/eu/engys/core/project/defaults/Defaults.java new file mode 100644 index 0000000..aed40a7 --- /dev/null +++ b/src/eu/engys/core/project/defaults/Defaults.java @@ -0,0 +1,142 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.defaults; + +import javax.inject.Inject; + +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.system.BlockMeshDict; +import eu.engys.core.project.system.MapFieldsDict; +import eu.engys.core.project.system.SnappyHexMeshDict; + +public class Defaults extends AbstractDefaultsProvider { + + private DictDataFolder dictDataFolder; + private Dictionary defaultsDictionary; + + @Inject + public Defaults(DictDataFolder folder) { + this.dictDataFolder = folder; + this.defaultsDictionary = new Dictionary(folder.getFile("caseSetupDict.defaults")).subDict("defaults"); + LoggerFactory.getLogger(Defaults.class).info("-> Defaults"); + } + + @Override + public String getName() { + return "Main"; + } + + public DictDataFolder getDictDataFolder() { + return dictDataFolder; + } + + private Dictionary getDefaultsDict() { + return defaultsDictionary; + } + + @Override + public Dictionary getStates() { + return getDefaultsDict().subDict("states"); + } + + @Override + public Dictionary getDefaultStateData() { + return getDefaultsDict().subDict("stateData"); + } + + @Override + public Dictionary getDefaultFieldsData() { + return getDefaultsDict().subDict("fields"); + } + + public Dictionary getCompressibleMaterials() { + return new Dictionary(dictDataFolder.getFile("caseSetupDict.materialProperties.compressible")).subDict("materialProperties"); + } + + public Dictionary getIncompressibleMaterials() { + return new Dictionary(dictDataFolder.getFile("caseSetupDict.materialProperties.incompressible")).subDict("materialProperties"); + } + + @Override + public Dictionary getDefaultTurbulenceProperties() { + return getDefaultsDict().subDict("turbulenceProperties"); + } + + public Dictionary getDefaultFunctions() { + return getDefaultsDict().subDict("functions"); + } + + public Dictionary getDefaultSchemes() { + return getDefaultsDict().subDict("schemes"); + } + + public SnappyHexMeshDict getDefaultSnappyHexMeshDict() { + return new SnappyHexMeshDict(dictDataFolder.getFile("createCase.snappyHexMeshDict")); + } + + public BlockMeshDict getDefaultBlockMeshDict() { + return new BlockMeshDict(dictDataFolder.getFile("createCase.blockMeshDict")); + } + + public Dictionary getDefaultFvSchemes() { + return new Dictionary(dictDataFolder.getFile("createCase.fvSchemes")); + } + + public Dictionary getDefaultFvSolution() { + return new Dictionary(dictDataFolder.getFile("createCase.fvSolution")); + } + + public Dictionary getDefaultFvOptions() { + return new Dictionary(""); + } + + public Dictionary getDefaultControlDict() { + return new Dictionary(dictDataFolder.getFile("createCase.controlDict")); + } + + public Dictionary getDefaultRunDict() { + return new Dictionary(dictDataFolder.getFile("createCase.runDict")); + } + public MapFieldsDict getDefaultMapFieldsDict() { + return new MapFieldsDict(dictDataFolder.getFile("createCase.mapFieldsDict")); + } + + public Dictionary getDefaultDecomposeParDict() { + return new Dictionary(dictDataFolder.getFile("createCase.decomposeParDict")); + } + + public Dictionary getDefaultCustomNodeDict() { + return new Dictionary(dictDataFolder.getFile("createCase.customNodeDict")); + } + + public Dictionary getDefaultShapes() { + return new Dictionary(dictDataFolder.getFile("createCase.shapes")); + } + +} diff --git a/src/eu/engys/core/project/defaults/DefaultsProvider.java b/src/eu/engys/core/project/defaults/DefaultsProvider.java new file mode 100644 index 0000000..4a14a9c --- /dev/null +++ b/src/eu/engys/core/project/defaults/DefaultsProvider.java @@ -0,0 +1,48 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.defaults; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.state.State; + +public interface DefaultsProvider { + + Dictionary getDefaultTurbulenceProperties(); + + Dictionary getDefaultFieldsData(); + + Dictionary getDefaultStateData(); + + Dictionary getStates(); + + Dictionary getDefaultsFor(State state); + + Dictionary getDefaultsFieldMapsFor(State state, String region); + + String getName(); + +} diff --git a/src/eu/engys/core/project/defaults/DictDataFolder.java b/src/eu/engys/core/project/defaults/DictDataFolder.java new file mode 100644 index 0000000..70df012 --- /dev/null +++ b/src/eu/engys/core/project/defaults/DictDataFolder.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.defaults; + +import java.io.File; + +public interface DictDataFolder { + + public File getFile(String fileName); + public File toFile(); + +} diff --git a/src/eu/engys/core/project/defaults/JarDictDataFolder.java b/src/eu/engys/core/project/defaults/JarDictDataFolder.java new file mode 100644 index 0000000..e84360e --- /dev/null +++ b/src/eu/engys/core/project/defaults/JarDictDataFolder.java @@ -0,0 +1,118 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.defaults; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.ArchiveUtils; +import eu.engys.util.TempFolder; + +public class JarDictDataFolder implements DictDataFolder { + + private static final Logger logger = LoggerFactory.getLogger(JarDictDataFolder.class); + + private File dictDataFolder; + private String applicationFolder; + + @Inject + public JarDictDataFolder(@Named("Application") String applicationFolder) throws IOException { + this.applicationFolder = applicationFolder; + } + + @Override + public File toFile() { + return dictDataFolder; + } + + private String getRootPath() { + URL appJarURL = JarDictDataFolder.class.getProtectionDomain().getCodeSource().getLocation(); + File appJarFile; + try { + appJarFile = new File(appJarURL.toURI()); + } catch (URISyntaxException e) { + appJarFile = new File(appJarURL.getPath()); + } + return appJarFile.getParentFile().getParent(); + } + + public File getFile(String fileName) { + if (dictDataFolder == null) { + extractDictData(); + } + return new File(dictDataFolder, fileName); + } + + public void extractDictData() { + extractToTemp(); + } + + public void extractToTemp() { + this.dictDataFolder = TempFolder.get("dictData", applicationFolder); + if (dictDataFolder.exists()) { + FileUtils.deleteQuietly(dictDataFolder); + } + logger.info("Extract to temp"); + dictDataFolder.mkdirs(); + Path pathToLibFile = Paths.get(getRootPath(), "lib", applicationFolder+"-data.jar"); + if (Files.exists(pathToLibFile)) { + logger.info("Extract to temp: File is {}", pathToLibFile); + ArchiveUtils.unzip(pathToLibFile.toFile(), dictDataFolder.getParentFile()); + } else { + logger.info("Extract to temp: File {} not found", pathToLibFile); + Path pathToDistFile = Paths.get(getRootPath(), "dist", applicationFolder+"-data.jar"); + if (Files.exists(pathToDistFile)){ + logger.info("Extract to temp: File is {}", pathToDistFile); + ArchiveUtils.unzip(pathToDistFile.toFile(), dictDataFolder.getParentFile()); + } else { + logger.info("Extract to temp: File {} not found", pathToDistFile); + } + } + } + +// public void extractToRoot() { +// this.dictDataFolder = new File(new File(getRootPath(), "dictData"), applicationFolder); +// if (!dictDataFolder.exists()) { +// logger.warn("Extract to root"); +// dictDataFolder.mkdirs(); +// Path path = Paths.get(getRootPath(), "lib", applicationFolder+"-data.jar"); +// IOUtils.unzip(dictDataFolder.getParentFile(), path.toFile()); +// } +// } + +} diff --git a/src/eu/engys/core/project/files/DefaultFileManager.java b/src/eu/engys/core/project/files/DefaultFileManager.java new file mode 100644 index 0000000..699c5c4 --- /dev/null +++ b/src/eu/engys/core/project/files/DefaultFileManager.java @@ -0,0 +1,136 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.files; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.Util; + +public class DefaultFileManager implements FileManager { + + protected static final Logger logger = LoggerFactory.getLogger(Folder.class); + + private File file; + + public DefaultFileManager(File file) { + setFile(file); + } + + private void setFile(File file) { + this.file = file; + if (!file.exists()) { + logger.warn("-> New Folder {}", file); + file.mkdirs(); + } + } + + public File getFile() { + return file; + } + + public File getFile(String fileName) { + return new File(file, fileName); + } + + public File newFile(String fileName) { + return new File(file, fileName); + } + + public File copyHere(File source, String newName, boolean overwrite) { + String name = Util.replaceForbiddenCharacters(newName); + File target; + if (overwrite) { + target = newFile(name); + } else { + target = getACopy(name); + } + + if (target.equals(source)) + return target; + + try { + FileUtils.copyFile(source, target); + logger.info("File {} copied to {}", source, target); + } catch (IOException e) { + e.printStackTrace(); + logger.error("Error copying", e); + } + + return target; + } + + // public File moveHere(File file, boolean overwrite) { + // Path source = file.toPath(); + // Path target = file.toPath().resolve(file.getName()); + // try { + // Files.move(source, target); + // } catch (IOException e) { + // e.printStackTrace(); + // } + // + // return target.toFile(); + // } + + public void rename(String oldFileName, String newFileName) { + Path source = file.toPath().resolve(oldFileName); + try { + Files.move(source, source.resolveSibling(newFileName)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public String[] list() { + return file.list(); + } + + private File getACopy(String name) { + String finalName = name; + String finalNameNoExtension = FilenameUtils.removeExtension(finalName); + + int counter = 0; + File file; + while ((file = newFile(finalName)).exists()) { + finalName = finalNameNoExtension + (counter++) + ".stl"; + } + + return file; + } + + public void deleteAll() { + FileUtils.deleteQuietly(file); + file.mkdir(); + } +} diff --git a/src/eu/engys/core/project/files/FileManager.java b/src/eu/engys/core/project/files/FileManager.java new file mode 100644 index 0000000..457b9ee --- /dev/null +++ b/src/eu/engys/core/project/files/FileManager.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.files; + +import java.io.File; + +public interface FileManager { + public File getFile(); + + public File getFile(String fileName); + + public File newFile(String fileName); + + public File copyHere(File file, String newName, boolean overwrite); + + public void deleteAll(); + +} diff --git a/src/eu/engys/core/project/files/Folder.java b/src/eu/engys/core/project/files/Folder.java new file mode 100644 index 0000000..af9ec47 --- /dev/null +++ b/src/eu/engys/core/project/files/Folder.java @@ -0,0 +1,33 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.files; + +public interface Folder { + public FileManager getFileManager(); +} + + diff --git a/src/eu/engys/core/project/geometry/BlockReader.java b/src/eu/engys/core/project/geometry/BlockReader.java new file mode 100644 index 0000000..b12a5ed --- /dev/null +++ b/src/eu/engys/core/project/geometry/BlockReader.java @@ -0,0 +1,221 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry; + +import static eu.engys.core.project.geometry.Surface.MAX_KEY; +import static eu.engys.core.project.geometry.Surface.MIN_KEY; +import static eu.engys.core.project.system.BlockMeshDict.BLOCKS_KEY; +import static eu.engys.core.project.system.BlockMeshDict.ELEMENTS_KEY; +import static eu.engys.core.project.system.BlockMeshDict.PATCHES_KEY; +import static eu.engys.core.project.system.BlockMeshDict.VERTICES_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.ADD_LAYERS_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.LAYERS_KEY; + +import java.util.ArrayList; +import java.util.List; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.dictionary.parser.ListField2; +import eu.engys.core.project.geometry.surface.MultiPlane; +import eu.engys.core.project.geometry.surface.PlaneRegion; +import eu.engys.core.project.system.BlockMeshDict; +import eu.engys.core.project.system.SnappyHexMeshDict; + +public class BlockReader { + + private static final String DEFAULT_MAX_VALUE = "(1 1 1)"; + private static final String DEFAULT_MIN_VALUE = "(-1 -1 -1)"; + private static final String DEFAULT_ELEMENTS_VALUE = "(10 10 10)"; + private Geometry geometry; + + public BlockReader(Geometry geometry) { + this.geometry = geometry; + } + + /* + * Here the user has selected a block mesh of type: user defined. I need to load the data from blockMeshDict to visualise the block. + */ + public MultiPlane loadBlock(BlockMeshDict blockMeshDict, SnappyHexMeshDict snappyHexMeshDict) { + Dictionary blockDict = new Dictionary("block"); + MultiPlane block = null; + loadBlocksFromBlockMeshDict(blockMeshDict, blockDict); + loadVerticesFromBlockMeshDict(blockMeshDict, blockDict); + if (blockMeshDict.found(PATCHES_KEY)) { + ListField2 patches = blockMeshDict.getList2(PATCHES_KEY); + String[] patchesList = extractPatches(patches); + if (patchesList.length == 6) { + block = loadPatches(patchesList, blockDict); + } else { + block = loadDefaultPatches(); + } + } else { + block = loadDefaultPatches(); + } + block.setGeometryDictionary(blockDict); + + loadLayers(snappyHexMeshDict, block); + geometry.setBlock(block); + geometry.setCellSize(block.getDelta()); + return block; + } + + /* + * Patches + */ + + private MultiPlane loadPatches(String[] patchesList, Dictionary blockDict) { + MultiPlane block = new MultiPlane("BoundingBox"); + for (int i = 0; i < patchesList.length; i++) { + blockDict.add("patch" + i, patchesList[i]); + block.addPlane(patchesList[i]); + } + return block; + } + + private MultiPlane loadDefaultPatches() { + MultiPlane block = new MultiPlane("BoundingBox"); + block.addPlane("ffminx"); + block.addPlane("ffmaxx"); + block.addPlane("ffminy"); + block.addPlane("ffmaxy"); + block.addPlane("ffminz"); + block.addPlane("ffmaxz"); + return block; + } + + /* + * Vertices + */ + + private void loadVerticesFromBlockMeshDict(BlockMeshDict blockMeshDict, Dictionary d) { + if (blockMeshDict.found(VERTICES_KEY)) { + ListField2 vertices = blockMeshDict.getList2(VERTICES_KEY); + d.add(MIN_KEY, extractMin(vertices)); + d.add(MAX_KEY, extractMax(vertices)); + } else { + loadDefaultVertices(d); + } + } + + private void loadDefaultVertices(Dictionary d) { + d.add(MIN_KEY, DEFAULT_MIN_VALUE); + d.add(MAX_KEY, DEFAULT_MAX_VALUE); + } + + /* + * Blocks + */ + + private void loadBlocksFromBlockMeshDict(BlockMeshDict blockMeshDict, Dictionary d) { + if (blockMeshDict.found(BLOCKS_KEY)) { + ListField2 blocks = blockMeshDict.getList2(BLOCKS_KEY); + d.add(ELEMENTS_KEY, extractElements(blocks)); + } else { + loadDefaultBlocks(d); + } + } + + private void loadDefaultBlocks(Dictionary d) { + d.add(ELEMENTS_KEY, DEFAULT_ELEMENTS_VALUE); + } + + private void loadLayers(SnappyHexMeshDict snappyHexMeshDict, MultiPlane block) { + if (snappyHexMeshDict.isDictionary(ADD_LAYERS_CONTROLS_KEY) && snappyHexMeshDict.subDict(ADD_LAYERS_CONTROLS_KEY).isDictionary(LAYERS_KEY)) { + Dictionary layers = snappyHexMeshDict.subDict(ADD_LAYERS_CONTROLS_KEY).subDict(LAYERS_KEY); + for (PlaneRegion plane : block.getPlanes()) { + if (layers.isDictionary(plane.getName())) { + plane.getLayerDictionary().merge(layers.subDict(plane.getName())); + } + } + } + } + + /* + * Utils + */ + + private String extractElements(ListField2 blocks) { + if (blocks.isEmpty()) { + return DEFAULT_ELEMENTS_VALUE; + } else { + StringBuffer sb = new StringBuffer("("); + ListField2 element = (ListField2) blocks.getListElements().get(2); + FieldElement x = ((FieldElement) element.getListElements().get(0)); + FieldElement y = ((FieldElement) element.getListElements().get(1)); + FieldElement z = ((FieldElement) element.getListElements().get(2)); + sb.append(x.getValue() + " "); + sb.append(y.getValue() + " "); + sb.append(z.getValue() + " "); + sb.append(")"); + return sb.toString(); + } + } + + private String extractMin(ListField2 vertices) { + if (vertices.isEmpty()) { + return DEFAULT_MIN_VALUE; + } else { + StringBuffer sb = new StringBuffer("("); + ListField2 firstElement = (ListField2) vertices.getListElements().get(0); + FieldElement x = ((FieldElement) firstElement.getListElements().get(0)); + FieldElement y = ((FieldElement) firstElement.getListElements().get(1)); + FieldElement z = ((FieldElement) firstElement.getListElements().get(2)); + sb.append(x.getValue() + " "); + sb.append(y.getValue() + " "); + sb.append(z.getValue() + " "); + sb.append(")"); + return sb.toString(); + } + } + + private String extractMax(ListField2 vertices) { + if (vertices.isEmpty()) { + return DEFAULT_MAX_VALUE; + } else { + StringBuffer sb = new StringBuffer("("); + ListField2 firstElement = (ListField2) vertices.getListElements().get(vertices.getListElements().size() - 2); + FieldElement x = ((FieldElement) firstElement.getListElements().get(0)); + FieldElement y = ((FieldElement) firstElement.getListElements().get(1)); + FieldElement z = ((FieldElement) firstElement.getListElements().get(2)); + sb.append(x.getValue() + " "); + sb.append(y.getValue() + " "); + sb.append(z.getValue() + " "); + sb.append(")"); + return sb.toString(); + } + } + + private String[] extractPatches(ListField2 patches) { + List tokens = new ArrayList(); + for (int i = 0; i < patches.getListElements().size(); i++) { + if (i % 3 == 1) { + tokens.add(((FieldElement) patches.getListElements().get(i)).getValue()); + } + } + return tokens.toArray(new String[0]); + } +} diff --git a/src/eu/engys/core/project/geometry/BlockSaver.java b/src/eu/engys/core/project/geometry/BlockSaver.java new file mode 100644 index 0000000..c363a4a --- /dev/null +++ b/src/eu/engys/core/project/geometry/BlockSaver.java @@ -0,0 +1,169 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry; + +import static eu.engys.core.project.geometry.Surface.MAX_KEY; +import static eu.engys.core.project.geometry.Surface.MIN_KEY; +import static eu.engys.core.project.system.BlockMeshDict.BLOCKS_KEY; +import static eu.engys.core.project.system.BlockMeshDict.ELEMENTS_KEY; +import static eu.engys.core.project.system.BlockMeshDict.HEX_KEY; +import static eu.engys.core.project.system.BlockMeshDict.PATCHES_KEY; +import static eu.engys.core.project.system.BlockMeshDict.SIMPLE_GRADING_KEY; +import static eu.engys.core.project.system.BlockMeshDict.VERTICES_KEY; +import static eu.engys.core.project.system.BlockMeshDict.WALL_KEY; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.dictionary.parser.ListField2; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.surface.PlaneRegion; +import eu.engys.core.project.system.BlockMeshDict; + +public class BlockSaver { + + private Model model; + private Geometry geometry; + + public BlockSaver(Model model, Geometry geometry) { + this.model = model; + this.geometry = geometry; + } + + public void saveAutomaticBlock() { + BlockMeshDict blockMeshDict = model.getProject().getSystemFolder().getBlockMeshDict(); + if(blockMeshDict != null){ + blockMeshDict.setBoundingBox(model.getGeometry().computeBoundingBox()); + } + } + /* + * Here I take the user defined block mesh parameters from the GUI and I + * save them in blockMeshDict. If the current blockMeshDict has been + * imported from external file I need to clean its data because there can be + * stuff I cannot visualise in the GUI + */ + public void saveUserDefinedBlock(Dictionary userDefinedDictionary) { + BlockMeshDict blockMeshDict = model.getProject().getSystemFolder().getBlockMeshDict(); + if (blockMeshDict.isFromFile()) { + blockMeshDict = new BlockMeshDict(); + } + saveBlocks(blockMeshDict, userDefinedDictionary); + saveVertices(blockMeshDict, userDefinedDictionary); + savePatches(blockMeshDict); + } + + + private void saveBlocks(BlockMeshDict blockMeshDict, Dictionary userDefinedDictionary) { + ListField2 blocksList = new ListField2(BLOCKS_KEY); + + // 1 + blocksList.add(new FieldElement("", HEX_KEY)); + + // 2 + ListField2 hexList = new ListField2(""); + hexList.add("0", "1", "2", "3", "4", "5", "6", "7"); + blocksList.add(hexList); + + // 3 + ListField2 elementsList = new ListField2(""); + int[] elements = userDefinedDictionary.lookupIntArray(ELEMENTS_KEY); + for (int el : elements) { + elementsList.add(new FieldElement("", String.valueOf(el))); + } + blocksList.add(elementsList); + + // 4 + blocksList.add(new FieldElement("", SIMPLE_GRADING_KEY)); + + // 5 + ListField2 lastList = new ListField2(""); + lastList.add("1", "1", "1"); + blocksList.add(lastList); + + blockMeshDict.add(blocksList); + } + + private void savePatches(BlockMeshDict blockMeshDict) { + PlaneRegion[] regions = geometry.getBlock().getPlanes(); + + ListField2 patchesList = new ListField2(PATCHES_KEY); + + patchesList.add(WALL_KEY, regions[0].getName()); + patchesList.add(getValuesList("0", "4", "7", "3")); + + patchesList.add(WALL_KEY, regions[1].getName()); + patchesList.add(getValuesList("1", "2", "6", "5")); + + patchesList.add(WALL_KEY, regions[2].getName()); + patchesList.add(getValuesList("0", "1", "5", "4")); + + patchesList.add(WALL_KEY, regions[3].getName()); + patchesList.add(getValuesList("3", "7", "6", "2")); + + patchesList.add(WALL_KEY, regions[4].getName()); + patchesList.add(getValuesList("0", "3", "2", "1")); + + patchesList.add(WALL_KEY, regions[5].getName()); + patchesList.add(getValuesList("4", "5", "6", "7")); + + blockMeshDict.add(patchesList); + } + + private void saveVertices(BlockMeshDict blockMeshDict, Dictionary d) { + String[] min = d.lookupArray(MIN_KEY); + String[] max = d.lookupArray(MAX_KEY); + + ListField2 verticesList = new ListField2(VERTICES_KEY); + verticesList.add(getPointList(min[0], min[1], min[2])); + verticesList.add(getPointList(max[0], min[1], min[2])); + verticesList.add(getPointList(max[0], max[1], min[2])); + verticesList.add(getPointList(min[0], max[1], min[2])); + verticesList.add(getPointList(min[0], min[1], max[2])); + verticesList.add(getPointList(max[0], min[1], max[2])); + verticesList.add(getPointList(max[0], max[1], max[2])); + verticesList.add(getPointList(min[0], max[1], max[2])); + + blockMeshDict.add(verticesList); + } + + /* + * Utils + */ + + private ListField2 getValuesList(String v1, String v2, String v3, String v4) { + ListField2 valuesList = new ListField2(""); + valuesList.add(v1, v2, v3, v4); + ListField2 valuesContainerList = new ListField2(""); + valuesContainerList.add(valuesList); + return valuesContainerList; + } + + private ListField2 getPointList(String x, String y, String z) { + ListField2 list = new ListField2(""); + list.add(x, y, z); + return list; + } + +} diff --git a/src/eu/engys/core/project/geometry/BoundingBox.java b/src/eu/engys/core/project/geometry/BoundingBox.java new file mode 100644 index 0000000..df85055 --- /dev/null +++ b/src/eu/engys/core/project/geometry/BoundingBox.java @@ -0,0 +1,140 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry; + +import java.util.Arrays; + +import javax.vecmath.Point3d; + +public class BoundingBox { + + private double xmin = Double.MAX_VALUE; + private double xmax = -Double.MAX_VALUE; + private double ymin = Double.MAX_VALUE; + private double ymax = -Double.MAX_VALUE; + private double zmin = Double.MAX_VALUE; + private double zmax = -Double.MAX_VALUE; + private Point3d center = new Point3d(0, 0, 0); + + public BoundingBox() { + } + + public BoundingBox(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) { + this.xmin = xmin; + this.xmax = xmax; + this.ymin = ymin; + this.ymax = ymax; + this.zmin = zmin; + this.zmax = zmax; + } + + public double getXmin() { + return xmin; + } + + public void setXmin(double xmin) { + this.xmin = xmin; + } + + public double getXmax() { + return xmax; + } + + public void setXmax(double xmax) { + this.xmax = xmax; + } + + public double getYmin() { + return ymin; + } + + public void setYmin(double ymin) { + this.ymin = ymin; + } + + public double getYmax() { + return ymax; + } + + public void setYmax(double ymax) { + this.ymax = ymax; + } + + public double getZmin() { + return zmin; + } + + public void setZmin(double zmin) { + this.zmin = zmin; + } + + public double getZmax() { + return zmax; + } + + public void setZmax(double zmax) { + this.zmax = zmax; + } + + public double[] getCenter() { + double centerX = (xmin + xmax) / 2; + double centerY = (ymin + ymax) / 2; + double centerZ = (zmin + zmax) / 2; + return new double[]{centerX, centerY, centerZ}; + } + + public double getWidth() { + return xmax - xmin; + } + + public double getHeight() { + return ymax - ymin; + } + + public double getDepth() { + return zmax - zmin; + } + + public double getDiagonal() { + return Math.sqrt(Math.pow(xmax - xmin, 2) + Math.pow(ymax - ymin, 2) + Math.pow(zmax - zmin, 2)); + } + + @Override + public String toString() { + return "Bounding Box: xmin (" + getXmin() + "), xmax (" + getXmax() + "), ymin (" + getYmin()+ "), ymax (" + getYmax()+ "), zmin (" + getZmin()+ "), zmax (" + getZmax() + "), centre " + Arrays.toString(getCenter()); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof BoundingBox) { + BoundingBox b = (BoundingBox) obj; + return b.getWidth() == getWidth() && b.getHeight() == getHeight(); + } + return false; + } + +} diff --git a/src/eu/engys/core/project/geometry/FeatureLine.java b/src/eu/engys/core/project/geometry/FeatureLine.java new file mode 100644 index 0000000..a38c6e4 --- /dev/null +++ b/src/eu/engys/core/project/geometry/FeatureLine.java @@ -0,0 +1,178 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry; + +import static eu.engys.core.project.system.SnappyHexMeshDict.FILE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.LEVELS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.REFINE_FEATURE_EDGES_ONLY_KEY; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; + +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.geometry.surface.BaseSurface; + +public class FeatureLine extends BaseSurface { + + public static class Refinement { + + private double distance; + private int level; + + public Refinement(double distance, int level) { + this.distance = distance; + this.level = level; + } + public double getDistance() { + return distance; + } + public int getLevel() { + return level; + } + } + + private boolean refineOnly; + private List refinements; + private vtkPolyData dataSet; + private Color color; + private boolean modified; + + public FeatureLine(String name) { + super(name); + this.refineOnly = false; + this.refinements = new ArrayList<>(); + this.refinements.add(new Refinement(0.0, 0)); + this.color = Color.BLUE; + } + + public boolean isRefineOnly() { + return refineOnly; + } + public void setRefineOnly(boolean refineOnly) { + this.refineOnly = refineOnly; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public List getRefinements() { + return refinements; + } + public void setRefinements(List refinements) { + this.refinements = refinements; + } + + @Override + public Type getType() { + return Type.LINE; + } + @Override + public Surface cloneSurface() { + return new FeatureLine(getName()); + } + @Override + public vtkPolyData getDataSet() { + return dataSet; + } + public void setDataSet(vtkPolyData dataSet) { + this.dataSet = dataSet; + } + @Override + public boolean isAppendRegionName() { + return false; + } + @Override + public boolean hasSurfaceRefinement() { + return false; + } + @Override + public boolean hasVolumeRefinement() { + return false; + } + @Override + public boolean hasLayers() { + return false; + } + + public void setColor(Color color) { + this.color = color; + } + + public Color getColor() { + return color; + } + + @Override + public Dictionary toDictionary() { + Dictionary d = new Dictionary(""); + d.add(FILE_KEY, "\"" + getName() + ".eMesh" + "\""); + StringBuilder sb = new StringBuilder(); + sb.append("("); + for (Refinement r : refinements) { + sb.append("("); + sb.append(r.distance); + sb.append(" "); + sb.append(r.level); + sb.append(")"); + } + sb.append(")"); + d.add(LEVELS_KEY, sb.toString()); + d.add(REFINE_FEATURE_EDGES_ONLY_KEY, String.valueOf(refineOnly)); + return d; + } + + @Override + public void fromDictionary(Dictionary d) { + refinements.clear(); + if (d.found(LEVELS_KEY)) { + double[][] levels = d.lookupDoubleMatrix(LEVELS_KEY); + for (int i = 0; i < levels.length; i++) { + if (levels[i].length == 2) { + double distance = levels[i][0]; + int level = (int) levels[i][1]; + refinements.add(new Refinement(distance, level)); + } + } + } + if (d.found(REFINE_FEATURE_EDGES_ONLY_KEY) ) { + this.refineOnly = Boolean.parseBoolean(d.lookup(REFINE_FEATURE_EDGES_ONLY_KEY)); + } + } + + public void setModified(boolean modified) { + this.modified = modified; + } + + public boolean isModified() { + return modified; + } +} diff --git a/src/eu/engys/core/project/geometry/FeatureLines.java b/src/eu/engys/core/project/geometry/FeatureLines.java new file mode 100644 index 0000000..9a11b30 --- /dev/null +++ b/src/eu/engys/core/project/geometry/FeatureLines.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class FeatureLines implements Iterable { + + private List list = new ArrayList<>(); + + public void addLine(FeatureLine line) { + list.add(line); + } + + public void remove(FeatureLine line) { + list.remove(line); + } + + @Override + public Iterator iterator() { + return list.iterator(); + } + + public int size() { + return list.size(); + } + + public FeatureLine getLine(int index) { + return list.get(index); + } + + public FeatureLine getLine(String name) { + for (FeatureLine line : list) { + if (line.getName().equals(name)) { + return line; + } + } + return null; + } + + public FeatureLine[] toArray() { + return list.toArray(new FeatureLine[0]); + } + +} diff --git a/src/eu/engys/core/project/geometry/Geometry.java b/src/eu/engys/core/project/geometry/Geometry.java new file mode 100644 index 0000000..fdbb908 --- /dev/null +++ b/src/eu/engys/core/project/geometry/Geometry.java @@ -0,0 +1,335 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry; + +import java.util.ArrayList; +import java.util.List; + +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.factory.GeometryFactory; +import eu.engys.core.project.geometry.surface.Box; +import eu.engys.core.project.geometry.surface.Cylinder; +import eu.engys.core.project.geometry.surface.MultiPlane; +import eu.engys.core.project.geometry.surface.Plane; +import eu.engys.core.project.geometry.surface.Ring; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.core.project.geometry.surface.Sphere; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.core.project.system.BlockMeshDict; +import eu.engys.core.project.system.SnappyHexMeshDict; +import eu.engys.util.Util; +import eu.engys.util.progress.ProgressMonitor; + +public class Geometry { + + public static MultiPlane FAKE_BLOCK = new MultiPlane(""); + + private final List surfaces = new ArrayList(); + private final FeatureLines lines = new FeatureLines(); + private MultiPlane block = FAKE_BLOCK; + private GeometryFactory geometryFactory; + + private boolean autoBoundingBox = true; + private double[] cellSize; + + public Geometry(GeometryFactory geometryFactory) { + this.geometryFactory = geometryFactory; + surfaces.clear(); + } + + public BoundingBox computeBoundingBox() { + if (Util.isVarArgsNotNull(surfaces.toArray(new Surface[0]))) { + double xmin = Double.MAX_VALUE; + double xmax = -Double.MAX_VALUE; + double ymin = Double.MAX_VALUE; + double ymax = -Double.MAX_VALUE; + double zmin = Double.MAX_VALUE; + double zmax = -Double.MAX_VALUE; + + for (Surface surface : getAllSurfaces()) { + vtkPolyData dataSet = surface.getTransformedDataSet(); + if (dataSet != null) { + double[] bounds = dataSet.GetBounds(); + xmin = Math.min(xmin, bounds[0]); + xmax = Math.max(xmax, bounds[1]); + ymin = Math.min(ymin, bounds[2]); + ymax = Math.max(ymax, bounds[3]); + zmin = Math.min(zmin, bounds[4]); + zmax = Math.max(zmax, bounds[5]); + } + } + return new BoundingBox(xmin, xmax, ymin, ymax, zmin, zmax); + } else { + return new BoundingBox(0, 0, 0, 0, 0, 0); + } + } + + private List getAllSurfaces() { + List allSurfaces = new ArrayList(); + for (Surface surface : surfaces) { + if (surface.getType().isPlane()) { + continue; + } else if (surface.getType().isStl()) { + Solid[] l = (((Stl) surface).getSolids()); + for (Solid solid : l) { + allSurfaces.add(solid); + } + } else { + allSurfaces.add(surface); + } + } + return allSurfaces; + } + + public FeatureLines getLines() { + return lines; + } + + public Surface[] getSurfaces() { + return surfaces.toArray(new Surface[surfaces.size()]); + } + + public void loadGeometry(Model model, ProgressMonitor monitor) { + new GeometryReader(this).loadGeometry(model, monitor); + } + + public void saveGeometry(Model model) { + new GeometrySaver(model, this).save(); + } + + public void writeGeometry(Model model, ProgressMonitor monitor) { + new GeometryWriter(model, this, monitor).write(); + } + + public void loadBlock(BlockMeshDict blockMeshDict, SnappyHexMeshDict snappyHexMeshDict) { + new BlockReader(this).loadBlock(blockMeshDict, snappyHexMeshDict); + } + + public void saveUserDefinedBlock(Model model, Dictionary d) { + new BlockSaver(model, this).saveUserDefinedBlock(d); + } + + public void saveAutoBlock(Model model) { + new BlockSaver(model, this).saveAutomaticBlock(); + } + + public GeometryFactory getFactory() { + return geometryFactory; + } + + public void addSurface(Surface... surfaces) { + for (Surface surface : surfaces) { + this.surfaces.add(surface); + } + } + + public void addLine(FeatureLine... lines) { + for (FeatureLine line : lines) { + this.lines.addLine(line); + } + } + + public void removeSurfaces(Model model, Surface... surfaces) { + for (Surface surface : surfaces) { + geometryFactory.deleteSurface(model, surface); + this.surfaces.remove(surface); + } + } + + public void removeLines(FeatureLine... lines) { + for (FeatureLine line : lines) { + this.lines.remove(line); + } + } + + public boolean contains(Surface surface) { + return surfaces.contains(surface); + } + + public boolean isAutoBoundingBox() { + return autoBoundingBox; + } + + public void setAutoBoundingBox(boolean autoBoundingBox) { + this.autoBoundingBox = autoBoundingBox; + } + + public Surface getABox() { + return geometryFactory.newSurface(Box.class, getAName("box")); + } + + public Surface getASphere() { + return geometryFactory.newSurface(Sphere.class, getAName("sphere")); + } + + public FeatureLine getALine() { + return geometryFactory.newSurface(FeatureLine.class, getALineName("line")); + } + + public Surface getARing() { + return geometryFactory.newSurface(Ring.class, getAName("ring")); + } + + public Surface getAPlane() { + return geometryFactory.newSurface(Plane.class, getAName("plane")); + } + + public Surface getACylinder() { + return geometryFactory.newSurface(Cylinder.class, getAName("cylinder")); + } + + public String getAName(String name) { + List surfacesNames = new ArrayList(); + for (Surface surface : surfaces) { + surfacesNames.add(surface.getName()); + } + + String finalName = name; + int counter = 0; + while (surfacesNames.contains(finalName)) { + finalName = name + counter++; + } + + return finalName; + } + + public String getALineName(String name) { + List linesNames = new ArrayList(); + for (FeatureLine line : lines) { + linesNames.add(line.getName()); + } + + String finalName = name; + int counter = 0; + while (linesNames.contains(finalName)) { + finalName = name + counter++; + } + + return finalName; + } + + public MultiPlane getBlock() { + return block; + } + + public void setBlock(MultiPlane block) { + this.block = block; + } + + public boolean hasBlock() { + return block != null && block != FAKE_BLOCK; + } + + public void clear() { + surfaces.clear(); + } + + public boolean isEmpty() { + return !hasBlock() && surfaces.isEmpty(); + } + + public void hideSurfaces() { + for (Surface surface : surfaces) { + surface.setVisible(false); + } + for (FeatureLine line : lines) { + line.setVisible(false); + } + if (hasBlock()) { + block.setVisible(false); + } + } + + public Surface getSurfaceByPatchName(String patchName) { + for (Surface surface : surfaces) { + if (surface.getPatchName().equals(patchName)) { + return surface; + } + if (surface.hasRegions()) { + for (Surface region : surface.getRegions()) { + if (region.getPatchName().equals(patchName)) { + return region; + } + } + } + } + return null; + } + + public Surface getSurfaceByName(String name) { + for (Surface surface : surfaces) { + if (surface.getName().equals(name)) { + return surface; + } + if (surface.hasRegions()) { + for (Surface region : surface.getRegions()) { + if (region.getName().equals(name)) { + return region; + } + } + } + } + return null; + } + + public boolean contains(String name) { + for (Surface surface : surfaces) { + if (surface.getName().equals(name)) { + return true; + } + if (surface.hasRegions()) { + for (Surface region : surface.getRegions()) { + if (region.getName().equals(name)) { + return true; + } + } + } + } + + for (Surface region : block.getRegions()) { + if (region.getName().equals(name)) { + return true; + } + } + + return false; + } + + public double[] getCellSize(int level) { + if (cellSize != null) { + return new double[] { cellSize[0] / Math.pow(2, level), cellSize[1] / Math.pow(2, level), cellSize[2] / Math.pow(2, level) }; + } else { + return new double[3]; + } + } + + + public void setCellSize(double[] cellSize) { + this.cellSize = cellSize; + } +} diff --git a/src/eu/engys/core/project/geometry/GeometryReader.java b/src/eu/engys/core/project/geometry/GeometryReader.java new file mode 100644 index 0000000..f6500f2 --- /dev/null +++ b/src/eu/engys/core/project/geometry/GeometryReader.java @@ -0,0 +1,304 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry; + +import static eu.engys.core.dictionary.DictionaryUtils.copyIfFound; +import static eu.engys.core.project.system.SnappyHexMeshDict.ADD_LAYERS_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.AUTO_BLOCK_MESH_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.BLOCK_DATA_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.CASTELLATED_MESH_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.CELL_ZONE_INSIDE; +import static eu.engys.core.project.system.SnappyHexMeshDict.CELL_ZONE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_TYPE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_ZONE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FEATURES_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.GEOMETRY_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.LAYERS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.LEVEL_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_CELLS_ACROSS_GAP_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.PROXIMITY_INCREMENT_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.REFINEMENTS_REGIONS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.REFINEMENTS_SURFACES_KEY; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.ListField; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.factory.DefaultGeometryFactory; +import eu.engys.core.project.geometry.surface.Region; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.core.project.system.BlockMeshDict; +import eu.engys.core.project.system.SnappyHexMeshDict; +import eu.engys.util.progress.ProgressMonitor; + +public class GeometryReader { + + private static final Logger logger = LoggerFactory.getLogger(GeometryReader.class); + + private Geometry geometry; + + private SnappyHexMeshDict snappyHexMeshDict; + private Dictionary castellatedDict; + private Dictionary refinementSurfaces; + private Dictionary refinementRegions; + private Dictionary geometryDict; + private Dictionary layers; + + public GeometryReader(Geometry geometry) { + this.geometry = geometry; + } + + public void loadGeometry(Model model, ProgressMonitor monitor) { + snappyHexMeshDict = model.getProject().getSystemFolder().getSnappyHexMeshDict(); + + if (hasAValidStructure(snappyHexMeshDict)) { + initDictionaries(); + loadFeatureLines(model, monitor); + loadSurfaces(model, monitor); + } + + if (snappyHexMeshDict == null) { + return; + } + + if (!snappyHexMeshDict.found(AUTO_BLOCK_MESH_KEY) || !snappyHexMeshDict.lookup(AUTO_BLOCK_MESH_KEY).equals("true")) { + BlockMeshDict blockMeshDict = model.getProject().getSystemFolder().getBlockMeshDict(); + if (blockMeshDict != null) { + geometry.setAutoBoundingBox(false); + if (!blockMeshDict.isFromFile()) { + new BlockReader(geometry).loadBlock(blockMeshDict, snappyHexMeshDict); + } + } else { + logger.warn("No patches found in blockMeshDict"); + } + } else { + geometry.setAutoBoundingBox(true); + if (snappyHexMeshDict.found(BLOCK_DATA_KEY)) { + double[] blockData = snappyHexMeshDict.lookupDoubleArray(BLOCK_DATA_KEY); + geometry.setCellSize(new double[] { blockData[0], blockData[0], blockData[0] }); + } + } + model.geometryChanged(); + } + + private boolean hasAValidStructure(SnappyHexMeshDict snappyHexMeshDict) { + if (snappyHexMeshDict != null && snappyHexMeshDict.found(GEOMETRY_KEY) && snappyHexMeshDict.found(CASTELLATED_MESH_CONTROLS_KEY)) { + Dictionary castellatedDict = snappyHexMeshDict.subDict(CASTELLATED_MESH_CONTROLS_KEY); + if (castellatedDict.found(REFINEMENTS_SURFACES_KEY)) { + if (castellatedDict.found(REFINEMENTS_REGIONS_KEY)) { + if (snappyHexMeshDict.found(ADD_LAYERS_CONTROLS_KEY) && snappyHexMeshDict.subDict(ADD_LAYERS_CONTROLS_KEY).found(LAYERS_KEY)) { + return true; + } else { + logger.error("SnappyHexMeshDict bad structure: addLayersControls is missing."); + } + } else { + logger.error("SnappyHexMeshDict bad structure: refinementRegions is missing."); + } + } else { + logger.error("SnappyHexMeshDict bad structure: refinementSurfaces is missing."); + } + } else { + logger.error("SnappyHexMeshDict missing or with bad structure"); + } + return false; + } + + private void initDictionaries() { + geometryDict = snappyHexMeshDict.subDict(GEOMETRY_KEY); + castellatedDict = snappyHexMeshDict.subDict(CASTELLATED_MESH_CONTROLS_KEY); + refinementSurfaces = castellatedDict.subDict(REFINEMENTS_SURFACES_KEY); + refinementRegions = castellatedDict.subDict(REFINEMENTS_REGIONS_KEY); + layers = snappyHexMeshDict.subDict(ADD_LAYERS_CONTROLS_KEY).subDict(LAYERS_KEY); + } + + private void loadFeatureLines(final Model model, final ProgressMonitor monitor) { + if (castellatedDict.found(FEATURES_KEY) && castellatedDict.isList(FEATURES_KEY)) { +// Dictionary lines = new Dictionary(""); +// lines.add(new ListField(castellatedDict.getList(FEATURES_KEY))); + ListField list = castellatedDict.getList(FEATURES_KEY); + for (DefaultElement el : list.getListElements()) { + if (el instanceof Dictionary) { + Dictionary dict = (Dictionary) el; + final FeatureLine line = (FeatureLine) geometry.getFactory().loadSurface(dict, model, monitor); + line.fromDictionary(dict); + + logger.info("LINE: " + line.getName()); + geometry.addLine( line); + } + + } + } + } + + private void loadSurfaces(final Model model, final ProgressMonitor monitor) { + DefaultGeometryFactory.clearSTLCache(); + List dictionaries = geometryDict.getDictionaries(); + + final List surfaces = Collections.synchronizedList(new ArrayList()); + + monitor.setTotal(dictionaries.size()); + monitor.info("STLS:", 1); + + for (int i = 0; i < dictionaries.size(); i++) { + final Dictionary dict = dictionaries.get(i); + surfaces.add(geometry.getFactory().loadSurface(dict, model, monitor)); + } + + String[] surfaceNames = new String[surfaces.size()]; + for (int i = 0; i < surfaces.size(); i++) { + Surface surface = surfaces.get(i); + if (surface != null) { + surfaceNames[i] = surface.getName(); + loadSurface(surface); + } else { + logger.warn("A surface is null"); + } + } + monitor.info("Surfaces:" + Arrays.toString(surfaceNames), 1); + } + + private void loadSurface(Surface surface) { + geometry.addSurface(surface); + readRefinementSurfaces(surface); + readRefinementRegions(surface); + readLayers(surface); + } + + void readRefinementSurfaces(Surface surface) { + String name = surface.getName(); + if (refinementSurfaces.found(name)) { + logger.info("SURFACE: " + name); + Dictionary surfaceDict = refinementSurfaces.subDict(name); + if (isAFaceZone(surfaceDict)) { + readSurfaceAsACellZone(surface, surfaceDict); + } else { + readSurface(surface, surfaceDict); + } + } + } + + private void readSurface(Surface surface, Dictionary surfaceDict) { + surface.setSurfaceDictionary(surfaceDict); + if (surfaceDict.found("regions") && surface.getType().isStl()) { + Dictionary regionsDict = surfaceDict.subDict("regions"); + Stl stl = (Stl) surface; + for (Region region : stl.getRegions()) { + if (regionsDict.found(region.getName())) { + region.setSurfaceDictionary(regionsDict.subDict(region.getName())); + } + } + } + } + + private void readSurfaceAsACellZone(Surface surface, Dictionary surfaceDict) { + + surface.setZoneDictionary(surfaceDict); + if (isACellZone(surfaceDict)) { + surfaceDict.add("isCellZone", "true"); + } else { + surfaceDict.add("isCellZone", "false"); + } + if (!surfaceDict.found(FACE_TYPE_KEY)) { + surfaceDict.add(FACE_TYPE_KEY, "internal"); + } + surfaceDict.add(CELL_ZONE_INSIDE, "inside"); + + Dictionary sd = surface.getSurfaceDictionary(); + copyIfFound(sd, surfaceDict, LEVEL_KEY); + copyIfFound(sd, surfaceDict, PROXIMITY_INCREMENT_KEY); + copyIfFound(sd, surfaceDict, MAX_CELLS_ACROSS_GAP_KEY); + } + + private boolean isACellZone(Dictionary surfaceDict) { + return surfaceDict.found(CELL_ZONE_KEY); + } + + private boolean isAFaceZone(Dictionary surfaceDict) { + return surfaceDict.found(FACE_ZONE_KEY); + } + + void readRefinementRegions(Surface surface) { + String name = surface.getName(); + if (refinementRegions.found(name)) { + logger.info("VOLUME: " + name); + Dictionary volumeDict = refinementRegions.subDict(name); + + String mode = volumeDict.lookup("mode"); + if ("inside".equals(mode) || "outside".equals(mode) || "distance".equals(mode)) { + surface.setVolumeDictionary(volumeDict); + } else { + logger.error("Volume dictionary does not contain a valid ('inside', 'outside' or 'distance') mode"); + } + } else { + surface.getVolumeDictionary().add("mode", "none"); + } + } + + void readLayers(Surface surface) { + if (surface.hasRegions()) { + if (surface.isSingleton()) { + if (surface.isAppendRegionName()) { + Region region = surface.getRegions()[0]; + if (layers.found(region.getPatchName())) { + region.setLayerDictionary(layers.subDict(region.getPatchName())); + } + } else { + if (layers.found(surface.getPatchName())) { + surface.setLayerDictionary(layers.subDict(surface.getPatchName())); + } + } + } else { + for (Region region : surface.getRegions()) { + if (layers.found(region.getPatchName())) { + region.setLayerDictionary(layers.subDict(region.getPatchName())); + } + } + } + } else { + if (layers.found(surface.getPatchName())) { + surface.setLayerDictionary(layers.subDict(surface.getPatchName())); + } + } + } + + // private boolean levelNotZeroZero(Dictionary surfaceDictionary) { + // if (surfaceDictionary.found("level")) { + // String[] level = surfaceDictionary.lookupArray("level"); + // return Integer.parseInt(level[0]) != 0 || Integer.parseInt(level[1]) != + // 0; + // } + // return false; + // } +} diff --git a/src/eu/engys/core/project/geometry/GeometrySaver.java b/src/eu/engys/core/project/geometry/GeometrySaver.java new file mode 100644 index 0000000..f612413 --- /dev/null +++ b/src/eu/engys/core/project/geometry/GeometrySaver.java @@ -0,0 +1,345 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry; + +import static eu.engys.core.dictionary.DictionaryUtils.copyIfFound; +import static eu.engys.core.project.system.SnappyHexMeshDict.ADD_LAYERS_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.BAFFLE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.BOUNDARY_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.CASTELLATED_MESH_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.CELL_ZONE_INSIDE; +import static eu.engys.core.project.system.SnappyHexMeshDict.CELL_ZONE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.DISTANCE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.EXPANSION_RATIO_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_TYPE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_ZONE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FCH_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FEATURES_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FINAL_LAYER_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.GEOMETRY_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.GROWN_UP_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.INSIDE; +import static eu.engys.core.project.system.SnappyHexMeshDict.IS_CELL_ZONE; +import static eu.engys.core.project.system.SnappyHexMeshDict.LAYERS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.LEVELS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.LEVEL_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_CELLS_ACROSS_GAP_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_LAYER_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MODE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.NONE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_SURFACE_LAYERS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.OUTSIDE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.PROXIMITY_INCREMENT_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.REFINEMENTS_REGIONS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.REFINEMENTS_SURFACES_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.REGIONS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.TWO_SIDED_KEY; + +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.ListField; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.geometry.surface.Region; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.core.project.system.SnappyHexMeshDict; +import eu.engys.util.Util; + +public class GeometrySaver { + + private Logger logger = LoggerFactory.getLogger(GeometrySaver.class); + + private Model model; + private Geometry geometry; + + private Dictionary geometryDict; + private Dictionary castellatedDict; + private Dictionary refinementSurfaces; + private Dictionary refinementRegions; + private Dictionary layers; + + public GeometrySaver(Model model, Geometry geometry) { + this.model = model; + this.geometry = geometry; + } + + public void save() { + SnappyHexMeshDict snappyHexMeshDict = model.getProject().getSystemFolder().getSnappyHexMeshDict(); + + if (snappyHexMeshDict == null) { + return; + } + initDictionaries(snappyHexMeshDict); + + saveFeatureLines(model); + saveSurfaces(model); + saveBlock(); + + // logger.info("Geometry: \n {}", snappyHexMeshDict); + } + + private void initDictionaries(SnappyHexMeshDict snappyHexMeshDict) { + geometryDict = snappyHexMeshDict.subDict(GEOMETRY_KEY); + castellatedDict = snappyHexMeshDict.subDict(CASTELLATED_MESH_CONTROLS_KEY); + refinementSurfaces = castellatedDict.subDict(REFINEMENTS_SURFACES_KEY); + refinementRegions = castellatedDict.subDict(REFINEMENTS_REGIONS_KEY); + layers = snappyHexMeshDict.subDict(ADD_LAYERS_CONTROLS_KEY).subDict(LAYERS_KEY); + + geometryDict.clear(); + refinementSurfaces.clear(); + refinementRegions.clear(); + layers.clear(); + } + + private void saveFeatureLines(Model model) { + ListField lines = new ListField(FEATURES_KEY); + for (FeatureLine line : geometry.getLines()) { + lines.add(line.toDictionary()); + } + castellatedDict.add(lines); + } + + private void saveSurfaces(Model model) { + for (Surface surface : geometry.getSurfaces()) { + if (surface.getType().isStl()) { + saveSTL((Stl) surface); + } + saveToGeometry(surface); + if (isACellZone(surface)) { + saveToRefinementSurfacesAsCellZone(surface); + } else if (hasSurfaceRefinement(surface)) { + saveToRefinementSurfaces(surface); + } + saveToRefinementRegions(surface); + + saveToLayers(surface); + + fixEmptySurfacesToZeroLevel(surface); + } + } + + private void saveSTL(Stl stl) { + AffineTransform transformation = stl.getTransformation(); + if (stl.getTransformMode() == TransfromMode.TO_DICTIONARY) { + if (!transformation.isIdentity()) { + ListField transforms = transformation.toDictionary(); + stl.getGeometryDictionary().add(transforms); + } + } + } + + private void saveToGeometry(Surface surface) { + Dictionary geometryDictionary = surface.getGeometryDictionary(); + if (geometryDictionary != null && geometryDictionary.found(Dictionary.TYPE)) { + geometryDict.add(geometryDictionary); + } + } + + private void saveToRefinementSurfacesAsCellZone(Surface surface) { + Dictionary surfaceDictionary = surface.getSurfaceDictionary(); + if (surfaceDictionary.found(LEVEL_KEY)) { + Dictionary zoneDictionary = surface.getZoneDictionary(); + Dictionary sd = new Dictionary(zoneDictionary); + + copyIfFound(sd, surfaceDictionary, LEVEL_KEY); + copyIfFound(sd, surfaceDictionary, PROXIMITY_INCREMENT_KEY); + copyIfFound(sd, surfaceDictionary, MAX_CELLS_ACROSS_GAP_KEY); + + if (sd.found(FACE_ZONE_KEY)) { + sd.add(CELL_ZONE_INSIDE, INSIDE); + if (sd.found(IS_CELL_ZONE)) { + if (sd.lookup(IS_CELL_ZONE).equals("true")) { + if (sd.found(CELL_ZONE_KEY)) { + sd.add(CELL_ZONE_KEY, sd.lookup(CELL_ZONE_KEY)); + } else { + sd.add(CELL_ZONE_KEY, sd.lookup(FACE_ZONE_KEY)); + } + } else { + sd.remove(CELL_ZONE_KEY); + } + sd.remove(IS_CELL_ZONE); + } + sd.remove(REGIONS_KEY); + } + refinementSurfaces.add(sd); + } + } + + private void saveToRefinementSurfaces(Surface surface) { + Dictionary surfaceDictionary = surface.getSurfaceDictionary(); + if (surface.getType().isStl()) { + Stl stl = (Stl) surface; + Dictionary regions = null; + + if (surfaceDictionary.found(REGIONS_KEY)) { + regions = surfaceDictionary.subDict(REGIONS_KEY); + } else { + regions = new Dictionary(REGIONS_KEY); + surfaceDictionary.add(regions); + } + + for (Region region : stl.getRegions()) { + Dictionary regionDictionary = region.getSurfaceDictionary(); + if (!surfaceRefinementIsZero(region)) { + regions.add(regionDictionary); + } + } + + if (regions.isEmpty()) { + surfaceDictionary.remove(REGIONS_KEY); + } + + if (surfaceDictionary.found(REGIONS_KEY) && !surfaceDictionary.found(LEVEL_KEY)) { + surfaceDictionary.add(LEVEL_KEY, "(0 0)"); + } + } + + if (!surfaceDictionary.isEmpty()) { + refinementSurfaces.add(surfaceDictionary); + } else { + refinementSurfaces.remove(surfaceDictionary.getName()); + } + } + + private void saveToRefinementRegions(Surface surface) { + Dictionary volumeDictionary = surface.getVolumeDictionary(); + if (volumeDictionary.found(LEVELS_KEY)) { + String mode = volumeDictionary.lookup(MODE_KEY); + if (mode != null && (mode.equals(INSIDE) || mode.equals(OUTSIDE_KEY) || mode.equals(DISTANCE_KEY))) { + refinementRegions.add(new Dictionary(volumeDictionary)); + } + } + } + + private void saveToLayers(Surface surface) { + if (surface.hasRegions()) { + if (surface.isSingleton()) { + Region region = surface.getRegions()[0]; + if (hasLayers(region)) { + addToLayers(region.getPatchName(), region); + } else if (hasLayers(surface)) { + addToLayers(region.getPatchName(), surface); + } + } else { + for (Region region : surface.getRegions()) { + if (hasLayers(region)) { + addToLayers(region.getPatchName(), region); + if (isBoundaryOrBaffleZone(surface.getZoneDictionary())) { + addToLayers(region.getPatchName() + "_slave", region); + } + } else if (hasLayers(surface)) { + addToLayers(region.getPatchName(), surface); + if (isBoundaryOrBaffleZone(surface.getZoneDictionary())) { + addToLayers(region.getPatchName() + "_slave", surface); + } + } + } + } + } else { + if (hasLayers(surface)) { + addToLayers(surface.getPatchName(), surface); + if (isBoundaryOrBaffleZone(surface.getZoneDictionary())) { + addToLayers(surface.getPatchName() + "_slave", surface); + } + } + } + } + + private void saveBlock() { + if (geometry.hasBlock()) { + saveToLayers(geometry.getBlock()); + } + } + + private void addToLayers(String patchName, Surface surface) { + if (isGrownUpLayers(surface)) { + Dictionary layerDict = new Dictionary(patchName); + layerDict.add(GROWN_UP_KEY, "true"); + layerDict.add(N_SURFACE_LAYERS_KEY, "0"); + layers.add(layerDict); + } else { + Dictionary layerDict = new Dictionary(surface.getLayerDictionary()); + layerDict.setName(patchName); + layers.add(layerDict); + } + } + + private boolean hasSurfaceRefinement(Surface surface) { + Dictionary volumeDictionary = surface.getVolumeDictionary(); + return volumeDictionary == null || !volumeDictionary.found(MODE_KEY) || volumeDictionary.lookup(MODE_KEY).equals(DISTANCE_KEY) || volumeDictionary.lookup(MODE_KEY).equals(NONE_KEY); + } + + private void fixEmptySurfacesToZeroLevel(Surface surface) { + if (!refinementSurfaces.found(surface.getName()) && !refinementRegions.found(surface.getName())) { + Dictionary surfaceDictionary = surface.getSurfaceDictionary(); + surfaceDictionary.add(LEVEL_KEY, "(0 0)"); + refinementSurfaces.add(surfaceDictionary); + } + } + + private boolean surfaceRefinementIsZero(Surface surface) { + Dictionary surfaceDictionary = surface.getSurfaceDictionary(); + return surfaceDictionary.isEmpty() || (surfaceDictionary.found(LEVEL_KEY) && Arrays.equals(surfaceDictionary.lookupIntArray(LEVEL_KEY), new int[2])); + } + + private boolean isACellZone(Surface surface) { + Dictionary zoneDictionary = surface.getZoneDictionary(); + return zoneDictionary != null && zoneDictionary.found(FACE_TYPE_KEY) && !zoneDictionary.lookup(FACE_TYPE_KEY).equals(NONE_KEY); + } + + private boolean isGrownUpLayers(Surface surface) { + Dictionary layerDictionary = surface.getLayerDictionary(); + return layerDictionary.found(GROWN_UP_KEY) && layerDictionary.lookup(GROWN_UP_KEY).equals("true"); + } + + private boolean hasNSurfaceLayers(Surface surface) { + Dictionary layerDictionary = surface.getLayerDictionary(); + return layerDictionary.found(N_SURFACE_LAYERS_KEY) && !layerDictionary.lookup(N_SURFACE_LAYERS_KEY).equals("0"); + } + + private boolean hasLayers(Surface surface) { + Dictionary layerDictionary = surface.getLayerDictionary(); + int total = checkValue(layerDictionary, N_SURFACE_LAYERS_KEY) + checkValue(layerDictionary, MAX_LAYER_THICKNESS_KEY) + checkValue(layerDictionary, FINAL_LAYER_THICKNESS_KEY) + checkValue(layerDictionary, EXPANSION_RATIO_KEY) + checkValue(layerDictionary, FCH_KEY); + + return isGrownUpLayers(surface) || hasNSurfaceLayers(surface) || (total > 0 && total == 3); + } + + private int checkValue(Dictionary d, String key) { + return Util.boolToInt(d.found(key) && d.lookupDouble(key) != 0); + } + + private boolean isTwoSided(Dictionary surfaceDictionary) { + return surfaceDictionary.found(TWO_SIDED_KEY) && Boolean.parseBoolean(surfaceDictionary.lookup(TWO_SIDED_KEY)); + } + + private boolean isBoundaryOrBaffleZone(Dictionary zoneDictionary) { + return zoneDictionary.found(FACE_TYPE_KEY) && (zoneDictionary.lookup(FACE_TYPE_KEY).equals(BAFFLE_KEY) || zoneDictionary.lookup(FACE_TYPE_KEY).equals(BOUNDARY_KEY)); + } +} diff --git a/src/eu/engys/core/project/geometry/GeometryWriter.java b/src/eu/engys/core/project/geometry/GeometryWriter.java new file mode 100644 index 0000000..4e486fa --- /dev/null +++ b/src/eu/engys/core/project/geometry/GeometryWriter.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry; + +import eu.engys.core.project.Model; +import eu.engys.util.progress.ProgressMonitor; + +public class GeometryWriter { + + private Model model; + private Geometry geometry; + private ProgressMonitor monitor; + + public GeometryWriter(Model model, Geometry geometry, ProgressMonitor monitor) { + this.model = model; + this.geometry = geometry; + this.monitor = monitor; + } + + public void write() { + writeFeatureLines(); + writeSurfaces(); + } + + private void writeFeatureLines() { + for (FeatureLine line : geometry.getLines()) { + geometry.getFactory().writeSurface(line, model, monitor); + } + } + + private void writeSurfaces() { + for (Surface surface : geometry.getSurfaces()) { + + if (surface.getType().isStl()) { + geometry.getFactory().writeSurface(surface, model, monitor); + } + } + } + +} diff --git a/src/eu/engys/core/project/geometry/Surface.java b/src/eu/engys/core/project/geometry/Surface.java new file mode 100644 index 0000000..d5e1b60 --- /dev/null +++ b/src/eu/engys/core/project/geometry/Surface.java @@ -0,0 +1,374 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry; + +import static eu.engys.core.project.system.SnappyHexMeshDict.EXPANSION_RATIO_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_TYPE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FINAL_LAYER_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.LEVEL_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.NONE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_SURFACE_LAYERS_KEY; +import vtk.vtkPolyData; +import vtk.vtkTransform; +import vtk.vtkTransformFilter; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.geometry.surface.Region; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public abstract class Surface implements VisibleItem { + + public static final String MAX_KEY = "max"; + public static final String MIN_KEY = "min"; + public static final String POINT1_KEY = "point1"; + public static final String POINT2_KEY = "point2"; + public static final String RADIUS_KEY = "radius"; + public static final String CENTRE_KEY = "centre"; + public static final String OUTER_RADIUS_KEY = "outerRadius"; + public static final String INNER_RADIUS_KEY = "innerRadius"; + public static final String PLANE_TYPE_KEY = "planeType"; + public static final String NORMAL_VECTOR_KEY = "normalVector"; + public static final String BASE_POINT_KEY = "basePoint"; + public static final String POINT_AND_NORMAL_KEY = "pointAndNormal"; + public static final String POINT_AND_NORMAL_DICT_KEY = "pointAndNormalDict"; + + public static final String TRI_SURFACE_MESH_KEY = "triSurfaceMesh"; + public static final String SEARCHABLE_RING_KEY = "searchableRing"; + public static final String SEARCHABLE_PLANE_KEY = "searchablePlane"; + public static final String SEARCHABLE_SPHERE_KEY = "searchableSphere"; + public static final String SEARCHABLE_CYLINDER_KEY = "searchableCylinder"; + public static final String SEARCHABLE_BOX_KEY = "searchableBox"; + + private Dictionary geometryDictionary; + private Dictionary surfaceDictionary; + private Dictionary volumeDictionary; + private Dictionary layerDictionary; + private Dictionary zoneDictionary; + + protected String name; + + private boolean visible = true; + private AffineTransform transformation; + private TransfromMode transformMode; + + public static final Dictionary surfaceDefault = new Dictionary("") { + { + add(LEVEL_KEY, "(0 0)"); + } + }; + public static final Dictionary volumeDefault = new Dictionary("") { + { + add("mode", "none"); + } + }; + public static final Dictionary zonesDefault = new Dictionary("") { + { + add(FACE_TYPE_KEY, NONE_KEY); + } + }; + public static final Dictionary layerDefault = new Dictionary("") { + { + add(N_SURFACE_LAYERS_KEY, "0"); + add(EXPANSION_RATIO_KEY, "1.25"); + add(FINAL_LAYER_THICKNESS_KEY, "0.4"); + } + }; + + public static final Dictionary stl = new Dictionary("name.stl") { + { + add(TYPE, TRI_SURFACE_MESH_KEY); + add("name", "name"); + } + }; + public static final Dictionary box = new Dictionary("box") { + { + add(TYPE, SEARCHABLE_BOX_KEY); + add(MIN_KEY, "(0 0 0)"); + add(MAX_KEY, "(2 2 1)"); + } + }; + public static final Dictionary cylinder = new Dictionary("cylinder") { + { + add(TYPE, SEARCHABLE_CYLINDER_KEY); + add(POINT1_KEY, "(0 0 0)"); + add(POINT2_KEY, "(1 0 0)"); + add(RADIUS_KEY, "1.0"); + } + }; + public static final Dictionary sphere = new Dictionary("sphere") { + { + add(TYPE, SEARCHABLE_SPHERE_KEY); + add(CENTRE_KEY, "(0 0 0)"); + add(RADIUS_KEY, "1.0"); + } + }; + public static final Dictionary plane = new Dictionary("plane") { + { + add(TYPE, SEARCHABLE_PLANE_KEY); + add(PLANE_TYPE_KEY, POINT_AND_NORMAL_KEY); + Dictionary dict = new Dictionary(POINT_AND_NORMAL_DICT_KEY); +// dict.add(BASE_POINT_KEY, "(0 0 0)"); + dict.add(NORMAL_VECTOR_KEY, "(0 0 1)"); + add(dict); + } + }; + public static final Dictionary planeWithCenter = new Dictionary("plane") { + { + add(TYPE, SEARCHABLE_PLANE_KEY); + add(PLANE_TYPE_KEY, POINT_AND_NORMAL_KEY); + Dictionary dict = new Dictionary(POINT_AND_NORMAL_DICT_KEY); + dict.add(BASE_POINT_KEY, "(0 0 0)"); + dict.add(NORMAL_VECTOR_KEY, "(0 0 1)"); + add(dict); + } + }; + public static final Dictionary ring = new Dictionary("ring") { + { + add(TYPE, SEARCHABLE_RING_KEY); + add(POINT1_KEY, "(0 0 0)"); + add(POINT2_KEY, "(0.05 0 0)"); + add(INNER_RADIUS_KEY, "0.2"); + add(OUTER_RADIUS_KEY, "0.5"); + } + }; + + public Surface(String name) { + this.name = name; + + this.surfaceDictionary = new Dictionary(name, surfaceDefault); + this.volumeDictionary = new Dictionary(name, volumeDefault); + this.layerDictionary = new Dictionary(name, layerDefault); + this.zoneDictionary = new Dictionary(name, zonesDefault); + + this.transformation = new AffineTransform(); +// this.transformMode = TransfromMode.TO_DICTIONARY; + this.transformMode = TransfromMode.TO_FILE; + } + + public boolean isAppendRegionName() { + return geometryDictionary.found("appendRegionName") && geometryDictionary.lookup("appendRegionName").equals("true"); + } + + public String getName() { + return name; + } + + public abstract String getPatchName(); + + public String getZoneName() { + return zoneDictionary.lookup("cellZone"); + } + + @Override + public boolean isVisible() { + return visible; + } + + @Override + public void setVisible(boolean visible) { + this.visible = visible; + } + + public abstract Type getType(); + + public abstract boolean isSingleton(); + + public abstract boolean hasRegions(); + + public abstract Region[] getRegions(); + + public abstract boolean hasSurfaceRefinement(); + + public abstract boolean hasVolumeRefinement(); + + public abstract boolean hasLayers(); + + public abstract boolean hasZones(); + + public abstract Surface cloneSurface(); + + protected abstract vtkPolyData getDataSet(); + + public vtkPolyData getTransformedDataSet() { + vtkPolyData dataSet = getDataSet(); + if (dataSet != null) { + if (getTransformation() != null) { + vtkTransformFilter tFilter = new vtkTransformFilter(); + tFilter.SetTransform(getTransformation().toVTK(new vtkTransform())); + tFilter.SetInputData(dataSet); + tFilter.Update(); + + return (vtkPolyData) tFilter.GetOutput(); + } else { + return dataSet; + } + } else { + return null; + } + } + + public void setGeometryDictionary(Dictionary geometryDictionary) { + this.geometryDictionary = geometryDictionary; + } + + public Dictionary getGeometryDictionary() { + return geometryDictionary; + } + + public void setSurfaceDictionary(Dictionary surfaceDictionary) { + this.surfaceDictionary = surfaceDictionary; + } + + public Dictionary getSurfaceDictionary() { + return surfaceDictionary; + } + + public void setVolumeDictionary(Dictionary volumeDictionary) { + this.volumeDictionary = volumeDictionary; + } + + public Dictionary getVolumeDictionary() { + return volumeDictionary; + } + + public void setLayerDictionary(Dictionary layerDictionary) { + this.layerDictionary = layerDictionary; + } + + public Dictionary getLayerDictionary() { + return layerDictionary; + } + + public void setZoneDictionary(Dictionary zoneDictionary) { + this.zoneDictionary = zoneDictionary; + } + + public Dictionary getZoneDictionary() { + return zoneDictionary; + } + + public Dictionary toDictionary() { + Dictionary d = new Dictionary(getName()); + d.add(new Dictionary("surface", surfaceDictionary)); + d.add(new Dictionary("volume", volumeDictionary)); + d.add(new Dictionary("layer", layerDictionary)); + d.add(new Dictionary("zone", zoneDictionary)); + + return d; + } + + public void fromDictionary(Dictionary d) { + buildSurfaceDictionary(d.subDict("surface")); + buildVolumeDictionary(d.subDict("volume")); + buildLayerDictionary(d.subDict("layer")); + buildZoneDictionary(d.subDict("zone")); + } + + @Override + public String toString() { + return String.format("[ name: %s, patch_name: %s, type: %s, singleton: %s, visible: %s] ", getName(), getPatchName(), getType(), isSingleton(), isVisible()); + } + + public void rename(String newName) { + String oldName = getName(); + if (oldName.equals(newName)) + return; + + this.name = newName; + getSurfaceDictionary().setName(getName()); + getVolumeDictionary().setName(getName()); + getLayerDictionary().setName(getName()); + getZoneDictionary().setName(getName()); + } + + public void buildGeometryDictionary(Dictionary dictionary) { + Dictionary geometryDict = new Dictionary(dictionary); + geometryDict.setName(getName()); + getSurfaceDictionary().setName(getName()); + getVolumeDictionary().setName(getName()); + getLayerDictionary().setName(getName()); + getZoneDictionary().setName(getName()); + setGeometryDictionary(geometryDict); + } + + public void buildSurfaceDictionary(Dictionary dictionary) { + Dictionary surfaceDict = new Dictionary(dictionary); + surfaceDict.setName(getName()); + setSurfaceDictionary(surfaceDict); + } + + public void buildVolumeDictionary(Dictionary dictionary) { + Dictionary volumeDict = new Dictionary(dictionary); + volumeDict.setName(getName()); + setVolumeDictionary(volumeDict); + } + + public void buildLayerDictionary(Dictionary dictionary) { + Dictionary layerDict = new Dictionary(dictionary); + layerDict.setName(getName()); + setLayerDictionary(layerDict); + } + + public void buildZoneDictionary(Dictionary dictionary) { + Dictionary zoneDict = new Dictionary(dictionary); + zoneDict.setName(getName()); + setZoneDictionary(zoneDict); + } + + public boolean willBePatch() { + return (getType().isSolid() && !((Solid) this).getParent().isSingleton()) || (getType().isStl() && isSingleton()); + } + + protected void cloneSurface(Surface surface) { + if (this.geometryDictionary != null) { + surface.geometryDictionary = new Dictionary(this.geometryDictionary); + } + surface.surfaceDictionary = new Dictionary(this.surfaceDictionary); + surface.volumeDictionary = new Dictionary(this.volumeDictionary); + surface.layerDictionary = new Dictionary(this.layerDictionary); + surface.zoneDictionary = new Dictionary(this.zoneDictionary); + + surface.visible = this.visible; + surface.transformation = new AffineTransform(this.transformation); + //System.out.println("Surface.cloneSurface() HASH: "+surface.hashCode()+surfaceDictionary+surface.surfaceDictionary); + } + + public AffineTransform getTransformation() { + return transformation; + } + public void setTransformation(AffineTransform transformation) { + this.transformation = transformation; + } + + public TransfromMode getTransformMode() { + return transformMode; + } + public void setTransformMode(TransfromMode transformMode) { + this.transformMode = transformMode; + } +} diff --git a/src/eu/engys/core/project/geometry/TransfromMode.java b/src/eu/engys/core/project/geometry/TransfromMode.java new file mode 100644 index 0000000..8f3db8b --- /dev/null +++ b/src/eu/engys/core/project/geometry/TransfromMode.java @@ -0,0 +1,31 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry; + +public enum TransfromMode { + TO_DICTIONARY, TO_FILE; + +} diff --git a/src/eu/engys/core/project/geometry/Type.java b/src/eu/engys/core/project/geometry/Type.java new file mode 100644 index 0000000..04be117 --- /dev/null +++ b/src/eu/engys/core/project/geometry/Type.java @@ -0,0 +1,77 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry; + +public enum Type { + STL, BOX, CYLINDER, SPHERE, REGION, SOLID, PLANE, MULTI, RING, LINE; + + public boolean isStl() { + return equals(STL); + } + + public boolean isBox() { + return equals(BOX); + } + + public boolean isCylinder() { + return equals(CYLINDER); + } + + public boolean isSphere() { + return equals(SPHERE); + } + + public boolean isRing() { + return equals(RING); + } + + public boolean isRegion() { + return equals(REGION); + } + + public boolean isMulti() { + return equals(MULTI); + } + + public boolean isSolid() { + return equals(SOLID); + } + + public boolean isPlane() { + return equals(PLANE); + } + + public boolean isLine() { + return equals(LINE); + } + + public boolean isBaseShape() { + return isBox() ||isPlane() ||isSphere() || isRing(); + } + + +} diff --git a/src/eu/engys/core/project/geometry/factory/DefaultGeometryFactory.java b/src/eu/engys/core/project/geometry/factory/DefaultGeometryFactory.java new file mode 100644 index 0000000..dcb89bb --- /dev/null +++ b/src/eu/engys/core/project/geometry/factory/DefaultGeometryFactory.java @@ -0,0 +1,311 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.factory; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.core.project.geometry.Surface.SEARCHABLE_BOX_KEY; +import static eu.engys.core.project.geometry.Surface.SEARCHABLE_CYLINDER_KEY; +import static eu.engys.core.project.geometry.Surface.SEARCHABLE_PLANE_KEY; +import static eu.engys.core.project.geometry.Surface.SEARCHABLE_RING_KEY; +import static eu.engys.core.project.geometry.Surface.SEARCHABLE_SPHERE_KEY; +import static eu.engys.core.project.geometry.Surface.TRI_SURFACE_MESH_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FILE_KEY; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.TransfromMode; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.geometry.stl.STLReader; +import eu.engys.core.project.geometry.stl.STLWriter; +import eu.engys.core.project.geometry.surface.Box; +import eu.engys.core.project.geometry.surface.Cylinder; +import eu.engys.core.project.geometry.surface.NullSurface; +import eu.engys.core.project.geometry.surface.Plane; +import eu.engys.core.project.geometry.surface.Ring; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.core.project.geometry.surface.Sphere; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.util.ColorUtil; +import eu.engys.util.progress.ProgressMonitor; + +public class DefaultGeometryFactory implements GeometryFactory { + + private static final Logger logger = LoggerFactory.getLogger(DefaultGeometryFactory.class); + private static final Map STLCache = new HashMap<>(); + + @Override + public void deleteSurface(Model model, Surface surface) { + if(surface instanceof Stl) { + File file = model.getProject().getConstantFolder().getTriSurface().getFileManager().getFile(surface.getName()+".stl"); + if (file.exists()) { + FileUtils.deleteQuietly(file); + } + file = model.getProject().getConstantFolder().getTriSurface().getFileManager().getFile(surface.getName()+".STL"); + if (file.exists()) { + FileUtils.deleteQuietly(file); + } + } + } + + @Override + public void writeSurface(Surface surface, Model model, ProgressMonitor monitor) { + if (surface.getType().isStl()) { + writeSTL((Stl) surface, model, monitor); + } else if (surface.getType().isLine()) { + writeFeatureLine((FeatureLine) surface, model, monitor); + } + } + + private void writeFeatureLine(FeatureLine line, Model model, ProgressMonitor monitor) { + String fileName = line.getName() + ".eMesh"; + File file = model.getProject().getConstantFolder().getTriSurface().getFileManager().getFile(fileName); + if (!file.exists()|| line.isModified()) { + new EMESHWriter(file, line).run(); + } + } + + private void writeSTL(Stl stl, Model model, ProgressMonitor monitor) { + String fileName = stl.getFileName(); + File file = model.getProject().getConstantFolder().getTriSurface().getFileManager().getFile(fileName); + AffineTransform transformation = stl.getTransformation(); + + if (stl.getTransformMode() == TransfromMode.TO_DICTIONARY) { + if (!file.exists() || stl.isModified()) { + new STLWriter(file, stl, monitor).run(); + } + } else { + if (!file.exists() || !transformation.isIdentity() || stl.isModified()) { + new STLWriter(file, stl, monitor).run(); + } + } + } + + + + @Override + public Surface loadSurface(Dictionary g, Model model, ProgressMonitor monitor) { + Surface surface; + if (isSTL(g)) { + surface = loadSTL(g, model, monitor); + } else if (isBox(g)) { + surface = loadBox(g); + } else if (isCylinder(g)) { + surface = loadCylinder(g); + } else if (isSphere(g)) { + surface = loadSphere(g); + } else if (isPlane(g)) { + surface = loadPlane(g); + } else if (isRing(g)) { + surface = loadRing(g); + } else if (isLine(g)) { + surface = loadLine(g, model, monitor); + } else { + if (g.isField(Dictionary.TYPE)) + logger.error("Unknown geometry type: {}.", g.lookup(Dictionary.TYPE)); + else + logger.error("Bad geometry dictionary format: {}.", g); + surface = new NullSurface(); + } + if (monitor != null) { + monitor.setCurrent(null, monitor.getCurrent() + 1); + } + return surface; + } + + @Override + public S newSurface(Class type, String name) { + try { + return type.getDeclaredConstructor(String.class).newInstance(name); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /* + * LOAD + */ + + @SuppressWarnings("deprecation") + protected Surface loadBox(Dictionary g) { + Surface box = new Box(g.getName()); + box.setGeometryDictionary(g); + return box; + } + + @SuppressWarnings("deprecation") + protected Cylinder loadCylinder(Dictionary g) { + Cylinder cyl = new Cylinder(g.getName()); + cyl.setGeometryDictionary(g); + return cyl; + } + + @SuppressWarnings("deprecation") + protected Plane loadPlane(Dictionary g) { + Plane plane = new Plane(g.getName()); + plane.setGeometryDictionary(g); + return plane; + } + + @SuppressWarnings("deprecation") + protected Ring loadRing(Dictionary g) { + Ring ring = new Ring(g.getName()); + ring.setGeometryDictionary(g); + return ring; + } + + @SuppressWarnings("deprecation") + protected Sphere loadSphere(Dictionary g) { + Sphere sphere = new Sphere(g.getName()); + sphere.setGeometryDictionary(g); + return sphere; + } + + @SuppressWarnings("deprecation") + protected Stl loadSTL(Dictionary g, Model model, ProgressMonitor monitor) { + Stl stl = new Stl(g.lookup("name")); + stl.setGeometryDictionary(g); + + loadStl(stl, model, monitor); + + stl.setTransformation(AffineTransform.fromGeometryDictionary(g)); + return stl; + } + + private void loadStl(Stl stl, Model model, ProgressMonitor monitor) { + String fileName = stl.getGeometryDictionary().getName(); + File file = model.getProject().getConstantFolder().getTriSurface().getFileManager().getFile(fileName); + stl.setFileName(file); + + if (STLCache.containsKey(fileName)) { + Stl cached = STLCache.get(fileName); + Solid[] cachedSolids = cached.getSolids(); + List solids = new ArrayList<>(); + for (Solid cachedSolid : cachedSolids) { + solids.add((Solid)cachedSolid.cloneSurface()); + } + stl.setSolids(solids); + } else { + STLReader reader = new STLReader(file, monitor); + reader.run(); + List solids = reader.getSolids(); + stl.setSolids(solids); + } + + if (!STLCache.containsKey(fileName)) { + STLCache.put(fileName, stl); + } + } + + @Override + public Stl readSTL(File file, ProgressMonitor monitor) { + String fileName = file.getName(); + String name = FilenameUtils.removeExtension(fileName); + Dictionary g = new Dictionary(fileName, Surface.stl); + g.setName(fileName); + g.add("name", name); + + Stl stl = new Stl(name); + stl.setGeometryDictionary(g); + stl.setFileName(file); + + STLReader reader = new STLReader(file, monitor); + reader.run(); + List solids = reader.getSolids(); + stl.setSolids(solids); + + return stl; + } + + private FeatureLine loadLine(Dictionary g, Model model, ProgressMonitor monitor) { + String fileName = g.lookup("file").replace("\"", ""); + File file = model.getProject().getConstantFolder().getTriSurface().getFileManager().getFile(fileName); + FeatureLine line = readLine(file); + line.setColor(ColorUtil.getColor(model.getGeometry().getLines().size())); + return line; + } + + @Override + public FeatureLine readLine(File file) { + FeatureLine featureLine = new FeatureLine(FilenameUtils.removeExtension(file.getName())); + featureLine.setModified(false); + vtkPolyData dataSet = new EMESHReader(file).run(); + featureLine.setDataSet(dataSet); + + return featureLine; + } + + /* + * IS + */ + + public static boolean isBox(Dictionary g) { + return g.isField(TYPE) && SEARCHABLE_BOX_KEY.equals(g.lookup(TYPE)); + } + + public static boolean isCylinder(Dictionary g) { + return g.isField(TYPE) && SEARCHABLE_CYLINDER_KEY.equals(g.lookup(TYPE)); + } + + public static boolean isSphere(Dictionary g) { + return g.isField(TYPE) && SEARCHABLE_SPHERE_KEY.equals(g.lookup(TYPE)); + } + + public static boolean isPlane(Dictionary g) { + return g.isField(TYPE) && SEARCHABLE_PLANE_KEY.equals(g.lookup(TYPE)); + } + + public static boolean isRing(Dictionary g) { + return g.isField(TYPE) && SEARCHABLE_RING_KEY.equals(g.lookup(TYPE)); + } + + public static boolean isLine(Dictionary g) { + return g.isField(FILE_KEY) && g.lookup(FILE_KEY).contains(".eMesh"); + } + + public static boolean isSTL(Dictionary g) { + return g.isField(TYPE) && TRI_SURFACE_MESH_KEY.equals(g.lookup(TYPE)); + } + + public static void clearSTLCache() { + STLCache.clear(); + } +} diff --git a/src/eu/engys/core/project/geometry/factory/EMESHReader.java b/src/eu/engys/core/project/geometry/factory/EMESHReader.java new file mode 100644 index 0000000..4466100 --- /dev/null +++ b/src/eu/engys/core/project/geometry/factory/EMESHReader.java @@ -0,0 +1,94 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry.factory; + +import java.io.File; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkCellArray; +import vtk.vtkLine; +import vtk.vtkPoints; +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.dictionary.parser.ListField2; +import eu.engys.util.VTKSettings; + +public class EMESHReader { + + private static final Logger logger = LoggerFactory.getLogger(EMESHReader.class); + private File file; + + public EMESHReader(File file) { + this.file = file; + } + + public vtkPolyData run() { + if (file.exists()) { + if (VTKSettings.librariesAreLoaded()) { + logger.info("Read eMesh " + file.getName() + " [ASCII]"); + Dictionary linesDict = DictionaryUtils.readDictionary2(file); + List listFields = linesDict.getListFields2(); + vtkPolyData dataSet = new vtkPolyData(); + if (listFields.size() == 2) { + ListField2 pointsList = listFields.get(0); + ListField2 linesList = listFields.get(1); + + List pointsArray = pointsList.getElementsAsVectorList(); + List linesArray = linesList.getElementsAsVectorList(); + + vtkPoints points = new vtkPoints(); + for (double[] point : pointsArray) { + points.InsertNextPoint(point); + } + + vtkCellArray lines = new vtkCellArray(); + for (double[] line : linesArray) { + vtkLine cell = new vtkLine(); + cell.GetPointIds().SetId(0, (int) line[0]); + cell.GetPointIds().SetId(1, (int) line[1]); + + lines.InsertNextCell(cell); + } + + dataSet.SetPoints(points); + dataSet.SetLines(lines); + } + + return dataSet; + } else { + logger.warn("Read eMesh: no VTK"); + return null; + } + } else { + logger.warn("Read eMesh " + file.getName() + " does not exist"); + return null; + } + } +} diff --git a/src/eu/engys/core/project/geometry/factory/EMESHWriter.java b/src/eu/engys/core/project/geometry/factory/EMESHWriter.java new file mode 100644 index 0000000..938a99a --- /dev/null +++ b/src/eu/engys/core/project/geometry/factory/EMESHWriter.java @@ -0,0 +1,88 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry.factory; + +import java.io.File; + +import vtk.vtkIdList; +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.core.dictionary.parser.ListField2; +import eu.engys.core.project.geometry.FeatureLine; + +public class EMESHWriter { + + private File file; + private FeatureLine line; + + public EMESHWriter(File file, FeatureLine line) { + this.file = file; + this.line = line; + } + + public void run() { + vtkPolyData dataSet = line.getDataSet(); + if (dataSet != null) { + + Dictionary d = new Dictionary(""); + d.setFoamFile(FoamFile.getDictionaryFoamFile("classe", "parent", "name")); + + ListField2 points = new ListField2(String.valueOf(dataSet.GetNumberOfPoints())); + ListField2 lines = new ListField2(String.valueOf(dataSet.GetNumberOfLines())); + + for (int i = 0; i < dataSet.GetNumberOfPoints(); i++) { + double[] point = dataSet.GetPoint(i); + ListField2 pointField = new ListField2(""); + pointField.add(new FieldElement("", String.valueOf(point[0]))); + pointField.add(new FieldElement("", String.valueOf(point[1]))); + pointField.add(new FieldElement("", String.valueOf(point[2]))); + + points.add(pointField); + } + + dataSet.GetLines().InitTraversal(); + for (int i = 0; i < dataSet.GetNumberOfLines(); i++) { + ListField2 lineField = new ListField2(""); + vtkIdList idList = new vtkIdList(); + dataSet.GetLines().GetNextCell(idList); + for (int j = 0; j < idList.GetNumberOfIds(); j++) { + int id = idList.GetId(j); + lineField.add(new FieldElement("", String.valueOf(id))); + + } + lines.add(lineField); + } + + d.add(points); + d.add(lines); + + DictionaryUtils.writeDictionaryFile(file, d); + } + } +} diff --git a/src/eu/engys/core/project/geometry/factory/EngysGeometryFactory.java b/src/eu/engys/core/project/geometry/factory/EngysGeometryFactory.java new file mode 100644 index 0000000..856b5f9 --- /dev/null +++ b/src/eu/engys/core/project/geometry/factory/EngysGeometryFactory.java @@ -0,0 +1,104 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry.factory; + +import java.io.File; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.Cylinder; +import eu.engys.core.project.geometry.surface.Plane; +import eu.engys.core.project.geometry.surface.Ring; +import eu.engys.core.project.geometry.surface.Sphere; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.util.progress.ProgressMonitor; + +public class EngysGeometryFactory extends DefaultGeometryFactory { + + @Override + public S newSurface(Class type, String name) { + S surface = super.newSurface(type, name); + setAppendRegionName(surface, true); + return surface; + } + + public void setAppendRegionName(Surface surface, boolean b) { + if (surface.getGeometryDictionary() != null) { + surface.getGeometryDictionary().add("appendRegionName", Boolean.toString(b)); + } + } + + @Override + protected Surface loadBox(Dictionary g) { + Surface box = super.loadBox(g); + setAppendRegionName(box, true); + return box; + } + + @Override + protected Cylinder loadCylinder(Dictionary g) { + Cylinder cylinder = super.loadCylinder(g); + setAppendRegionName(cylinder, true); + return cylinder; + } + + @Override + protected Plane loadPlane(Dictionary g) { + Plane plane = super.loadPlane(g); + setAppendRegionName(plane, true); + return plane; + } + + @Override + protected Ring loadRing(Dictionary g) { + Ring ring = super.loadRing(g); + setAppendRegionName(ring, true); + return ring; + } + + @Override + protected Sphere loadSphere(Dictionary g) { + Sphere sphere = super.loadSphere(g); + setAppendRegionName(sphere, true); + return sphere; + } + + @Override + protected Stl loadSTL(Dictionary g, Model model, ProgressMonitor monitor) { + Stl stl = super.loadSTL(g, model, monitor); + setAppendRegionName(stl, !stl.isSingleton()); + return stl; + } + + @Override + public Stl readSTL(File file, ProgressMonitor monitor) { + Stl stl = super.readSTL(file, monitor); + setAppendRegionName(stl, !stl.isSingleton()); + return stl; + } + +} diff --git a/src/eu/engys/core/project/geometry/factory/GeometryFactory.java b/src/eu/engys/core/project/geometry/factory/GeometryFactory.java new file mode 100644 index 0000000..1122245 --- /dev/null +++ b/src/eu/engys/core/project/geometry/factory/GeometryFactory.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry.factory; + +import java.io.File; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.util.progress.ProgressMonitor; + +public interface GeometryFactory { + + Surface loadSurface(Dictionary g, Model model, ProgressMonitor monitor); + + void writeSurface(Surface surface, Model model, ProgressMonitor monitor); + + S newSurface(Class type, String name); + + Stl readSTL(File file, ProgressMonitor monitor); + + FeatureLine readLine(File file); + + void deleteSurface(Model model, Surface surface); + +} diff --git a/src/eu/engys/core/project/geometry/stl/AffineTransform.java b/src/eu/engys/core/project/geometry/stl/AffineTransform.java new file mode 100644 index 0000000..8f5a797 --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/AffineTransform.java @@ -0,0 +1,356 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.stl; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +import javax.vecmath.Matrix3d; +import javax.vecmath.Vector3d; + +import vtk.vtkTransform; +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.ListField; + + +public class AffineTransform { + + public static final String YAW_PITCH_ROLL_KEY = "yawPitchRoll"; + public static final String ROLL_PITCH_YAW_KEY = "rollPitchYaw"; + public static final String TRANSFORMS_KEY = "transforms"; + public static final String TRANSLATE_VEC_KEY = "translateVec"; + public static final String TRANSLATE_KEY = "translate"; + public static final String N1N2_KEY = "n1n2"; + public static final String ROTATE_KEY = "rotate"; + public static final String ABOUT_POINT_KEY = "aboutPoint"; + public static final String SCALE_VEC_KEY = "scaleVec"; + public static final String SCALE_KEY = "scale"; + public static final String TYPE_KEY = "type"; + + private double originX = 0; + private double originY = 0; + private double originZ = 0; + + private double scaleX = 1; + private double scaleY = 1; + private double scaleZ = 1; + + private double rotX = 0; + private double rotY = 0; + private double rotZ = 0; + + private double posX = 0; + private double posY = 0; + private double posZ = 0; + + public AffineTransform() {} + + public AffineTransform(AffineTransform t) { + setOrigin(t.getOrigin()); + setScale(t.getScale()); + setTranslate(t.getTranslation()); + setRotation(t.getRotation()); + } + + public void setOrigin(double[] origin) { + originX = origin[0]; + originY = origin[1]; + originZ = origin[2]; + } + + public void setScale(double[] scale) { + scaleX = scale[0]; + scaleY = scale[1]; + scaleZ = scale[2]; + } + + public void setTranslate(double[] translate) { + posX = translate[0]; + posY = translate[1]; + posZ = translate[2]; + } + + public void setRotation(double[] rotation) { + rotX = rotation[0]; + rotY = rotation[1]; + rotZ = rotation[2]; + } + + @Override + public String toString() { + return String.format("Scale: %f %f %f, Rot: %f %f %f, Pos: %f %f %f", scaleX, scaleY, scaleZ, rotX, rotY, rotZ, posX, posY, posZ); + } + + public boolean isIdentity() { + return scaleX==1 && scaleY==1 && scaleZ==1 && rotX==0 && rotY==0 && rotZ==0 && posX==0 && posY==0 && posZ==0; + } + + public double[] getTranslation() { + return new double[] {posX, posY, posZ}; + } + public double[] getScale() { + return new double[] {scaleX, scaleY, scaleZ}; + } + public double[] getRotation() { + return new double[] {rotX, rotY, rotZ}; + } + public double getRotationX() { + return rotX; + } + public double getRotationY() { + return rotY; + } + public double getRotationZ() { + return rotZ; + } + public double[] getOrigin() { + return new double[] {originX, originY, originZ}; + } + + public static AffineTransform getTranslation(double dx, double dy, double dz) { + AffineTransform t = new AffineTransform(); + t.posX = dx; + t.posY = dy; + t.posZ = dz; + + return t; + } + + public static AffineTransform getScale(double dx, double dy, double dz) { + AffineTransform t = new AffineTransform(); + t.scaleX = dx; + t.scaleY = dy; + t.scaleZ = dz; + + return t; + } + + public static AffineTransform getRotateX(double dx) { + AffineTransform t = new AffineTransform(); + t.rotX = dx; + return t; + } + public static AffineTransform getRotateY(double dx) { + AffineTransform t = new AffineTransform(); + t.rotY = dx; + return t; + } + public static AffineTransform getRotateZ(double dx) { + AffineTransform t = new AffineTransform(); + t.rotZ = dx; + return t; + } + + public static AffineTransform fromVTK(vtkTransform t) { + AffineTransform transform = new AffineTransform(); + transform.setOrigin(new double[]{0, 0, 0}); + transform.setRotation(t.GetOrientation()); + transform.setScale(t.GetScale()); + transform.setTranslate(t.GetPosition()); + + return transform; + } + + public vtkTransform toVTK(vtkTransform current) { + vtkTransform transform = new vtkTransform(); + transform.PostMultiply(); + transform.SetInput(current); + transform.Scale(scaleX, scaleY, scaleZ); + transform.Translate(-originX, -originY, -originZ); + transform.RotateY(rotY); + transform.RotateX(rotX); + transform.RotateZ(rotZ); + transform.Translate(originX, originY, originZ); + transform.Translate(posX, posY, posZ); + + return transform; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof AffineTransform) { + AffineTransform t = (AffineTransform) obj; + return posX == t.posX && posY == t.posY && posZ == t.posZ && scaleX == t.scaleX && scaleY == t.scaleY && scaleZ == t.scaleZ && rotX == t.rotX && rotY == t.rotY && rotZ == t.rotZ; + } + return super.equals(obj); + } + + public static AffineTransform fromGeometryDictionary(Dictionary g) { + AffineTransform t = new AffineTransform(); + if (g.isList(TRANSFORMS_KEY)) { + ListField transforms = g.getList(TRANSFORMS_KEY); + for (DefaultElement el : transforms.getListElements()) { + if (el instanceof Dictionary) { + Dictionary d = (Dictionary) el; + if (d.found(TYPE_KEY)) { + String type = d.lookup(TYPE_KEY); + switch (type) { + case TRANSLATE_KEY: + double[] translate = d.lookupDoubleArray(TRANSLATE_VEC_KEY); + t.setTranslate(translate); + break; + case ROTATE_KEY: + if (d.found(N1N2_KEY)) { + double[][] n1n2 = d.lookupDoubleMatrix(N1N2_KEY); + double[] n1 = n1n2[0]; + double[] n2 = n1n2[1]; + t.setRotation(new double[] {getRotX(n1, n2), getRotY(n1, n2), getRotZ(n1, n2)}); + } else if (d.found(ROLL_PITCH_YAW_KEY)) { + double[] rollPitchYaw = d.lookupDoubleArray(ROLL_PITCH_YAW_KEY); + double roll = rollPitchYaw[0]; + double pitch = rollPitchYaw[1]; + double yaw = rollPitchYaw[2]; + t.setRotation(new double[] { roll, pitch, yaw}); + } else if (d.found(YAW_PITCH_ROLL_KEY)) { + double[] yawPitchRoll = d.lookupDoubleArray(YAW_PITCH_ROLL_KEY); + double yaw = yawPitchRoll[0]; + double pitch = yawPitchRoll[1]; + double roll = yawPitchRoll[2]; + t.setRotation(new double[] { roll, pitch, yaw}); + } + break; + case SCALE_KEY: + double[] value = d.lookupDoubleArray(SCALE_VEC_KEY); + t.setScale(value); + break; + + default: + break; + } + } + } + } + } + return t; + } + + public ListField toDictionary() { + ListField transforms = new ListField(TRANSFORMS_KEY); + if (scaleX != 1 || scaleY != 1 || scaleZ != 1) { + Dictionary d = new Dictionary(""); + d.add(TYPE_KEY, SCALE_KEY); + d.add(SCALE_VEC_KEY, format(getScale())); + d.add(ABOUT_POINT_KEY, format(getOrigin())); + + transforms.add(d); + } + if (rotX != 0 || rotY != 0 || rotZ != 0) { + Dictionary d = new Dictionary(""); + d.add(TYPE_KEY, ROTATE_KEY); + d.add(ROLL_PITCH_YAW_KEY, format(getRotation())); + d.add(ABOUT_POINT_KEY, format(getOrigin())); + + transforms.add(d); + } + if (posX != 0 || posY != 0 || posZ != 0) { + Dictionary d = new Dictionary(""); + d.add(TYPE_KEY, TRANSLATE_KEY); + d.add(TRANSLATE_VEC_KEY, format(getTranslation())); + + transforms.add(d); + } + return transforms; + } + + private static final DecimalFormat formatter = new DecimalFormat("0.0##", new DecimalFormatSymbols(Locale.US)); + + private String[] format(double[] d) { + return new String[] { formatter.format(d[0]), formatter.format(d[1]), formatter.format(d[2])} ; + } + + private String getN1N2() { + Matrix3d R = getRotationMatrix(rotX, rotY, rotZ); + + Vector3d axis1 = new Vector3d(1, 0, 0); + Vector3d axis2 = new Vector3d(); + R.transform(axis1, axis2); + + StringBuffer sb = new StringBuffer("("); + sb.append("("); + sb.append(formatter.format(axis1.x) + " " + formatter.format(axis1.y) + " " + formatter.format(axis1.z) + " "); + sb.append(")"); + sb.append("("); + sb.append(formatter.format(axis2.x) + " " + formatter.format(axis2.y) + " " + formatter.format(axis2.z) + " "); + sb.append(")"); + sb.append(")"); + + return sb.toString(); + } + + public Matrix3d getRotationMatrix(double rotX, double rotY, double rotZ) { + + Matrix3d X = new Matrix3d(); + X.rotX(Math.toRadians(rotX)); + + Matrix3d Y = new Matrix3d(); + Y.rotY(Math.toRadians(rotY)); + + Matrix3d Z = new Matrix3d(); + Z.rotZ(Math.toRadians(rotZ)); + + Matrix3d R = new Matrix3d(); + R.mul(Y, X); + R.mul(Z, R); + + return R; + } + + public static double getRotX(double[] n1, double[] n2) { + Vector3d v1 = new Vector3d(n1); + Vector3d v2 = new Vector3d(n2); + v1.normalize(); + v2.normalize(); + Vector3d v1_yz = new Vector3d(0, v1.y, v1.z); + Vector3d v2_yz = new Vector3d(0, v2.y, v2.z); + + return Math.toDegrees(v1_yz.angle(v2_yz)); + } + + public static double getRotY(double[] n1, double[] n2) { + Vector3d v1 = new Vector3d(n1); + Vector3d v2 = new Vector3d(n2); + v1.normalize(); + v2.normalize(); + Vector3d v1_xz = new Vector3d(v1.x, 0, v1.z); + Vector3d v2_xz = new Vector3d(v2.x, 0, v2.z); + + return Math.toDegrees(v1_xz.angle(v2_xz)); + } + + public static double getRotZ(double[] n1, double[] n2) { + Vector3d v1 = new Vector3d(n1); + Vector3d v2 = new Vector3d(n2); + v1.normalize(); + v2.normalize(); + Vector3d v1_xy = new Vector3d(v1.x, v1.y, 0); + Vector3d v2_xy = new Vector3d(v2.x, v2.y, 0); + + return Math.toDegrees(v1_xy.angle(v2_xy)); + } +} diff --git a/src/eu/engys/core/project/geometry/stl/ImportIGES.java b/src/eu/engys/core/project/geometry/stl/ImportIGES.java new file mode 100644 index 0000000..a227909 --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/ImportIGES.java @@ -0,0 +1,124 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry.stl; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.loadEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.printHeader; +import static eu.engys.core.OpenFOAMEnvironment.printVariables; +import static eu.engys.core.project.openFOAMProject.LOG; +import static eu.engys.util.OpenFOAMCommands.CAD_TOOL; + +import java.io.File; +import java.nio.file.Paths; + +import eu.engys.core.controller.ScriptBuilder; +import eu.engys.core.controller.actions.AbstractRunCommand; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.ExecutorHook; +import eu.engys.core.executor.ExecutorListener.ExecutorState; +import eu.engys.core.executor.ExecutorMonitor; +import eu.engys.core.executor.ExecutorTerminal; +import eu.engys.core.executor.TerminalExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.util.IOUtils; +import eu.engys.util.Util; + +public class ImportIGES extends AbstractRunCommand { + + public static final String ACTION_NAME = "Import IGES"; + public static final String LOG_NAME = "importIGES.log"; + + private static final String IMPORT_IGES_RUN = "importIGES.run"; + private static final String IMPORT_IGES_BAT = "importIGES.bat"; + + private File[] input; + private File[] output; + + private boolean split; + private double precision; + private File logFile; + private Runnable loadSTLRunnable; + + public ImportIGES(Model model, Runnable loadSTLRunnable, File[] input, File[] output, boolean split, double precision) { + super(model, null); + this.input = input; + this.output = output; + this.split = split; + this.precision = precision; + this.loadSTLRunnable = loadSTLRunnable; + this.logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, LOG_NAME).toFile(); + } + + @Override + public void beforeExecute() { + IOUtils.clearFile(logFile); + } + + @Override + public void executeClient() { + File script = getScript(); + + ExecutorTerminal terminal = new TerminalExecutorMonitor(logFile); + ExecutorMonitor monitor = new ExecutorMonitor(); + monitor.addHook(ExecutorState.FINISH, new FinishHook()); + + this.executor = Executor.script(script).description(ACTION_NAME).inFolder(input[0].getParentFile()).env(getEnvironment(model, LOG_NAME)).inTerminal(terminal).withMonitors(monitor); + executor.exec(); + } + + private File getScript() { + File file = new File(model.getProject().getBaseDir(), Util.isWindows() ? IMPORT_IGES_BAT : IMPORT_IGES_RUN); + ScriptBuilder sb = new ScriptBuilder(); + writeScript(sb); + + IOUtils.writeLinesToFile(file, sb.getLines()); + file.setExecutable(true); + return file; + } + + private void writeScript(ScriptBuilder sb) { + printHeader(sb, ACTION_NAME.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + writeCommand(sb); + } + + private void writeCommand(ScriptBuilder sb) { + for (int i = 0; i < input.length; i++) { + sb.append(CAD_TOOL(split, precision, input[i], output[i])); + } + } + + private class FinishHook implements ExecutorHook { + + @Override + public void run(ExecutorMonitor monitor) { + loadSTLRunnable.run(); + } + } + +} diff --git a/src/eu/engys/core/project/geometry/stl/NastranReader.java b/src/eu/engys/core/project/geometry/stl/NastranReader.java new file mode 100644 index 0000000..8a37cbd --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/NastranReader.java @@ -0,0 +1,105 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.stl; + +public class NastranReader { + + /* +Step 1 Indexing the BDF file. +The first thing I do is read the BDF file once and indexing every BDF +card in the file. The result is a list with entries (line_id, card +label, card format (either comma, small (8 chars) or large (16 +chars)). I also return an the file contents as a list of strings so we +don't need the file anymore. + +Step 2 Parsing the card information +In this step I start digesting the card data based on the result from +the indexing routine. The first thing I do is start looking for +coordinate system information. I need this in case nodes are defined +in a local coordinate system. I translate all information (including +results like displacement fields) to the global coordinate system; +maybe not the best, but I am not sure how vtk/paraview handles local +coordinate systems). +Next I check if I have a handler for all cells in the BDF (CQUAD4, +CTRIA3 etc.). If not I issue a warning. Handlers are simple pieces of +Python code that receive a block of BDF text for a single card, digest +the information contained inside and returns an object representing +the card (for example a vtkCell instance). + +Next I parse all the grid cards translating to the global coordinate +system if necessary. The VTK classes you need are +- vtkPoints, vtkCellArray, vtkUnstructuredGrid +- vtkQuad, vtkTria etc. Note that you need only one instance of these; +they serve primarily to provide you with information like its element +type id, and the number of nodes for the element. You need this to +fill the cell datastructures later. You can ofcourse hardcode this +information directly, but I don't recommend this +- vtkIntArray, vtkFloatArray etc. for storing results, or any kind of +other information; for example I typically store the original cell and +grid identification numbers, property/material id and the thickness +- vtkXMLUnstructuredGridWriter (if you want to export to vtu) + +A typical (simple) code structure would be: + +points = vtkPoints() +cells = vtkCellArray() +grid = vtkUnstructuredGrid() + +Fill the points with points.InsertNextPoint(..) or similar +Fill the cells with cells.InsertNextCell(..) or grid.InsertNextCell(..) + +Assign points and possibly cells to the grid: + +grid.SetPoints(points) +grid.SetCells(cells) + +# Create some data +displacements = vtkFloatArray() +displacements.SetName('displacements) +displacements.SetNumberOfComponents(3) +Fill with displacement information + +# Assign the displacement data to the grid +grid.GetPointData().AddArray(displacements) + +A final remark. By far the hardest part is to properly parse the BDF +file. Some of the gotchas: +- Properly catching line termination in case of long formatted lines +- Parsing cards with variable length (like MPC cards) +- Parsing the unconventional floating point representation (e.g. 1.0-1 +instead of 1.0e-1) +- Handling include statements in different sections of the file +- Detecting card start and end points +etc. + +I hope this helps a little, feel free to ask more questions. + +Regards, + +Marco + */ +} diff --git a/src/eu/engys/core/project/geometry/stl/RemoveDuplicates.java b/src/eu/engys/core/project/geometry/stl/RemoveDuplicates.java new file mode 100644 index 0000000..0d66ae8 --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/RemoveDuplicates.java @@ -0,0 +1,162 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry.stl; + +import java.util.Arrays; + +import vtk.vtkCell; +import vtk.vtkCellArray; +import vtk.vtkIdList; +import vtk.vtkMergePoints; +import vtk.vtkPoints; +import vtk.vtkPolyData; +import vtk.vtkTriangle; + +public class RemoveDuplicates { + + private vtkPolyData dataset; + private vtkMergePoints PointsLocator; + private vtkMergePoints CellsLocator; + + public RemoveDuplicates(vtkPolyData dataset) { + this.dataset = dataset; + this.PointsLocator = new vtkMergePoints(); + this.CellsLocator = new vtkMergePoints(); + } + + public vtkPolyData execute() { + vtkPolyData input = dataset; + vtkPolyData output = new vtkPolyData(); + + if (input.GetNumberOfCells() == 0) + { + // set up a ugrid with same data arrays as input, but + // no points, cells or data. + output.Allocate(1, 0); +// output.GetPointData().CopyAllocate(input.GetPointData(), 0, 0); +// output.GetCellData().CopyAllocate(input.GetCellData(), 0, 0); + vtkPoints pts = new vtkPoints(); + output.SetPoints(pts); + pts.Delete(); + return output; + } + +// output.GetPointData().CopyAllocate(input.GetPointData(), 0, 0); +// output.GetCellData().PassData(input.GetCellData()); + + // First, create a new points array that eliminate duplicate points. + // Also create a mapping from the old point id to the new. + vtkPoints newPts = new vtkPoints(); + int num = input.GetNumberOfPoints(); + int newId; + int[] ptMap = new int[num]; + double[] pt = new double[3]; + + this.PointsLocator.InitPointInsertion(newPts, input.GetBounds(), num); + +// int progressStep = num / 100; +// if (progressStep == 0) +// { +// progressStep = 1; +// } + for (int id = 0; id < num; ++id) + { +// if (id % progressStep == 0) +// { +// this.UpdateProgress(0.8*((float)id/num)); +// } + input.GetPoint(id, pt); + if ( (newId = this.PointsLocator.IsInsertedPoint(pt)) < 0) + { + newId = this.PointsLocator.InsertNextPoint(pt); + output.GetPointData().CopyData(input.GetPointData(),id,newId); + } + ptMap[id] = newId; + } + output.SetPoints(newPts); + newPts.Delete(); + + + // New copy the cells. + int newCenterId; + vtkPoints newCenterPts = new vtkPoints(); + vtkIdList cellPoints = new vtkIdList(); + num = input.GetNumberOfCells(); +// output.Allocate(num, 0); + + this.CellsLocator.InitPointInsertion(newCenterPts, input.GetBounds(), num); + + vtkCellArray cells = new vtkCellArray(); + output.SetPolys(cells); + + System.out.println("RemoveDuplicates.execute() " + output.GetNumberOfCells()); + + for (int id = 0; id < num; ++id) + { +// if (id % progressStep == 0) +// { +// this.UpdateProgress(0.8+0.2*((float)id/num)); +// } +// input.GetCell(id).GetParametricCenter(id0); + + vtkCell cell = input.GetCell(id); + + if (cell instanceof vtkTriangle) { + vtkTriangle tri = (vtkTriangle) cell; + vtkPoints verices = tri.GetPoints(); + double[] center = new double[3]; + tri.TriangleCenter(verices.GetPoint(0), verices.GetPoint(1), verices.GetPoint(2), center); + + newCenterId = this.CellsLocator.IsInsertedPoint(center); + System.out.println("RemoveDuplicates.execute() center: " + Arrays.toString(center) + ", id: " + newCenterId); + if ( newCenterId < 0) + { + newCenterId = this.CellsLocator.InsertNextPoint(center); + + input.GetCellPoints(id, cellPoints); + for (int i=0; i < cellPoints.GetNumberOfIds(); i++) + { + int cellPtId = cellPoints.GetId(i); + newId = ptMap[cellPtId]; + cellPoints.SetId(i, newId); + } + cells.InsertNextCell(cell); + } else { + System.err.println("Duplicated!"); + } + } else { + System.err.println("Cell isn't a TRIANGLE"); + } + } + + output.SetPolys(cells); + +// delete [] ptMap; + cellPoints.Delete(); + output.Squeeze(); + return output; + } +} diff --git a/src/eu/engys/core/project/geometry/stl/STLJoiner.java b/src/eu/engys/core/project/geometry/stl/STLJoiner.java new file mode 100644 index 0000000..abeaf41 --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/STLJoiner.java @@ -0,0 +1,122 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.stl; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import eu.engys.util.progress.ProgressMonitor; + +public class STLJoiner implements Runnable { + + private final ProgressMonitor monitor; + + private BufferedWriter flatWriter = null; + + private int lineCounter = 0; + + private File destination; + private List children; + + public STLJoiner(File destination, List children, ProgressMonitor monitor) { + this.destination = destination; + this.children = children; + this.monitor = monitor; + } + + @Override + public void run() { + try { + joinFiles(); + } catch (Exception e) { + monitor.error(e.getMessage()); + } finally { + } + } + + public void joinFiles() throws Exception { + monitor.setIndeterminate(true); + String line = null; + try { + flatWriter = new BufferedWriter(new FileWriter(destination)); + for (File child : children) { + monitor.info("Copying " + child.getAbsolutePath()); + try (BufferedReader reader = new BufferedReader(new FileReader(child), 2000);) { + if (reader.ready()) { + while ((line = reader.readLine()) != null && !line.isEmpty()) { + writeln(line); + increaseCounter(); + } + } + } catch (Exception e) { + + } + } + } finally { + if (flatWriter != null) + flatWriter.close(); + } + } + + private void writeln(String string) throws IOException { + if (flatWriter != null) + flatWriter.write(string + "\n"); + } + + + protected void increaseCounter() { + lineCounter++; + if (lineCounter % 30000 == 0) + monitor.setCurrent(null, lineCounter); + } + + public int count(File file) throws IOException { + InputStream is = new BufferedInputStream(new FileInputStream(file)); + try { + byte[] c = new byte[1024]; + int count = 0; + int readChars = 0; + while ((readChars = is.read(c)) != -1) { + for (int i = 0; i < readChars; ++i) { + if (c[i] == '\n') + ++count; + } + } + return count; + } finally { + is.close(); + } + } +} diff --git a/src/eu/engys/core/project/geometry/stl/STLManager.java b/src/eu/engys/core/project/geometry/stl/STLManager.java new file mode 100644 index 0000000..ec8c89b --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/STLManager.java @@ -0,0 +1,76 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.stl; + +import java.io.File; + +import javax.inject.Inject; + +import org.apache.commons.io.FilenameUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.constant.TriSurfaceFolder; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.util.progress.ProgressMonitor; + +public class STLManager { + + public static final String COPY_OF_PREFIX = "CopyOf"; + + private static final Logger logger = LoggerFactory.getLogger(STLManager.class); + + private ProgressMonitor monitor; + private TriSurfaceFolder triSurface; + private Model model; + + @Inject + public STLManager(Model model, ProgressMonitor monitor) { + this.monitor = monitor; + this.model = model; + this.triSurface = model.getProject().getConstantFolder().getTriSurface(); + } + + private Stl loadFromTriSurface(String fileName) { + Dictionary g = new Dictionary(fileName, Surface.stl); + g.setName(fileName); + g.add("name", FilenameUtils.removeExtension(fileName)); + + Stl stl = (Stl) model.getGeometry().getFactory().loadSurface(g, model, monitor); + return stl; + } + + public Stl copyAndLoadFile(File file, String name, boolean overwrite) { + triSurface.getFileManager().copyHere(file, name, overwrite); + return loadFromTriSurface(name); + } + + +} diff --git a/src/eu/engys/core/project/geometry/stl/STLReader.java b/src/eu/engys/core/project/geometry/stl/STLReader.java new file mode 100644 index 0000000..c988c29 --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/STLReader.java @@ -0,0 +1,470 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.stl; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; + +import javax.vecmath.Point3f; +import javax.vecmath.Vector3f; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Level; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkCleanPolyData; +import vtk.vtkPolyData; +import vtk.vtkSTLReader; +import eu.engys.core.LoggerUtil; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.util.TempFolder; +import eu.engys.util.Util; +import eu.engys.util.VTKSettings; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.progress.SilentMonitor; +import eu.engys.util.ui.ExecUtil; + +public class STLReader implements Runnable { + + private static final Logger logger = LoggerFactory.getLogger(STLReader.class); + + private static final long CHAR_PER_ROW = 30; + private static final int SIZE = 8192; + private static final int NP = 4; + + private final File sourceFile; + private final String fileName; + private final File tmp; + private final ProgressMonitor monitor; + + private BufferedReader reader = null; + private PrintWriter regionWriter = null; + + private int lineCounter = 0; + private int counter = 0; + private boolean Ascii; + + private List solids; + private List regionFiles; + + private ExecutorService executor; + + public STLReader(File source, ProgressMonitor monitor) { + this.sourceFile = source; + this.fileName = source.getName(); + this.monitor = monitor; + this.solids = new ArrayList(); + this.regionFiles = new ArrayList<>(); + this.tmp = TempFolder.get(STLReader.class.getSimpleName()); + } + + @Override + public void run() { + try { + initMonitor(); + initFilesIO(); + readFile(); + } catch (Exception e) { + logAnError(e); + } finally { + monitor.setCurrent(null, monitor.getTotal()); + FileUtils.deleteQuietly(tmp); + } + } + + void initMonitor() throws IOException { + int totalLines = count(sourceFile); + monitor.setTotal(totalLines); + monitor.setIndeterminate(false); + } + + void initFilesIO() throws IOException { + reader = new BufferedReader(new FileReader(sourceFile), SIZE); + } + + void logAnError(Exception e) { + monitor.error(e.getMessage(), 1); + logger.error("Error reading STL file ", e); + solids.clear(); + } + + void readFile() throws Exception { + if (reader.ready()) { + String line = reader.readLine(); + detectType(line); + + try { + executor = ExecUtil.createParallelExecutor(NP); + if (isAscii()) { + logger.info("Read STL " + sourceFile.getName() + " [ASCII]"); + monitor.info(sourceFile.getName() + " [ASCII]", 2); + + parseLine(line); + while ((line = reader.readLine()) != null && !line.isEmpty()) { + parseLine(line); + increaseCounter(); + } + + } else { + logger.info("Read STL " + sourceFile.getName() + " [BINARY]"); + monitor.info(sourceFile.getName() + " [BINARY]", 2); + readBinary(); + } + ExecUtil.awaitTermination(executor); + } finally { + closeFilesIO(); + } + } + } + + private void increaseCounter() { + lineCounter++; + if (lineCounter % 50000 == 0) + monitor.setCurrent(null, lineCounter); + } + + void closeFilesIO() throws IOException { + if (reader != null) + reader.close(); + if (regionWriter != null) + regionWriter.close(); + + reader = null; + regionWriter = null; + } + + private void detectType(String line) { + if (line.startsWith("solid")) { + this.setAscii(true); + } else { + // If the first word is not "solid" then we consider the file is binary + // Can give us problems if the comment of the binary file begins by "solid" + this.setAscii(false); + } + } + + private String regionName = ""; + private File regionFile; + private Solid solid; + + private String parseLine(String line) throws IOException { + if (line.startsWith("solid")) { + setValidRegionName(line); + + newRegionFile(); + + startRegionWriter(); + } else if (line.startsWith("endsolid")) { + flushRegionWriter(); + } else { + writeln(line); + } + + return regionName; + } + + private File newRegionFile() { + regionFile = new File(tmp, fileName + "_" + regionName); + regionFiles.add(regionFile); + solid = new Solid(regionName); + solids.add(solid); + return regionFile; + } + + private void startRegionWriter() throws IOException { + regionWriter = new PrintWriter(new FileWriter(regionFile)); + writeln("solid " + regionName); + } + + private void writeln(String string) throws IOException { + if (regionWriter != null) + regionWriter.write(string.replace(',', '.') + "\n"); + } + + private void write(String string) throws IOException { + if (regionWriter != null) + regionWriter.write(string.replace(',', '.')); + } + + private void flushRegionWriter() throws IOException { + write("endsolid " + regionName); + if (regionWriter != null) { + regionWriter.flush(); + regionWriter.close(); + regionWriter = null; + } + + executor.submit(new SolidReader(regionFile, solid)); + + regionFile = null; + } + + class SolidReader implements Runnable { + + private File regionFile; + private Solid solid; + + public SolidReader(File regionFile, Solid solid) { + this.regionFile = regionFile; + this.solid = solid; + } + + @Override + public void run() { + if (VTKSettings.librariesAreLoaded()) { + vtkSTLReader reader = new vtkSTLReader(); + reader.SetFileName(regionFile.getAbsolutePath()); + reader.Update(); + + this.solid.setDataSet(reader.GetOutput()); + + reader.Delete(); + } + this.regionFile.delete(); + + } + } + +// public static vtkPolyData repairDataSet(vtkPolyData dataset) { +// System.out.println("STLReader.repairDataSet() POINTS: " + dataset.GetNumberOfPoints()); +// System.out.println("STLReader.repairDataSet() LINES: " + dataset.GetNumberOfLines()); +// System.out.println("STLReader.repairDataSet() CELLS: " + dataset.GetNumberOfCells()); +// +// vtkPolyData pippo = new RemoveDuplicates(dataset).execute(); +// +// System.out.println("STLReader.repairDataSet() POINTS: " + repaired.GetNumberOfPoints()); +// System.out.println("STLReader.repairDataSet() LINES: " + repaired.GetNumberOfLines()); +// System.out.println("STLReader.repairDataSet() CELLS: " + repaired.GetNumberOfCells()); +// return pippo; +// } + + public static vtkPolyData repairDataSet(vtkPolyData dataset) { + System.out.println("STLReader.repairDataSet() POINTS: " + dataset.GetNumberOfPoints()); + System.out.println("STLReader.repairDataSet() LINES: " + dataset.GetNumberOfLines()); + System.out.println("STLReader.repairDataSet() CELLS: " + dataset.GetNumberOfCells()); + + vtkCleanPolyData clean = new vtkCleanPolyData(); + // clean.ConvertLinesToPointsOff(); //def: on + // clean.ConvertPolysToLinesOff(); //def: on + // clean.ConvertStripsToPolysOff(); //def: on + // clean.PieceInvariantOff(); //def: on + // clean.PointMergingOff(); //def: on + // clean.SetAbsoluteTolerance(0); //def: 1.0 + // clean.SetTolerance(0);//def: 0.0 + // clean.ToleranceIsAbsoluteOn(); //def: off + clean.SetInputData(dataset); + clean.Update(); + + vtkPolyData repaired = clean.GetOutput(); + System.out.println("STLReader.repairDataSet() POINTS: " + repaired.GetNumberOfPoints()); + System.out.println("STLReader.repairDataSet() LINES: " + repaired.GetNumberOfLines()); + System.out.println("STLReader.repairDataSet() CELLS: " + repaired.GetNumberOfCells()); + + return repaired; + } + + private void setValidRegionName(String line) { + int startIndex = line.indexOf(" "); + if (startIndex < 0) { + regionName = "solid" + counter++; + logger.info("- " + "Found empty name. Set to " + regionName, 1); + return; + } + String name = line.substring(startIndex).trim(); + if (name.isEmpty()) { + regionName = "solid" + counter++; + logger.info("- " + "Found empty name. Set to " + regionName, 1); + return; + } + regionName = Util.replaceForbiddenCharacters(name); + regionName = uniqueNameAmongSolids(regionName); + if (regionName.equals(name)) { + logger.info("- " + regionName + " found", 1); + } else { + logger.info(String.format("- " + "Found invalid name \"%s\". Set to \"%s\".", name, regionName), 1); + } + } + + private String uniqueNameAmongSolids(String name) { + for (Solid solid : solids) { + if (solid.getName().equals(name)) { + return uniqueNameAmongSolids(name + counter++); + } + } + return name; + } + + private int count(File file) throws IOException { + int i = (int) (file.length() / CHAR_PER_ROW); + return i; + } + + private void readBinary() throws Exception { + ByteBuffer dataBuffer; // For reading in the correct endian + byte[] Info = new byte[80]; // Header data + byte[] Array_number = new byte[4]; // Holds the number of faces + byte[] Temp_Info; // Intermediate array + + int Number_faces; // First info (after the header) on the file + + FileInputStream data = new FileInputStream(sourceFile); + + // First 80 bytes aren't important + if (80 != data.read(Info)) { + // File is incorrect + // System.out.println("Format Error: 80 bytes expected"); + data.close(); + throw new Exception("Incorrect Format"); + } else { + // We must first read the number of faces -> 4 bytes int + // It depends on the endian so.. + + data.read(Array_number); // We get the 4 bytes + dataBuffer = ByteBuffer.wrap(Array_number); // ByteBuffer for reading correctly the int + dataBuffer.order(ByteOrder.nativeOrder()); // Set the right order + + Number_faces = dataBuffer.getInt(); + + Temp_Info = new byte[50 * Number_faces]; // Each face has 50 bytes of data + + data.read(Temp_Info); // We get the rest of the file + + dataBuffer = ByteBuffer.wrap(Temp_Info); // Now we have all the data in this ByteBuffer + dataBuffer.order(ByteOrder.nativeOrder()); + + // We can create that array directly as we know how big it's going to be + // coordArray = new Point3f[Number_faces * 3]; // Each face has 3 vertices + // normArray = new Vector3f[Number_faces]; + + setValidRegionName(""); + + // we create an ascii file -> an stl surface + + newRegionFile(); + + startRegionWriter(); + + int[] stripCounts = new int[Number_faces]; + for (int i = 0; i < Number_faces; i++) { + stripCounts[i] = 3; + try { + readFacetB(dataBuffer, i); + // After each facet there are 2 bytes without information + // In the last iteration we don't have to skip those bytes.. + if (i != Number_faces - 1) { + dataBuffer.get(); + dataBuffer.get(); + } + } catch (IOException e) { + // Quit + System.out.println("Format Error: iteration number " + i); + data.close(); + throw new Exception("Incorrect Format"); + } + } + flushRegionWriter(); + } + + data.close(); + } + + private void readFacetB(ByteBuffer in, int index) throws IOException { + Vector3f normal = new Vector3f(in.getFloat(), in.getFloat(), in.getFloat()); + Point3f vertex1 = new Point3f(in.getFloat(), in.getFloat(), in.getFloat()); + Point3f vertex2 = new Point3f(in.getFloat(), in.getFloat(), in.getFloat()); + Point3f vertex3 = new Point3f(in.getFloat(), in.getFloat(), in.getFloat()); + + /* + * facet normal -1 0 0 + * outer loop + * vertex 5 15 10 + * vertex 5 5 10 + * vertex 5 15 15 + * endloop + * endfacet + */ + writeln(String.format("facet normal %f %f %f", normal.x, normal.y, normal.z)); + writeln(" outer loop"); + writeln(String.format(" vertex %f %f %f", vertex1.x, vertex1.y, vertex1.z)); + writeln(String.format(" vertex %f %f %f", vertex2.x, vertex2.y, vertex2.z)); + writeln(String.format(" vertex %f %f %f", vertex3.x, vertex3.y, vertex3.z)); + writeln(" endloop"); + writeln("endfacet"); + } + + public List getSolids() { + return solids; + } + + public boolean isAscii() { + return this.Ascii; + } + + public void setAscii(boolean b) { + this.Ascii = b; + } + + public static void main(String[] args) { + LoggerUtil.initTestLogger(Level.DEBUG); + VTKSettings.LoadAllNativeLibraries(); + new STLReader(new File("/home/stefano/ENGYS/examples/STL/plateExchanger.stl"), new SilentMonitor()).run(); + +// long fileLenght = 40 * 1024 * 1024; +// int i = (int) (fileLenght / CHAR_PER_ROW); +// System.out.println(fileLenght + " Byte -> " + i + " rows"); + +// System.out.println("**************"); +// System.out.println("* SERIAL *"); +// System.out.println("**************"); +// NP = 1; +// for (int i=0; i<10; i++) { +// long start = System.currentTimeMillis(); +// new STLReader(new File("/home/stefano/ENGYS/examples/STL/Bravo/car.stl"), new SilentMonitor()).run(); +// System.err.println("Time: " + (System.currentTimeMillis() - start)/1000.0 ); +// } +// NP = 4; +// System.out.println("**************"); +// System.out.println("* PARALLEL "+NP+" *"); +// System.out.println("**************"); +// for (int i=0; i<10; i++) { +// long start = System.currentTimeMillis(); +// new STLReader(new File("/home/stefano/ENGYS/examples/STL/Bravo/car.stl"), new SilentMonitor()).run(); +// System.err.println("Time: " + (System.currentTimeMillis() - start)/1000.0 ); +// } + } +} diff --git a/src/eu/engys/core/project/geometry/stl/STLReplacer.java b/src/eu/engys/core/project/geometry/stl/STLReplacer.java new file mode 100644 index 0000000..4a8b4bd --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/STLReplacer.java @@ -0,0 +1,204 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.stl; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; + +import eu.engys.util.Util; +import eu.engys.util.progress.ProgressMonitor; + +public class STLReplacer implements Runnable { + + private final ProgressMonitor monitor; + + private BufferedReader reader = null; + private BufferedWriter flatWriter = null; + + private int lineCounter = 0; + + private File source; + private String solidName; + private File replacement; + + public STLReplacer(File source, String name, File replacement, ProgressMonitor monitor) { + this.source = source; + this.solidName = name; + this.replacement = replacement; + this.monitor = monitor; + } + + @Override + public void run() { + try { + replaceFile(); + } catch (Exception e) { + monitor.error(e.getMessage()); + } finally { + } + } + + public void replaceFile() throws Exception { + String sourceName = source.getName(); + File source_org = new File(source.getParent(), sourceName + ".org"); + source.renameTo(source_org); + File replacedFile = new File(source.getParent(), sourceName); + monitor.info(source.getAbsolutePath() + " -> " + source_org.getAbsolutePath()); + + int totalLines = count(source_org); + monitor.setTotal(totalLines); + monitor.setIndeterminate(false); + monitor.info("Reading " + source.getAbsolutePath()); + + String line = null; + try { + reader = new BufferedReader(new FileReader(source_org), 2000); + flatWriter = new BufferedWriter(new FileWriter(replacedFile)); + + // writeln("solid "+flattenedFile.getName()); + if (reader.ready()) { + while ((line = reader.readLine()) != null && !line.isEmpty()) { + exceptionIfLineIsntSolid(lineCounter, line); + parseLine(line); + increaseCounter(); + } + } + // write("endsolid "+flattenedFile.getName()); + } finally { + if (reader != null) + reader.close(); + if (flatWriter != null) + flatWriter.close(); + } + } + + private String regionName = ""; + + private boolean replacing; + + protected void parseLine(String line) throws IOException { + if (line.startsWith("solid " + solidName)) { + replacing = true; + writeReplacement(); + return; + } else if (line.startsWith("endsolid") && replacing) { + replacing = false; + } else if (!replacing) { + // System.out.println("STLReplacer.parseLine() COPY: "+line); + writeln(line); + } + } + + private void writeReplacement() throws FileNotFoundException, IOException { + String line = null; + int lineCounter = 0; + try (BufferedReader reader = new BufferedReader(new FileReader(replacement), 2000)) { + writeln("solid " + solidName); + if (reader.ready()) { + while ((line = reader.readLine()) != null && !line.isEmpty()) { + //exceptionIfLineIsntSolid(lineCounter, line); + // System.out.println("STLReplacer.parseLine() REPLACE: "+line); + if (line.startsWith("solid") || line.startsWith("endsolid")) + continue; + writeln(line); + lineCounter++; + } + } + write("endsolid " + solidName); + } + } + + private void writeln(String string) throws IOException { + if (flatWriter != null) + flatWriter.write(string + "\n"); + } + + private void write(String string) throws IOException { + if (flatWriter != null) + flatWriter.write(string); + } + + protected void increaseCounter() { + lineCounter++; + if (lineCounter % 30000 == 0) + monitor.setCurrent(null, lineCounter); + } + + protected void exceptionIfLineIsntSolid(int counter, String line) { + if (counter == 0 && !line.startsWith("solid")) + throw new IllegalArgumentException("Binary STL format not supported"); + } + + private int counter = 0; + + public void setValidRegionName(String line) { + int startIndex = line.indexOf(" "); + if (startIndex < 0) { + regionName = "solid" + counter++; + monitor.info(" - " + "Found empty name. Set to " + regionName); + return; + } + String name = line.substring(startIndex).trim(); + if (name.isEmpty()) { + regionName = "solid" + counter++; + monitor.info(" - " + "Found empty name. Set to " + regionName); + return; + } + regionName = Util.replaceForbiddenCharacters(name); + if (regionName.equals(name)) { + monitor.info(" - " + regionName + " found"); + } else { + monitor.info(String.format(" - " + "Found invalid name \"%s\". Set to \"%s\".", name, regionName)); + } + } + + public int count(File file) throws IOException { + InputStream is = new BufferedInputStream(new FileInputStream(file)); + try { + byte[] c = new byte[1024]; + int count = 0; + int readChars = 0; + while ((readChars = is.read(c)) != -1) { + for (int i = 0; i < readChars; ++i) { + if (c[i] == '\n') + ++count; + } + } + return count; + } finally { + is.close(); + } + } +} diff --git a/src/eu/engys/core/project/geometry/stl/STLWriter.java b/src/eu/engys/core/project/geometry/stl/STLWriter.java new file mode 100644 index 0000000..a8c020f --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/STLWriter.java @@ -0,0 +1,132 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.stl; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.util.TempFolder; +import eu.engys.util.VTKSettings; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; + +public class STLWriter implements Runnable { + + private static final Logger logger = LoggerFactory.getLogger(STLWriter.class); + private static final int SIZE = 8192; + + private final File targetFile; + private final String fileName; + private final File tmp; + private final ProgressMonitor monitor; + + private Stl stl; + + public STLWriter(File target, Stl stl, ProgressMonitor monitor) { + this.targetFile = target; + this.stl = stl; + this.fileName = target.getName(); + this.monitor = monitor; + this.tmp = TempFolder.get(STLWriter.class.getSimpleName()); + } + + @Override + public void run() { + try { + initMonitor(); + writeFile(); + } catch (Exception e) { + logAnError(e); + } finally { + monitor.setCurrent(null, monitor.getTotal()); + FileUtils.deleteQuietly(tmp); + } + } + + void initMonitor() throws IOException { + int totalLines = stl.getSolids().length; + monitor.setTotal(totalLines); + monitor.setCurrent(null, 0); + monitor.setIndeterminate(false); + } + + void logAnError(Exception e) { + monitor.error(e.getMessage(), 1); + logger.error("Error writing STL file ", e); + } + + void writeFile() throws Exception { + monitor.info(targetFile.getName() + " [ASCII]", 2); + logger.info("Write STL " + targetFile.getName() + " [ASCII]"); + + if (VTKSettings.librariesAreLoaded()) { + try (FileWriter writer = new FileWriter(targetFile)) { + Solid[] solids = stl.getSolids(); + SolidWriter[] solidWriters = new SolidWriter[solids.length]; + for (int i = 0; i < solidWriters.length; i++) { + solidWriters[i] = new SolidWriter(tmp, fileName, solids[i]); + } + + ExecUtil.execSerial(solidWriters); + + for (SolidWriter solidWriter : solidWriters) { + try (BufferedReader reader = new BufferedReader(new FileReader(solidWriter.getFile()))) { + String line = ""; + while ((line = reader.readLine()) != null) { + if (line.startsWith("solid")) { + writer.write("solid " + solidWriter.getSolid().getName() + "\n"); + } else if (line.startsWith("endsolid")) { + writer.write("endsolid " + solidWriter.getSolid().getName() + "\n"); + } else { + writer.write(line + "\n"); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + monitor.setCurrent(null, monitor.getCurrent()); + } + writer.flush(); + } finally { + + } + } else { + logger.info("Write STL SKIPPED: no 3D"); + } + + } + +} diff --git a/src/eu/engys/core/project/geometry/stl/SolidWriter.java b/src/eu/engys/core/project/geometry/stl/SolidWriter.java new file mode 100644 index 0000000..549dd73 --- /dev/null +++ b/src/eu/engys/core/project/geometry/stl/SolidWriter.java @@ -0,0 +1,91 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry.stl; + +import java.io.File; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkSTLWriter; +import vtk.vtkTransform; +import vtk.vtkTransformFilter; +import eu.engys.core.project.geometry.TransfromMode; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.util.Util; + +public class SolidWriter implements Runnable { + + private static final Logger logger = LoggerFactory.getLogger(SolidWriter.class); + + private Solid solid; + private File file; + private String fileName; + private File tmp; + + public SolidWriter(File tmp, String fileName, Solid solid) { + this.tmp = tmp; + this.fileName = fileName; + this.solid = solid; + } + + public File getFile() { + return file; + } + + public Solid getSolid() { + return solid; + } + + @Override + public void run() { + String regionName = solid.getName(); + logger.info("- " + regionName + " written", 1); + + this.file = new File(tmp, fileName + "_" + Util.generateID()); + + if (solid.getTransformMode() == TransfromMode.TO_FILE) { + vtkTransform transform = solid.getTransformation().toVTK(new vtkTransform()); + + vtkTransformFilter tFilter = new vtkTransformFilter(); + tFilter.SetTransform(transform); + tFilter.SetInputData(solid.getDataSet()); + tFilter.Update(); + + vtkSTLWriter write = new vtkSTLWriter(); + // write.SetFileTypeToASCII(); + write.SetFileName(file.getAbsolutePath()); + write.SetInputData(tFilter.GetOutput()); + write.Write(); + } else { + vtkSTLWriter write = new vtkSTLWriter(); + // write.SetFileTypeToASCII(); + write.SetFileName(file.getAbsolutePath()); + write.SetInputData(solid.getDataSet()); + write.Write(); + } + } +} diff --git a/src/eu/engys/core/project/geometry/surface/BaseSurface.java b/src/eu/engys/core/project/geometry/surface/BaseSurface.java new file mode 100644 index 0000000..76153c0 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/BaseSurface.java @@ -0,0 +1,78 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import eu.engys.core.project.geometry.Surface; + +public abstract class BaseSurface extends Surface { + + private static final String _REGION0 = "_region0"; + + public BaseSurface(String name) { + super(name); + } + + @Override + public String getPatchName() { + return isAppendRegionName() ? getName() + _REGION0 : getName(); + } + + @Override + public boolean hasRegions() { + return false; + } + + @Override + public Region[] getRegions() { + return new Region[0]; + } + + @Override + public boolean isSingleton() { + return true; + } + + @Override + public boolean hasLayers() { + return true; + } + + @Override + public boolean hasSurfaceRefinement() { + return true; + } + + @Override + public boolean hasVolumeRefinement() { + return true; + } + + @Override + public boolean hasZones() { + return true; + } +} diff --git a/src/eu/engys/core/project/geometry/surface/Box.java b/src/eu/engys/core/project/geometry/surface/Box.java new file mode 100644 index 0000000..f9b1f06 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/Box.java @@ -0,0 +1,84 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import vtk.vtkCubeSource; +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; + +public class Box extends BaseSurface { + + /** + * @deprecated Use GeometryFactory!! + */ + @Deprecated + public Box(String name) { + super(name); + Dictionary geometryDictionary = new Dictionary(box); + geometryDictionary.setName(name); + setGeometryDictionary(geometryDictionary); + } + + @Override + public Type getType() { + return Type.BOX; + } + + public double[] getMin() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(MIN_KEY)) + return getGeometryDictionary().lookupDoubleArray(MIN_KEY); + else + return new double[] { 0, 0, 0 }; + } + + public double[] getMax() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(MAX_KEY)) + return getGeometryDictionary().lookupDoubleArray(MAX_KEY); + else + return new double[] { 0, 0, 0 }; + } + + @Override + public Surface cloneSurface() { + Surface box = new Box(name); + cloneSurface(box); + return box; + } + + @Override + public vtkPolyData getDataSet() { + double[] min = getMin(); + double[] max = getMax(); + + vtkCubeSource cubeSource = new vtkCubeSource(); + cubeSource.SetBounds(min[0], max[0], min[1], max[1], min[2], max[2]); + cubeSource.Update(); + return cubeSource.GetOutput(); + } +} diff --git a/src/eu/engys/core/project/geometry/surface/Cylinder.java b/src/eu/engys/core/project/geometry/surface/Cylinder.java new file mode 100644 index 0000000..2ae8d18 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/Cylinder.java @@ -0,0 +1,102 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import vtk.vtkLineSource; +import vtk.vtkPolyData; +import vtk.vtkTubeFilter; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; + +public class Cylinder extends BaseSurface { + + /** + * @deprecated Use GeometryFactory!! + */ + @Deprecated + public Cylinder(String name) { + super(name); + Dictionary geometryDictionary = new Dictionary(cylinder); + geometryDictionary.setName(name); + setGeometryDictionary(geometryDictionary); + } + + @Override + public Type getType() { + return Type.CYLINDER; + } + + public double[] getPoint1() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(POINT1_KEY)) + return getGeometryDictionary().lookupDoubleArray(POINT1_KEY); + else + return new double[] { 0, 0, 0 }; + } + + public double[] getPoint2() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(POINT2_KEY)) + return getGeometryDictionary().lookupDoubleArray(POINT2_KEY); + else + return new double[] { 0, 0, 0 }; + } + + public double getRadius() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(RADIUS_KEY)) + return Double.valueOf(getGeometryDictionary().lookup(RADIUS_KEY)); + else + return 0; + } + + @Override + public Surface cloneSurface() { + Surface box = new Cylinder(name); + cloneSurface(box); + return box; + } + + @Override + public vtkPolyData getDataSet() { + double[] point1 = getPoint1(); + double[] point2 = getPoint2(); + double radius = getRadius(); + + vtkLineSource lineSource = new vtkLineSource(); + lineSource.SetPoint1(point1); + lineSource.SetPoint2(point2); + + // Create a tube (cylinder) around the line + vtkTubeFilter tubeFilter = new vtkTubeFilter(); + tubeFilter.SetInputConnection(lineSource.GetOutputPort()); + tubeFilter.SetCapping(1); + tubeFilter.SetRadius(radius); + tubeFilter.SetNumberOfSides(50); + tubeFilter.Update(); + + return tubeFilter.GetOutput(); + } +} diff --git a/src/eu/engys/core/project/geometry/surface/MultiPlane.java b/src/eu/engys/core/project/geometry/surface/MultiPlane.java new file mode 100644 index 0000000..972ff8d --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/MultiPlane.java @@ -0,0 +1,137 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import static eu.engys.core.project.system.BlockMeshDict.ELEMENTS_KEY; +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; + +public class MultiPlane extends MultiRegion { + + public MultiPlane(String name) { + super(name); + } + + public void addPlane(String name) { + if (!regionsMap.containsKey(name)) { + PlaneRegion newPlane = new PlaneRegion(name); + super.addRegion(newPlane); + } + } + + public void setPlane(String name, double[] origin, double[] point1, double[] point2, int resX, int resY) { + if (regionsMap.containsKey(name)) { + PlaneRegion plane = (PlaneRegion) regionsMap.get(name); + plane.origin = origin; + plane.point1 = point1; + plane.point2 = point2; + plane.resolutionX = resX; + plane.resolutionY = resY; + } else { + System.err.println(String.format("Plane %s not found.", name)); + } + } + + public PlaneRegion[] getPlanes() { + return regions.toArray(new PlaneRegion[0]); + } + + @Override + public Type getType() { + return Type.MULTI; + } + + @Override + public void setGeometryDictionary(Dictionary d) { + super.setGeometryDictionary(d); + + double[] min = d.lookupDoubleArray(MIN_KEY); + double[] max = d.lookupDoubleArray(MAX_KEY); + int[] res = d.lookupIntArray(ELEMENTS_KEY); + + if (regions.size() == 6) { + setPlane(regions.get(0).getName(), new double[] { min[0], min[1], min[2] }, new double[] { min[0], max[1], min[2] }, new double[] { min[0], min[1], max[2] }, res[1], res[2]); + setPlane(regions.get(1).getName(), new double[] { max[0], min[1], min[2] }, new double[] { max[0], max[1], min[2] }, new double[] { max[0], min[1], max[2] }, res[1], res[2]); + + setPlane(regions.get(2).getName(), new double[] { min[0], min[1], min[2] }, new double[] { max[0], min[1], min[2] }, new double[] { min[0], min[1], max[2] }, res[0], res[2]); + setPlane(regions.get(3).getName(), new double[] { min[0], max[1], min[2] }, new double[] { max[0], max[1], min[2] }, new double[] { min[0], max[1], max[2] }, res[0], res[2]); + + setPlane(regions.get(4).getName(), new double[] { min[0], min[1], min[2] }, new double[] { max[0], min[1], min[2] }, new double[] { min[0], max[1], min[2] }, res[0], res[1]); + setPlane(regions.get(5).getName(), new double[] { min[0], min[1], max[2] }, new double[] { max[0], min[1], max[2] }, new double[] { min[0], max[1], max[2] }, res[0], res[1]); + } + } + + @Override + public boolean hasLayers() { + return false; + } + + @Override + public boolean hasSurfaceRefinement() { + return false; + } + + @Override + public boolean hasVolumeRefinement() { + return false; + } + + @Override + public boolean hasZones() { + return false; + } + + public double[] getDelta() { + double[] delta = new double[3]; + + if (getGeometryDictionary() != null) { + double[] min = getGeometryDictionary().lookupDoubleArray(MIN_KEY); + double[] max = getGeometryDictionary().lookupDoubleArray(MAX_KEY); + int[] res = getGeometryDictionary().lookupIntArray(ELEMENTS_KEY); + + for (int i = 0; i < delta.length; i++) { + delta[i] = (max[i] - min[i]) / res[i]; + } + } + + return delta; + } + + @Override + public Surface cloneSurface() { + Surface s = new MultiPlane(name); + cloneSurface(s); + return s; + } + + @Override + public vtkPolyData getDataSet() { + return null; + } +} diff --git a/src/eu/engys/core/project/geometry/surface/MultiRegion.java b/src/eu/engys/core/project/geometry/surface/MultiRegion.java new file mode 100644 index 0000000..b5e10b5 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/MultiRegion.java @@ -0,0 +1,134 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.TransfromMode; +import eu.engys.core.project.geometry.stl.AffineTransform; + +public abstract class MultiRegion extends Surface { + + protected Map regionsMap = new HashMap(); + protected List regions = new ArrayList(); + private boolean modified = false; + + public MultiRegion(String name) { + super(name); + } + + public void addRegion(Region region) { + setName(region); + region.setParent(this); + regions.add(region); + regionsMap.put(region.getName(), region); + } + + private void setName(Region region) { + String name = region.getName(); + int counter = 0; + while (regionsMap.containsKey(name)) { + name += counter++; + } + + region.rename(name); + } + + public Region[] getRegions() { + return regions.toArray(new Region[regions.size()]); + } + + @Override + public boolean hasRegions() { + return true; + } + + protected void clearRegions() { + regions.clear(); + } + + @Override + public String getPatchName() { + return getName(); + } + + public void renameRegion(String oldName, String newName) { + regionsMap.put(newName, regionsMap.remove(oldName)); + } + + public void removeRegion(String name) { + regions.remove(regionsMap.remove(name)); + } + + public boolean isSingleton() { + return regions.size() == 1; + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + for (Region region : regions) { + region.setVisible(visible); + } + } + + @Override + public void setTransformation(AffineTransform transformation) { + super.setTransformation(transformation); + for (Region region : regions) { + region.setTransformation(transformation); + } + } + + @Override + public void setTransformMode(TransfromMode transformMode) { + super.setTransformMode(transformMode); + for (Region region : regions) { + region.setTransformMode(transformMode); + } + } + + @Override + protected void cloneSurface(Surface surface) { + super.cloneSurface(surface); + MultiRegion mr = (MultiRegion) surface; + for (Region region : regions) { + mr.addRegion((Region) region.cloneSurface()); + } + } + + public void setModified(boolean modified) { + this.modified = modified; + } + public boolean isModified() { + return modified; + } +} diff --git a/src/eu/engys/core/project/geometry/surface/NullSurface.java b/src/eu/engys/core/project/geometry/surface/NullSurface.java new file mode 100644 index 0000000..3650db6 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/NullSurface.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.geometry.surface; + +import vtk.vtkPolyData; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; + +public class NullSurface extends Surface { + + public NullSurface() { + super(""); + } + + public NullSurface(String name) { + super(name); + } + + @Override + public String getPatchName() { + return ""; + } + + @Override + public Type getType() { + return Type.BOX; + } + + @Override + public boolean isSingleton() { + return false; + } + + @Override + public boolean hasRegions() { + return false; + } + + @Override + public Region[] getRegions() { + return null; + } + + @Override + public boolean hasSurfaceRefinement() { + return false; + } + + @Override + public boolean hasVolumeRefinement() { + return false; + } + + @Override + public boolean hasLayers() { + return false; + } + + @Override + public boolean hasZones() { + return false; + } + + @Override + public Surface cloneSurface() { + return new NullSurface(name); + } + + @Override + public vtkPolyData getDataSet() { + return null; + } +} diff --git a/src/eu/engys/core/project/geometry/surface/Plane.java b/src/eu/engys/core/project/geometry/surface/Plane.java new file mode 100644 index 0000000..9f53e2f --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/Plane.java @@ -0,0 +1,112 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import vtk.vtkPlaneSource; +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; + +public class Plane extends BaseSurface { + + private double diagonal = 1; + + /** + * @deprecated Use GeometryFactory!! + */ + @Deprecated + public Plane(String name) { + super(name); + Dictionary geometryDictionary = new Dictionary(plane); + geometryDictionary.setName(name); + setGeometryDictionary(geometryDictionary); + } + + @Override + public Type getType() { + return Type.PLANE; + } + + public double[] getCenter() { + if (getGeometryDictionary() != null && getGeometryDictionary().subDict(POINT_AND_NORMAL_DICT_KEY) != null && getGeometryDictionary().subDict(POINT_AND_NORMAL_DICT_KEY).found(BASE_POINT_KEY)) + return getGeometryDictionary().subDict(POINT_AND_NORMAL_DICT_KEY).lookupDoubleArray(BASE_POINT_KEY); + else + return null; + } + + public void setCenter(double[] center) { + if (getGeometryDictionary() != null && getGeometryDictionary().isDictionary(POINT_AND_NORMAL_DICT_KEY)){ + Dictionary dict = getGeometryDictionary().subDict(POINT_AND_NORMAL_DICT_KEY); + dict.add(BASE_POINT_KEY, center); + } + } + + public double[] getNormal() { + if (getGeometryDictionary() != null && getGeometryDictionary().subDict(POINT_AND_NORMAL_DICT_KEY) != null && getGeometryDictionary().subDict(POINT_AND_NORMAL_DICT_KEY).found(NORMAL_VECTOR_KEY)) + return getGeometryDictionary().subDict(POINT_AND_NORMAL_DICT_KEY).lookupDoubleArray(NORMAL_VECTOR_KEY); + else + return null; + } + + public void setNormal(double[] normal) { + if (getGeometryDictionary() != null && getGeometryDictionary().isDictionary(POINT_AND_NORMAL_DICT_KEY)){ + Dictionary dict = getGeometryDictionary().subDict(POINT_AND_NORMAL_DICT_KEY); + dict.add(NORMAL_VECTOR_KEY, normal); + } + } + + public void setDiagonal(double diagonal) { + this.diagonal = diagonal; + } + + public double getDiagonal() { + return diagonal; + } + + @Override + public Surface cloneSurface() { + Plane plane = new Plane(name); + cloneSurface(plane); + plane.diagonal = this.diagonal; + return plane; + } + + @Override + public vtkPolyData getDataSet() { + + vtkPlaneSource planeSource = new vtkPlaneSource(); + planeSource.SetOrigin(0, 0, 0); + planeSource.SetPoint1(diagonal, 0, 0); + planeSource.SetPoint2(0, diagonal, 0); + planeSource.SetCenter(getCenter()); + planeSource.SetNormal(getNormal()); + planeSource.Update(); + + return planeSource.GetOutput(); + } +} diff --git a/src/eu/engys/core/project/geometry/surface/PlaneRegion.java b/src/eu/engys/core/project/geometry/surface/PlaneRegion.java new file mode 100644 index 0000000..b8c82e6 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/PlaneRegion.java @@ -0,0 +1,117 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import vtk.vtkPlaneSource; +import vtk.vtkPolyData; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; + + +public class PlaneRegion extends Region { + + double[] origin; + double[] point1; + double[] point2; + + int resolutionX; + int resolutionY; + + public PlaneRegion(String name) { + super(name); + } + + public double[] getPoint1() { + return point1; + } + + public double[] getPoint2() { + return point2; + } + + public double[] getOrigin() { + return origin; + } + + @Override + public Type getType() { + return Type.PLANE; + } + @Override + public String getPatchName() { + return getName(); + } + + @Override + public boolean hasLayers() { + return true; + } + + @Override + public boolean hasSurfaceRefinement() { + return false; + } + + @Override + public boolean hasVolumeRefinement() { + return false; + } + + public int getResolutionX() { + return resolutionX; + } + + public int getResolutionY() { + return resolutionY; + } + + @Override + public vtkPolyData getDataSet() { + vtkPlaneSource planeSource = new vtkPlaneSource(); + planeSource.SetOrigin(getOrigin()); + planeSource.SetPoint1(getPoint1()); + planeSource.SetPoint2(getPoint2()); + planeSource.SetXResolution(getResolutionX()); + planeSource.SetYResolution(getResolutionY()); + planeSource.Update(); + return planeSource.GetOutput(); + } + + @Override + public Surface cloneSurface() { + PlaneRegion region = new PlaneRegion(name); + cloneSurface(region); + region.origin = origin; + region.point1 = point1; + region.point2 = point2; + + region.resolutionX = resolutionX; + region.resolutionY = resolutionY; + + return region; + } +} diff --git a/src/eu/engys/core/project/geometry/surface/Region.java b/src/eu/engys/core/project/geometry/surface/Region.java new file mode 100644 index 0000000..29c6f22 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/Region.java @@ -0,0 +1,69 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import eu.engys.core.project.geometry.Type; + +public abstract class Region extends BaseSurface { + + private MultiRegion parent; + + public Region(String name) { + super(name); + } + + public void setParent(MultiRegion parent) { + this.parent = parent; + } + + public MultiRegion getParent() { + return parent; + } + + @Override + public Type getType() { + return Type.REGION; + } + + @Override + public String getPatchName() { +// System.out.println("Region.getPatchName() "+getName()+", is singleton: "+parent.isSingleton()+", append: "+parent.isAppendRegionName()); + if (parent.isSingleton() && !parent.isAppendRegionName()) { + return parent.getPatchName(); + } else { + return parent.getPatchName() + "_" + getName(); + } + } + +// @Override +// public Surface cloneSurface() { +// Surface region = new Region(name); +// cloneSurface(region); +// return region; +// } + +} diff --git a/src/eu/engys/core/project/geometry/surface/Ring.java b/src/eu/engys/core/project/geometry/surface/Ring.java new file mode 100644 index 0000000..50363d1 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/Ring.java @@ -0,0 +1,159 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import vtk.vtkAppendPolyData; +import vtk.vtkCellArray; +import vtk.vtkIdList; +import vtk.vtkLineSource; +import vtk.vtkPolyData; +import vtk.vtkPolyDataNormals; +import vtk.vtkTubeFilter; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; + +public class Ring extends BaseSurface { + + /** + * @deprecated Use GeometryFactory!! + */ + @Deprecated + public Ring(String name) { + super(name); + Dictionary geometryDictionary = new Dictionary(ring); + geometryDictionary.setName(name); + setGeometryDictionary(geometryDictionary); + } + + @Override + public Type getType() { + return Type.RING; + } + + public double[] getPoint1() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(POINT1_KEY)) + return getGeometryDictionary().lookupDoubleArray(POINT1_KEY); + else + return new double[] { 0, 0, 0 }; + } + + public double[] getPoint2() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(POINT2_KEY)) + return getGeometryDictionary().lookupDoubleArray(POINT2_KEY); + else + return new double[] { 0, 0, 0 }; + } + + public double getInnerRadius() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(INNER_RADIUS_KEY)) + return Double.valueOf(getGeometryDictionary().lookup(INNER_RADIUS_KEY)); + else + return 0; + } + + public double getOuterRadius() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(OUTER_RADIUS_KEY)) + return Double.valueOf(getGeometryDictionary().lookup(OUTER_RADIUS_KEY)); + else + return 0; + } + + @Override + public Surface cloneSurface() { + Surface box = new Ring(name); + cloneSurface(box); + return box; + } + + @Override + public vtkPolyData getDataSet() { + + vtkLineSource lineSource = new vtkLineSource(); + lineSource.SetPoint1(getPoint1()); + lineSource.SetPoint2(getPoint2()); + + vtkTubeFilter internalTubeFilter = new vtkTubeFilter(); + internalTubeFilter.SetInputConnection(lineSource.GetOutputPort()); + internalTubeFilter.SetCapping(0); + internalTubeFilter.SetRadius(getInnerRadius()); + internalTubeFilter.SetNumberOfSides(50); + internalTubeFilter.Update(); + + vtkTubeFilter externalTubeFilter = new vtkTubeFilter(); + externalTubeFilter.SetInputConnection(lineSource.GetOutputPort()); + externalTubeFilter.SetCapping(0); + externalTubeFilter.SetRadius(getOuterRadius()); + externalTubeFilter.SetNumberOfSides(50); + externalTubeFilter.Update(); + + vtkAppendPolyData append = new vtkAppendPolyData(); + append.AddInputConnection(internalTubeFilter.GetOutputPort()); + append.AddInputConnection(externalTubeFilter.GetOutputPort()); + append.Update(); + + vtkPolyData outputMesh = new vtkPolyData(); + outputMesh.DeepCopy(append.GetOutput()); + vtkCellArray outputTriangles = outputMesh.GetPolys(); + + int length = internalTubeFilter.GetOutput().GetNumberOfPoints(); + for (int ptId = 0; ptId < 50; ptId++) { + // Triangle one extremity + vtkIdList triangle = new vtkIdList(); + triangle.InsertNextId(ptId); + triangle.InsertNextId(ptId + length); + triangle.InsertNextId((ptId + 1) % 50 + length); + outputTriangles.InsertNextCell(triangle); + + triangle = new vtkIdList(); + triangle.InsertNextId(ptId); + triangle.InsertNextId((ptId + 1) % 50 + length); + triangle.InsertNextId((ptId + 1) % 50); + outputTriangles.InsertNextCell(triangle); + + // Triangle the other extremity + int offset = length - 50; + triangle = new vtkIdList(); + triangle.InsertNextId(ptId + offset); + triangle.InsertNextId(ptId + +offset + length); + triangle.InsertNextId((ptId + 1) % 50 + offset + length); + outputTriangles.InsertNextCell(triangle); + + triangle = new vtkIdList(); + triangle.InsertNextId((ptId + 1) % 50 + length + offset); + triangle.InsertNextId((ptId + 1) % 50 + offset); + triangle.InsertNextId(ptId + offset); + outputTriangles.InsertNextCell(triangle); + } + + vtkPolyDataNormals normals = new vtkPolyDataNormals(); + normals.SetInputData(outputMesh); + normals.Update(); + + return normals.GetOutput(); + } +} diff --git a/src/eu/engys/core/project/geometry/surface/Solid.java b/src/eu/engys/core/project/geometry/surface/Solid.java new file mode 100644 index 0000000..04534c0 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/Solid.java @@ -0,0 +1,87 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import vtk.vtkPolyData; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; +import eu.engys.util.VTKSettings; + +public class Solid extends Region { + private vtkPolyData dataSet; + + public Solid(String name) { + super(name); + } + + @Override + public Type getType() { + return Type.SOLID; + } + + @Override + public boolean hasLayers() { + return true; + } + + @Override + public boolean hasSurfaceRefinement() { + return true; + } + + @Override + public boolean hasVolumeRefinement() { + return false; + } + + @Override + public boolean hasZones() { + return false; + } + + @Override + public Surface cloneSurface() { + Solid solid = new Solid(name); + cloneSurface(solid); + + if (VTKSettings.librariesAreLoaded()) { + solid.dataSet = new vtkPolyData(); + solid.dataSet.ShallowCopy(dataSet); + } + + return solid; + } + + public void setDataSet(vtkPolyData dataSet) { + this.dataSet = dataSet; + } + + @Override + public vtkPolyData getDataSet() { + return dataSet; + } +} diff --git a/src/eu/engys/core/project/geometry/surface/Sphere.java b/src/eu/engys/core/project/geometry/surface/Sphere.java new file mode 100644 index 0000000..25e4fef --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/Sphere.java @@ -0,0 +1,88 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import vtk.vtkPolyData; +import vtk.vtkSphereSource; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; + +public class Sphere extends BaseSurface { + + /** + * @deprecated Use GeometryFactory!! + */ + @Deprecated + public Sphere(String name) { + super(name); + Dictionary geometryDictionary = new Dictionary(sphere); + geometryDictionary.setName(name); + setGeometryDictionary(geometryDictionary); + } + + @Override + public Type getType() { + return Type.SPHERE; + } + + public double[] getCenter() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(CENTRE_KEY)) + return getGeometryDictionary().lookupDoubleArray(CENTRE_KEY); + else + return new double[] { 0, 0, 0 }; + } + + public double getRadius() { + if (getGeometryDictionary() != null && getGeometryDictionary().found(RADIUS_KEY)) + return Double.valueOf(getGeometryDictionary().lookup(RADIUS_KEY)); + else + return 0; + } + + @Override + public Surface cloneSurface() { + Surface box = new Sphere(name); + cloneSurface(box); + return box; + } + + @Override + public vtkPolyData getDataSet() { + double[] center = getCenter(); + double radius = getRadius(); + + vtkSphereSource sphereSource = new vtkSphereSource(); + sphereSource.SetCenter(center); + sphereSource.SetRadius(radius); + sphereSource.SetPhiResolution(20); + sphereSource.SetThetaResolution(20); + sphereSource.Update(); + + return sphereSource.GetOutput(); + } +} diff --git a/src/eu/engys/core/project/geometry/surface/Stl.java b/src/eu/engys/core/project/geometry/surface/Stl.java new file mode 100644 index 0000000..14f2577 --- /dev/null +++ b/src/eu/engys/core/project/geometry/surface/Stl.java @@ -0,0 +1,151 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.geometry.surface; + +import java.io.File; +import java.util.List; + +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.TransfromMode; +import eu.engys.core.project.geometry.Type; + +public class Stl extends MultiRegion { + + private String fileName; + + /** + * @deprecated Use GeometryFactory!! + */ + @Deprecated + public Stl(String name) { + super(name); + this.fileName = getName() + ".stl"; + Dictionary defaultSTLDictionary = new Dictionary(stl); + defaultSTLDictionary.setName(fileName); + defaultSTLDictionary.add("name", getName()); + defaultSTLDictionary.add("appendRegionName", "false"); + setGeometryDictionary(defaultSTLDictionary); + } + + public String getFileName() { + return fileName; + } + + public void setFileName(File file) { + this.fileName = file.getName(); + } + + @Override + public Type getType() { + return Type.STL; + } + + public Solid[] getSolids() { + return regions.toArray(new Solid[0]); + } + + @Override + public boolean isSingleton() { + return regions.size() == 1; + } + + public void setSolids(List solids) { + for (Solid solid : solids) { + addRegion(solid); + } + } + + @Override + public void rename(String newName) { + super.rename(newName); + if (getGeometryDictionary() != null && getGeometryDictionary().isField("name")) { + getGeometryDictionary().add("name", newName); + + if (getTransformMode() == TransfromMode.TO_FILE) { + String dictName = getGeometryDictionary().getName(); + if (dictName.endsWith(".stl")) { + this.fileName = newName + ".stl"; + } else if (dictName.endsWith(".STL")) { + this.fileName = newName + ".STL"; + } + + getGeometryDictionary().setName(fileName); + setModified(true); + } + } + } + + @Override + public boolean hasLayers() { + return true; + } + + @Override + public boolean hasSurfaceRefinement() { + return true; + } + + @Override + public boolean hasVolumeRefinement() { + return true; + } + + @Override + public boolean hasZones() { + return true; + } + + public void buildGeometryDictionary(Dictionary dictionary) { + Dictionary geometryDict = new Dictionary(dictionary); + geometryDict.setName(fileName); + setGeometryDictionary(geometryDict); + } + + @Override + public String getPatchName() { + if (getGeometryDictionary().found("name")) { + return getGeometryDictionary().lookup("name"); + } else { + return super.getPatchName(); + } + } + + @Override + public Surface cloneSurface() { + Stl s = new Stl(name); + s.fileName = this.fileName; + cloneSurface(s); + return s; + } + + @Override + public vtkPolyData getDataSet() { + return null; + } +} diff --git a/src/eu/engys/core/project/materials/Material.java b/src/eu/engys/core/project/materials/Material.java new file mode 100644 index 0000000..29ea64e --- /dev/null +++ b/src/eu/engys/core/project/materials/Material.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.materials; + +import eu.engys.core.dictionary.Dictionary; + +public class Material { + + private String name; + private Dictionary dictionary; + + public Material(String name, Dictionary dictionary) { + this.name = name; + this.dictionary = dictionary; + } + + public String getName() { + return name; + } + + public Dictionary getDictionary() { + return dictionary; + } + + @Override + public String toString() { + return name; + } + + public void setDictionary(Dictionary d) { + this.dictionary = d; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/src/eu/engys/core/project/materials/Materials.java b/src/eu/engys/core/project/materials/Materials.java new file mode 100644 index 0000000..d3ea4b2 --- /dev/null +++ b/src/eu/engys/core/project/materials/Materials.java @@ -0,0 +1,98 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.materials; + +import java.util.LinkedList; + +import eu.engys.core.project.Model; +import eu.engys.core.project.constant.ThermophysicalProperties; +import eu.engys.core.project.constant.TransportProperties; +import eu.engys.util.progress.ProgressMonitor; + +public class Materials extends LinkedList { + + public Materials() { + super(); + } + + public static String materialsToString(Materials materials) { + StringBuilder sb = new StringBuilder(); + sb.append("("); + for (Material material : materials) { + sb.append(material.getName()); + sb.append(" "); + } + sb.append(")"); + return sb.toString(); + } + + public String getFirstMaterialName() { + if (size() > 1) { + return get(0).getName(); + } + return ""; + } + + public void loadMaterials(Model model, MaterialsReader reader, ProgressMonitor monitor) { + clear(); + TransportProperties transProp = model.getProject().getConstantFolder().getTransportProperties(); + ThermophysicalProperties thermoProp = model.getProject().getConstantFolder().getThermophysicalProperties(); + + if (!model.getState().getMultiphaseModel().isMultiphase()) { + if (model.getState().isIncompressible()) { + reader.readSingle_Material(this, transProp, monitor); + } else { + reader.readSingle_Material(this, thermoProp, monitor); + } + model.materialsChanged(); + } + } + + public void saveMaterials(Model model, MaterialsWriter writer) { + TransportProperties transProp = new TransportProperties(); + ThermophysicalProperties thermoProp = new ThermophysicalProperties(); + + if (!model.getState().getMultiphaseModel().isMultiphase()) { + if (model.getState().isIncompressible()) { + writer.writeSingle_IncompressibleMaterial(this, transProp); + } else { + writer.writeSingle_CompressibleMaterial(this, thermoProp); + } + model.getProject().getConstantFolder().setTransportProperties(transProp); + model.getProject().getConstantFolder().setThermophysicalProperties(thermoProp); + } else { + // ECOMARINE + if (model.getState().isIncompressible() && model.getMaterials().size() == 1) { + writer.writeSingle_IncompressibleMaterial(this, transProp); + model.getProject().getConstantFolder().setTransportProperties(transProp); + model.getProject().getConstantFolder().setThermophysicalProperties(thermoProp); + } else { + /**/ + } + } + } +} diff --git a/src/eu/engys/core/project/materials/Materials200To210Converter.java b/src/eu/engys/core/project/materials/Materials200To210Converter.java new file mode 100644 index 0000000..c8ca584 --- /dev/null +++ b/src/eu/engys/core/project/materials/Materials200To210Converter.java @@ -0,0 +1,262 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.materials; + +import static eu.engys.core.project.constant.ThermophysicalProperties.AS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.CONSTANT_CP_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.CONST_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.CP_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.ENERGY_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.EQUATION_OF_STATE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HF_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HIGH_CP_COEFFS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.JANAF_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.LOW_CP_COEFFS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MATERIAL_NAME_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MIXTURE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MOL_WEIGHT_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MU_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.N_MOLES_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PR_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PURE_MIXTURE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SENSIBLE_ENTHALPY_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SPECIE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SUTHERLAND_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TCOMMON_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMODYNAMICS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMO_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMO_MODEL_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMO_TYPE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THIGH_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TLOW_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TRANSPORT_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TS_KEY; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.constant.ThermophysicalProperties; + +public class Materials200To210Converter { + + /* + * thermoType + * thermoModel>>>>; + * thermoType + * hRhoThermo>>>>; + * + * mixture { specie { nMoles 1; molWeight 28.9; } thermodynamics { Cp 1000; + * Hf 0; } transport { mu 1.8e-05; Pr 0.7; } } + */ + public ThermophysicalProperties convert(Dictionary oldDictionary) { + ThermophysicalProperties thermophysicalProperties = new ThermophysicalProperties(); + + Dictionary materialGUIDict = toGUIFormat(oldDictionary); + + String type = materialGUIDict.lookup(THERMO_MODEL_KEY); + String energy = SENSIBLE_ENTHALPY_KEY; + String thermo = materialGUIDict.found(THERMO_KEY) ? materialGUIDict.lookup(THERMO_KEY) : ""; + String transport = materialGUIDict.found(TRANSPORT_KEY) ? materialGUIDict.lookup(TRANSPORT_KEY) : ""; + + Dictionary thermoDict = new Dictionary(THERMO_TYPE_KEY); + thermoDict.add(Dictionary.TYPE, type); + thermoDict.add(MIXTURE_KEY, PURE_MIXTURE_KEY); + thermoDict.add(TRANSPORT_KEY, transport); + thermoDict.add(THERMO_KEY, thermo); + thermoDict.add(EQUATION_OF_STATE_KEY, materialGUIDict.lookup(EQUATION_OF_STATE_KEY)); + thermoDict.add(SPECIE_KEY, SPECIE_KEY); + thermoDict.add(ENERGY_KEY, energy); + + /* SPECIES */ + Dictionary specieDict = new Dictionary(SPECIE_KEY); + specieDict.add(N_MOLES_KEY, materialGUIDict.lookup(N_MOLES_KEY)); + specieDict.add(MOL_WEIGHT_KEY, materialGUIDict.lookup(MOL_WEIGHT_KEY)); + + /* THERMODYNAMICS */ + Dictionary thermodynamicsDict = new Dictionary(THERMODYNAMICS_KEY); + if (thermo.equals(CONSTANT_CP_KEY)) { + thermodynamicsDict.add(CP_KEY, materialGUIDict.lookup(CP_KEY)); + thermodynamicsDict.add(HF_KEY, materialGUIDict.lookup(HF_KEY)); + } else if (thermo.equals(JANAF_KEY)) { + thermodynamicsDict.add(TLOW_KEY, materialGUIDict.lookup(TLOW_KEY)); + thermodynamicsDict.add(THIGH_KEY, materialGUIDict.lookup(THIGH_KEY)); + thermodynamicsDict.add(TCOMMON_KEY, materialGUIDict.lookup(TCOMMON_KEY)); + thermodynamicsDict.add(HIGH_CP_COEFFS_KEY, materialGUIDict.lookup(HIGH_CP_COEFFS_KEY)); + thermodynamicsDict.add(LOW_CP_COEFFS_KEY, materialGUIDict.lookup(LOW_CP_COEFFS_KEY)); + } + + /* TRANSPORT */ + Dictionary transportDict = new Dictionary(TRANSPORT_KEY); + if (transport.equals(CONST_KEY)) { + transportDict.add(MU_KEY, materialGUIDict.lookup(MU_KEY)); + transportDict.add(PR_KEY, materialGUIDict.lookup(PR_KEY)); + } else if (transport.equals(SUTHERLAND_KEY)) { + transportDict.add(AS_KEY, materialGUIDict.lookup(AS_KEY)); + transportDict.add(TS_KEY, materialGUIDict.lookup(TS_KEY)); + } + + Dictionary mixtureDict = new Dictionary(MIXTURE_KEY); + mixtureDict.add(specieDict); + mixtureDict.add(thermodynamicsDict); + mixtureDict.add(transportDict); + + thermophysicalProperties.add(MATERIAL_NAME_KEY, materialGUIDict.lookup(MATERIAL_NAME_KEY)); + thermophysicalProperties.add(thermoDict); + thermophysicalProperties.add(mixtureDict); + + // System.out.println("MaterialsBuilder.saveCompressible() "+thermophysicalProperties); + return thermophysicalProperties; + + } + + // @Override + // public Dictionary loadCompressible(Model model) { + // return + // toGUIFormat(model.getProject().getConstantFolder().getThermophysicalProperties()); + // } + + // @Override + public Dictionary toGUIFormat(Dictionary thermophysicalProperties) { + Dictionary d = new Dictionary(""); + + if (thermophysicalProperties.isField("thermoType")) { + String thermoType = thermophysicalProperties.lookup("thermoType"); + String[] tokens = thermoType.replace(">", "").trim().split("<"); + + String transport = tokens[2]; + String thermo = tokens[4]; + + d.add("thermoModel", tokens[0]); + d.add("transport", transport); + d.add("thermo", thermo); + d.add("equationOfState", tokens[5]); + } + + if (thermophysicalProperties.found("materialName")) + d.add("materialName", thermophysicalProperties.lookup("materialName")); + else + d.add("materialName", "defaultMaterial"); + + if (thermophysicalProperties.found("mixture")) { + Dictionary mixture = thermophysicalProperties.subDict("mixture"); + + /* SPECIES */ + Dictionary speciesDict = mixture.subDict("specie"); + d.merge(speciesDict); + + /* THERMODYNAMICS */ + Dictionary thermodynamicsDict = mixture.subDict("thermodynamics"); + d.merge(thermodynamicsDict); + + /* TRANSPORT */ + Dictionary transportDict = mixture.subDict("transport"); + d.merge(transportDict); + } + + return d; + } + + // @Override + // public Dictionary saveIncompressible(Model model, Dictionary + // materialDict) { + // + // Dictionary transportProperties = new Dictionary("transportProperties"); + // + // transportProperties.add("materialName", + // materialDict.lookup("materialName")); + // + // String transportModel = materialDict.lookup("transportModel"); + // transportProperties.add("transportModel", transportModel); + // + // if (materialDict.found(transportModel + "Coeffs")) { + // transportProperties.add(materialDict.subDict(transportModel + "Coeffs")); + // } + // + // if (materialDict.found("rho")) { + // transportProperties.add(materialDict.lookupScalar("rho")); + // } + // + // if (materialDict.found("mu")) { + // transportProperties.add(materialDict.lookupScalar("mu")); + // } + // + // if (materialDict.found("nu")) { + // transportProperties.add(materialDict.lookupScalar("nu")); + // } else if (materialDict.found("rho") && materialDict.found("mu")) { + // DimensionedScalar rho = materialDict.lookupScalar("rho"); + // DimensionedScalar mu = materialDict.lookupScalar("mu"); + // + // double nuValue = mu.doubleValue() / rho.doubleValue(); + // Dimensions nuDimensions = mu.getDimensions().divide(rho.getDimensions()); + // + // DimensionedScalar nu = new DimensionedScalar("nu", + // Double.toString(nuValue), nuDimensions); + // + // transportProperties.add(nu); + // } + // + // if (materialDict.found("Cp")) { + // DimensionedScalar cp = materialDict.lookupScalar("Cp"); + // transportProperties.add(cp); + // transportProperties.add("Cp0", cp.getValue()); + // } + // if (materialDict.found("Prt")) { + // transportProperties.add(materialDict.lookupScalar("Prt")); + // } + // if (materialDict.found("Pr")) { + // transportProperties.add(materialDict.lookupScalar("Pr")); + // } + // if (materialDict.found("lambda")) { + // transportProperties.add(materialDict.lookupScalar("lambda")); + // } + // + // if (materialDict.found("pRef")) { + // transportProperties.add(materialDict.lookupScalar("pRef")); + // } + // if (materialDict.found("beta")) { + // transportProperties.add(materialDict.lookupScalar("beta")); + // } + // if (materialDict.found("TRef")) { + // transportProperties.add(materialDict.lookupScalar("TRef")); + // } + // + // // + // System.out.println("MaterialsBuilder.saveIncompressible() "+transportProperties); + // + // return transportProperties; + // } + + // @Override + // public Dictionary saveSigma(Model model, Dictionary sigmaDict) { + // Dictionary transportProperties = new Dictionary("sigma"); + // if (model.getState().isMultiphase()) { + // if (sigmaDict.found("sigma")) { + // transportProperties.add(sigmaDict.lookupScalar("sigma")); + // } + // } + // return transportProperties; + // } + +} diff --git a/src/eu/engys/core/project/materials/MaterialsReader.java b/src/eu/engys/core/project/materials/MaterialsReader.java new file mode 100644 index 0000000..571f09b --- /dev/null +++ b/src/eu/engys/core/project/materials/MaterialsReader.java @@ -0,0 +1,38 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.materials; + +import eu.engys.core.project.constant.ThermophysicalProperties; +import eu.engys.core.project.constant.TransportProperties; +import eu.engys.util.progress.ProgressMonitor; + +public interface MaterialsReader { + + void readSingle_Material(Materials materials, TransportProperties tpp, ProgressMonitor monitor); + + void readSingle_Material(Materials materials, ThermophysicalProperties tfp, ProgressMonitor monitor); + +} diff --git a/src/eu/engys/core/project/materials/MaterialsWriter.java b/src/eu/engys/core/project/materials/MaterialsWriter.java new file mode 100644 index 0000000..8379648 --- /dev/null +++ b/src/eu/engys/core/project/materials/MaterialsWriter.java @@ -0,0 +1,37 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.materials; + +import eu.engys.core.project.constant.ThermophysicalProperties; +import eu.engys.core.project.constant.TransportProperties; + +public interface MaterialsWriter { + + void writeSingle_IncompressibleMaterial(Materials materials, TransportProperties tpp); + + void writeSingle_CompressibleMaterial(Materials materials, ThermophysicalProperties tfp); + +} diff --git a/src/eu/engys/core/project/materials/Phase.java b/src/eu/engys/core/project/materials/Phase.java new file mode 100644 index 0000000..285afc0 --- /dev/null +++ b/src/eu/engys/core/project/materials/Phase.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.materials; + +import eu.engys.core.dictionary.Dictionary; + +public class Phase { + + private String name; + private Dictionary dictionary; + + public Phase(String name, Dictionary dictionary) { + this.name = name; + this.dictionary = dictionary; + } + + public String getName() { + return name; + } + + public Dictionary getDictionary() { + return dictionary; + } + + @Override + public String toString() { + return name; + } + + public void setDictionary(Dictionary d) { + this.dictionary = d; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/src/eu/engys/core/project/mesh/FieldItem.java b/src/eu/engys/core/project/mesh/FieldItem.java new file mode 100644 index 0000000..771133d --- /dev/null +++ b/src/eu/engys/core/project/mesh/FieldItem.java @@ -0,0 +1,133 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.mesh; + +import static eu.engys.core.project.mesh.ScalarBarType.BLUE_TO_RED_RAINBOW; + +public class FieldItem { + + public static final int DEFAULT_RESOLUTION = 256; + public static final String SOLID = "Solid Color"; + public static final String INDEXED = "Index"; + public static final String[] COMPONENTS = new String[] { "Magnitude", "X", "Y", "Z" }; + + private int component; + private String name; + private DataType dataType; + private double[] range; + private ScalarBarType scalarBarType; + private int resolution; + private boolean automaticRange; + + public FieldItem(String fieldName, DataType dataType, int component) { + this.name = fieldName; + this.dataType = dataType; + this.component = component; + this.range = new double[] { Double.MAX_VALUE, -Double.MAX_VALUE }; + this.scalarBarType = BLUE_TO_RED_RAINBOW; + this.resolution = DEFAULT_RESOLUTION; + this.automaticRange = true; + } + + public int getComponent() { + return component; + } + + public String getName() { + return name; + } + + public DataType getDataType() { + return dataType; + } + + public void setAutomaticRange(boolean automaticRange) { + this.automaticRange = automaticRange; + } + + public boolean isAutomaticRange() { + return automaticRange; + } + + public void setRange(double[] range) { + this.range = range; + } + + public double[] getRange() { + return range; + } + + public ScalarBarType getScalarBarType() { + return scalarBarType; + } + + public void setScalarBarType(ScalarBarType scalarBarType) { + this.scalarBarType = scalarBarType; + } + + public int getResolution() { + return resolution; + } + + public void setResolution(int resolution) { + this.resolution = resolution; + } + + public enum DataType { + POINT, CELL, NONE; + + public boolean isPoint() { + return this.equals(POINT); + } + + public boolean isCell() { + return this.equals(CELL); + } + + public boolean isNone() { + return this.equals(NONE); + } + } + + @Override + public String toString() { + return name; + } + + public boolean isScalar() { + return ! SOLID.equals(name) && ! INDEXED.equals(name); + } + + public boolean isSolid() { + return SOLID.equals(name); + } + + public boolean isIndexed() { + return INDEXED.equals(name); + } + +} diff --git a/src/eu/engys/core/project/mesh/Mesh.java b/src/eu/engys/core/project/mesh/Mesh.java new file mode 100644 index 0000000..36d87dc --- /dev/null +++ b/src/eu/engys/core/project/mesh/Mesh.java @@ -0,0 +1,201 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.mesh; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.io.input.ReversedLinesFileReader; + +import eu.engys.core.controller.actions.RunMesh; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.util.RegexpUtils; + +public class Mesh { + + private static final String HELYXOS_MESH_START_TAG = "Layer mesh : "; + private static final String HELYX_MESH_START_TAG = "Final mesh : "; + private long numberOfPoints = 0; + private long numberOfCells = 0; + private long numberOfFaces = 0; + private double meshTime = 0; + + private List cellsPerRefinementLevel = new ArrayList<>(); + + private int memorySize = 0; + private double[] bounds = new double[6]; + + private List timeSteps = new LinkedList<>(); + + private Map cellFieldMap = new LinkedHashMap<>(); + private Map pointFieldMap = new LinkedHashMap<>(); + + private Map> timeStepCellFieldsMap = new HashMap>(); + private Map> timeStepPointFieldsMap = new HashMap>(); + private List regions; + + public long getNumberOfPoints() { + return numberOfPoints; + } + + public void setNumberOfPoints(int numberOfPoints) { + this.numberOfPoints = numberOfPoints; + } + + public long getNumberOfCells() { + return numberOfCells; + } + + public void setNumberOfCells(int numberOfCells) { + this.numberOfCells = numberOfCells; + } + + public long getNumberOfFaces() { + return this.numberOfFaces; + } + + public void setNumberOfFaces(int numberOfFaces) { + this.numberOfFaces = numberOfFaces; + } + + public double getMeshTime() { + return meshTime; + } + + public List getCellsPerRefinementLevel() { + return cellsPerRefinementLevel; + } + + public int getMemorySize() { + return memorySize; + } + + public void setMemorySize(int memorySize) { + this.memorySize = memorySize; + } + + public double[] getBounds() { + return bounds; + } + + public void setBounds(double[] bounds) { + this.bounds = bounds; + } + + public List getTimeSteps() { + return timeSteps; + } + + public void setTimeSteps(List timeSteps) { + this.timeSteps = timeSteps; + } + + public List getRegions() { + return regions; + } + public void setRegions(List regions) { + this.regions = regions; + } + + public Map getCellFieldMap() { + return cellFieldMap; + } + + public Map getPointFieldMap() { + return pointFieldMap; + } + + public Map> getTimeStepCellFieldsMap() { + return timeStepCellFieldsMap; + } + + public Map> getTimeStepPointFieldsMap() { + return timeStepPointFieldsMap; + } + + public void readStatistics(Model model) { + Path log = model.getProject().getBaseDir().toPath().resolve(openFOAMProject.LOG).resolve(RunMesh.LOG_NAME); + if (Files.exists(log)) { + try (ReversedLinesFileReader reader = new ReversedLinesFileReader(log.toFile())) { + Stack stack = new Stack<>(); + while (true) { + String line = reader.readLine(); + stack.push(line); + if (stack.peek().startsWith(HELYX_MESH_START_TAG)) { + read(stack, HELYX_MESH_START_TAG); + break; + } else if (stack.peek().startsWith(HELYXOS_MESH_START_TAG)) { + read(stack, HELYXOS_MESH_START_TAG); + break; + } + } + } catch (Exception e) { + } + } + } + + private void read(Stack stack, String startTag) { + while (!stack.isEmpty()) { + String line = stack.pop(); + Pattern pattern1 = Pattern.compile(startTag + "cells:(\\d+)\\s+faces:(\\d+)\\s+points:(\\d+)"); + Matcher matcher1 = pattern1.matcher(line); + if (matcher1.matches()) { + this.numberOfCells = Integer.valueOf(matcher1.group(1)); + this.numberOfFaces = Integer.valueOf(matcher1.group(2)); + this.numberOfPoints = Integer.valueOf(matcher1.group(3)); + } else if (line.startsWith("Cells per refinement level:")) { + this.cellsPerRefinementLevel.clear(); + String row = stack.pop(); + while (!row.startsWith("Writing mesh")) { + Pattern pattern2 = Pattern.compile("\\s+(\\d)\\s+(\\d+)"); + Matcher matcher2 = pattern2.matcher(row); + if (matcher2.matches()) { + this.cellsPerRefinementLevel.add(Integer.valueOf(matcher2.group(2))); + } + row = stack.pop(); + } + } else if (line.startsWith("Finished meshing in")) { + Pattern pattern3 = Pattern.compile("Finished meshing in =\\s+(" + RegexpUtils.DOUBLE + ")\\s+s."); + Matcher matcher3 = pattern3.matcher(line); + if (matcher3.matches()) { + this.meshTime = Double.valueOf(matcher3.group(1)); + } + } + } + } + +} diff --git a/src/eu/engys/core/project/mesh/ScalarBarType.java b/src/eu/engys/core/project/mesh/ScalarBarType.java new file mode 100644 index 0000000..c0371bc --- /dev/null +++ b/src/eu/engys/core/project/mesh/ScalarBarType.java @@ -0,0 +1,350 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.mesh; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.Icon; + +import com.google.common.collect.Lists; + +import eu.engys.util.ui.ResourcesUtil; + +public enum ScalarBarType { + + BLUE_TO_RED_RAINBOW("Rainbow (Blue to Red)", ResourcesUtil.getIcon("scalarbar.rainbow.icon")), + RED_TO_BLUE_RAINBOW("Rainbow (Red to Blue)", ResourcesUtil.getIcon("scalarbar.rainbow.inverted.icon")), + + BLUE_TO_RED_HSV("Blue to Red (HSV)", ResourcesUtil.getIcon("scalarbar.bluetored.hsv.icon")), + RED_TO_BLUE_HSV("Red to Blue (HSV)", ResourcesUtil.getIcon("scalarbar.redtoblue.hsv.icon")), + BLUE_TO_RED_RGB("Blue to Red (RGB)", ResourcesUtil.getIcon("scalarbar.bluetored.rgb.icon")), + RED_TO_BLUE_RGB("Red to Blue (RGB)", ResourcesUtil.getIcon("scalarbar.redtoblue.rgb.icon")), + BLUE_TO_RED_DIV("Blue to Red (Diverging)", ResourcesUtil.getIcon("scalarbar.bluetored.div.icon")), + RED_TO_BLUE_DIV("Red to Blue (Diverging)", ResourcesUtil.getIcon("scalarbar.redtoblue.div.icon")), + + BLUE_TO_YELLOW_HSV("Blue to Yellow (HSV)", ResourcesUtil.getIcon("scalarbar.bluetoyellow.hsv.icon")), + YELLOW_TO_BLUE_HSV("Yellow to Blue (HSV)", ResourcesUtil.getIcon("scalarbar.yellowtoblue.hsv.icon")), + BLUE_TO_YELLOW_RGB("Blue to Yellow (RGB)", ResourcesUtil.getIcon("scalarbar.bluetoyellow.rgb.icon")), + YELLOW_TO_BLUE_RGB("Yellow to Blue (RGB)", ResourcesUtil.getIcon("scalarbar.yellowtoblue.rgb.icon")), + BLUE_TO_YELLOW_DIV("Blue to Yellow (Diverging)", ResourcesUtil.getIcon("scalarbar.bluetoyellow.div.icon")), + YELLOW_TO_BLUE_DIV("Yellow to Blue (Diverging)", ResourcesUtil.getIcon("scalarbar.yellowtoblue.div.icon")), + + BLACK_TO_WHITE("Black to White", ResourcesUtil.getIcon("scalarbar.blacktowhite.icon")), + WHITE_TO_BLACK("White to Black", ResourcesUtil.getIcon("scalarbar.whitetoblack.icon")); + + private String label; + private Icon icon; + + private ScalarBarType(String label, Icon icon) { + this.label = label; + this.icon = icon; + } + + public String getLabel() { + return label; + } + + public List getColors(int resolution) { + switch (label) { + // RAINBOW + case "Rainbow (Blue to Red)": + return getRainbowColors(); + case "Rainbow (Red to Blue)": + return getRainbowColorsInverted(); + // RED TO BLUE + case "Blue to Red (HSV)": + return getBlueToRedHSVColors(resolution); + case "Red to Blue (HSV)": + return getRedToBlueHSVColors(resolution); + case "Blue to Red (RGB)": + return getBlueToRedRGBColors(resolution); + case "Red to Blue (RGB)": + return getRedToBlueRGBColors(resolution); + case "Blue to Red (Diverging)": + return getBlueToRedDivergingColors(resolution); + case "Red to Blue (Diverging)": + return getRedToBlueDivergingColors(resolution); + // BLUE TO YELLOW + case "Blue to Yellow (HSV)": + return getBlueToYellowHSVColors(resolution); + case "Yellow to Blue (HSV)": + return getYellowToBlueHSVColors(resolution); + case "Blue to Yellow (RGB)": + return getBlueToYellowRGBColors(resolution); + case "Yellow to Blue (RGB)": + return getYellowToBlueRGBColors(resolution); + case "Blue to Yellow (Diverging)": + return getBlueToYellowDivergingColors(resolution); + case "Yellow to Blue (Diverging)": + return getYellowToBlueDivergingColors(resolution); + // GRAYSCALE + case "Black to White": + return getBlackToWhiteColors(resolution); + case "White to Black": + return getWhiteToBlackColors(resolution); + default: + return new ArrayList(); + } + } + + public Icon getIcon() { + return icon; + } + + /* + * Utils + */ + + public static Icon getIconByLabel(String label) { + ScalarBarType[] all = values(); + for (ScalarBarType type : all) { + if (type.getLabel().equals(label)) { + return type.getIcon(); + } + } + return null; + } + + public static ScalarBarType getTypeByLabel(String label) { + ScalarBarType[] all = values(); + for (ScalarBarType type : all) { + if (type.getLabel().equals(label)) { + return type; + } + } + return null; + + } + + public static String[] labels() { + ScalarBarType[] all = values(); + String[] labels = new String[all.length]; + for (int i = 0; i < labels.length; i++) { + labels[i] = all[i].getLabel(); + } + return labels; + } + + /***** COLORS *****/ + + /* + * RED TO BLUE + */ + + // HSV (rainbow) + private static List getRainbowColors() { + List colors = new ArrayList<>(); + colors.add(new double[] { 0.667, 0 }); + return colors; + } + + private static List getRainbowColorsInverted() { + List colors = new ArrayList<>(); + colors.add(new double[] { 0, 0.667 }); + return colors; + } + + // HSV (red -> pink -> blue) + private static List getBlueToRedHSVColors(int resolution) { + List colors = new LinkedList<>(); + if (resolution == 1) { + colors.add(new double[] { 0, 0, 1 }); + } else if (resolution == 2) { + colors.add(new double[] { 0, 0, 1 }); + colors.add(new double[] { 1, 0, 0 }); + } else if (resolution > 2) { + int limit1 = (resolution % 2 == 0) ? (resolution / 2) : (resolution - 1)/2; + int limit2 = (resolution - 1)/2; + colors.add(new double[] { 0, 0, 1 }); + for (float i = 1; i < limit1; i++) { + colors.add(new double[] { i / limit1, 0, 1 }); + } + colors.add(new double[] { 1, 0, 1 }); + for (float i = 1; i < limit2; i++) { + colors.add(new double[] { 1, 0, 1 - (i / limit2) }); + } + colors.add(new double[] { 1, 0, 0 }); + } + return colors; + } + + private static List getRedToBlueHSVColors(int resolution) { + return Lists.reverse(getBlueToRedHSVColors(resolution)); + } + + // RGB (red -> blue) + private static List getBlueToRedRGBColors(int resolution) { + List colors = new LinkedList<>(); + if (resolution == 1) { + colors.add(new double[] { 0, 0, 1 }); + } else if (resolution > 1) { + int limit = resolution -1; + colors.add(new double[] { 0, 0, 1 }); + for (float i = 1; i < limit; i++) { + colors.add(new double[] { i / limit, 0, 1 - (i / limit) }); + } + colors.add(new double[] { 1, 0, 0 }); + } + return colors; + } + + private static List getRedToBlueRGBColors(int resolution) { + return Lists.reverse(getBlueToRedRGBColors(resolution)); + } + + // DIVERGING (red -> white -> blue) + private static List getBlueToRedDivergingColors(int resolution) { + List colors = new LinkedList<>(); + if (resolution == 1) { + colors.add(new double[] { 0, 0, 1 }); + } else if (resolution == 2) { + colors.add(new double[] { 0, 0, 1 }); + colors.add(new double[] { 1, 0, 0 }); + } else if (resolution > 2) { + int limit1 = (resolution % 2 == 0) ? (resolution / 2) : (resolution - 1)/2; + int limit2 = (resolution - 1)/2; + colors.add(new double[] { 0, 0, 1 }); + for (float i = 1; i < limit1; i++) { + colors.add(new double[] { i / limit1, i / limit1, 1 }); + } + colors.add(new double[] { 1, 1, 1 }); + for (float i = 1; i < limit2; i++) { + colors.add(new double[] { 1, 1 - (i / limit2), 1 - (i / limit2) }); + } + colors.add(new double[] { 1, 0, 0 }); + } + return colors; + } + + private static List getRedToBlueDivergingColors(int resolution) { + return Lists.reverse(getBlueToRedDivergingColors(resolution)); + } + + /* + * BLUE TO YELLOW + */ + + // HSV (blue -> green -> yellow) + private static List getBlueToYellowHSVColors(int resolution) { + List colors = new LinkedList<>(); + if (resolution == 1) { + colors.add(new double[] { 0, 0, 1 }); + } else if (resolution == 2) { + colors.add(new double[] { 0, 0, 1 }); + colors.add(new double[] { 1, 1, 0 }); + } else if (resolution > 2) { + int limit1 = (resolution % 2 == 0) ? (resolution / 2) : (resolution - 1)/2; + int limit2 = (resolution - 1)/2; + colors.add(new double[] { 0, 0, 1 }); + for (float i = 1; i < limit1; i++) { + colors.add(new double[] { 0, i / limit1, 1 - (i / limit1) }); + } + colors.add(new double[] { 0, 1, 0 }); + for (float i = 1; i < limit2; i++) { + colors.add(new double[] { 1 - (i / limit2), 1, 0 }); + } + colors.add(new double[] { 1, 1, 0 }); + } + return colors; + } + + private static List getYellowToBlueHSVColors(int resolution) { + return Lists.reverse(getBlueToYellowHSVColors(resolution)); + } + + // RGB (blue -> yellow) + private static List getBlueToYellowRGBColors(int resolution) { + List colors = new LinkedList<>(); + if (resolution == 1) { + colors.add(new double[] { 0, 0, 1 }); + } else if (resolution > 1) { + int limit = resolution - 1; + colors.add(new double[] { 0, 0, 1 }); + for (float i = 1; i < limit; i++) { + colors.add(new double[] { i / limit, i / limit, 1 - (i / limit) }); + } + colors.add(new double[] { 1, 1, 0 }); + } + return colors; + } + + private static List getYellowToBlueRGBColors(int resolution) { + return Lists.reverse(getBlueToYellowRGBColors(resolution)); + } + + // DIVERGING (blue -> white -> yellow) + private static List getBlueToYellowDivergingColors(int resolution) { + List colors = new LinkedList<>(); + if (resolution == 1) { + colors.add(new double[] { 0, 0, 1 }); + } else if (resolution == 2) { + colors.add(new double[] { 0, 0, 1 }); + colors.add(new double[] { 1, 1, 0 }); + } else if (resolution > 2) { + int limit1 = (resolution % 2 == 0) ? (resolution / 2) : (resolution - 1)/2; + int limit2 = (resolution - 1)/2; + colors.add(new double[] { 0, 0, 1 }); + for (float i = 1; i < limit1; i++) { + colors.add(new double[] { i / limit1, i / limit1, 1 }); + } + colors.add(new double[] { 1, 1, 1 }); + for (float i = 1; i < limit2; i++) { + colors.add(new double[] { 1, 1, 1 - (i / limit2) }); + } + colors.add(new double[] { 1, 1, 0 }); + } + return colors; + } + + private static List getYellowToBlueDivergingColors(int resolution) { + return Lists.reverse(getBlueToYellowDivergingColors(resolution)); + } + + /* + * GRAYSCALE + */ + private static List getBlackToWhiteColors(int resolution) { + List colors = new LinkedList<>(); + if (resolution == 1) { + colors.add(new double[] { 0, 0, 0 }); + } else if (resolution > 1) { + int limit = resolution - 1; + colors.add(new double[] { 0, 0, 0 }); + for (float i = 1; i < limit; i++) { + colors.add(new double[] { i / (limit), i / (limit), i / (limit) }); + } + colors.add(new double[] { 1, 1, 1 }); + } + return colors; + } + + private static List getWhiteToBlackColors(int resolution) { + return Lists.reverse(getBlackToWhiteColors(resolution)); + } + +} diff --git a/src/eu/engys/core/project/openFOAMProject.java b/src/eu/engys/core/project/openFOAMProject.java new file mode 100644 index 0000000..8c1311d --- /dev/null +++ b/src/eu/engys/core/project/openFOAMProject.java @@ -0,0 +1,159 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project; + +import java.io.File; + +import eu.engys.core.project.constant.ConstantFolder; +import eu.engys.core.project.defaults.Defaults; +import eu.engys.core.project.system.SystemFolder; +import eu.engys.core.project.zero.ZeroFolder; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.progress.SilentMonitor; + +public class openFOAMProject { + + public static final String LOG = "log"; + public static final String HOSTFILE = "hostfile"; + public static final String POST_PROC = "postProcessing"; + public static final String MACHINEFILE = "machinefile"; + + private final File baseDir; + private final boolean parallel; + private final int processors; + + private final SystemFolder system; + private final ConstantFolder constant; + private final ZeroFolder zero; + + public static openFOAMProject createProject(File baseDir, ProgressMonitor monitor) { + ProjectFolderAnalyzer pa = new ProjectFolderAnalyzer(baseDir, monitor); + ProjectFolderStructure structure = pa.checkAll(); + + return structure.isParallel() ? openFOAMProject.newParallelProject(baseDir, structure.getProcessors()) : openFOAMProject.newSerialProject(baseDir); + } + + public static openFOAMProject createProject(CaseParameters parameters) { + return parameters.isParallel() ? openFOAMProject.newParallelProject(parameters.getBaseDir(), parameters.getnProcessors()) : openFOAMProject.newSerialProject(parameters.getBaseDir()); + } + + public static openFOAMProject newSerialProject(File baseDir) { + return new openFOAMProject(baseDir, false, -1); + } + + public static openFOAMProject newDefaultSerialProject(File baseDir, Defaults defaults) { + CreateCase createCase = new CreateCase(defaults, new SilentMonitor()); + CaseParameters caseParams = new CaseParameters(); + caseParams.setParallel(false); + caseParams.setnHierarchy(new int[] { 1, 1, 1 }); + caseParams.setnProcessors(1); + caseParams.setBaseDir(baseDir); + return createCase.create(caseParams); + } + + public static openFOAMProject newParallelProject(File baseDir) { + return new openFOAMProject(baseDir, true, new ProjectFolderAnalyzer(baseDir, null).findProcessorsFolders()); + } + + public static openFOAMProject newParallelProject(File baseDir, int nProcessors) { + return new openFOAMProject(baseDir, true, nProcessors); + } + + public static openFOAMProject newCopy(openFOAMProject project) { + return new openFOAMProject(project); + } + + public static openFOAMProject newCopy(File baseDir, openFOAMProject project) { + return new openFOAMProject(baseDir, project); + } + + private openFOAMProject(File baseDir, boolean parallel, int processors) { + this.baseDir = baseDir; + this.parallel = parallel; + this.processors = processors; + + this.system = new SystemFolder(this); + this.constant = new ConstantFolder(this); + this.zero = new ZeroFolder(this); + } + + private openFOAMProject(File baseDir, openFOAMProject prj) { + this.baseDir = baseDir; + this.parallel = prj.parallel; + this.processors = prj.processors; + + this.system = new SystemFolder(baseDir, prj.getSystemFolder()); + this.constant = new ConstantFolder(baseDir, prj.getConstantFolder()); + this.zero = new ZeroFolder(baseDir, prj.getZeroFolder()); + } + + private openFOAMProject(openFOAMProject prj) { + this.baseDir = prj.baseDir; + this.parallel = prj.parallel; + this.processors = prj.processors; + + this.system = new SystemFolder(baseDir, prj.getSystemFolder()); + this.constant = new ConstantFolder(baseDir, prj.getConstantFolder()); + this.zero = new ZeroFolder(baseDir, prj.getZeroFolder()); + } + + public File getBaseDir() { + return baseDir; + } + public boolean isParallel() { + return parallel; + } + public boolean isSerial() { + return !isParallel(); + } + + public boolean isMeshOnZero() { + ProjectFolderAnalyzer analyzer = new ProjectFolderAnalyzer(getBaseDir(), null).checkSerialOrParallel(); + return analyzer.isParallel_zero() || analyzer.isSerial_zero(); + } + + public int getProcessors() { + return processors; + } + + public ConstantFolder getConstantFolder() { + return constant; + } + + public SystemFolder getSystemFolder() { + return system; + } + + public ZeroFolder getZeroFolder() { + return zero; + } + + @Override + public String toString() { + return "PROJECT [ basedir: " + baseDir + " ] - [ parallel: " + parallel + " ] - [ processors: " + processors + "]"; + } +} diff --git a/src/eu/engys/core/project/runtimefields/RuntimeField.java b/src/eu/engys/core/project/runtimefields/RuntimeField.java new file mode 100644 index 0000000..5fc19ae --- /dev/null +++ b/src/eu/engys/core/project/runtimefields/RuntimeField.java @@ -0,0 +1,40 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.runtimefields; + +public class RuntimeField { + + private String name; + + public RuntimeField(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/src/eu/engys/core/project/runtimefields/RuntimeFields.java b/src/eu/engys/core/project/runtimefields/RuntimeFields.java new file mode 100644 index 0000000..1d4d584 --- /dev/null +++ b/src/eu/engys/core/project/runtimefields/RuntimeFields.java @@ -0,0 +1,95 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.runtimefields; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.core.project.system.ControlDict.FUNCTIONS_KEY; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.ListField; +import eu.engys.core.project.system.ControlDict; +import eu.engys.util.progress.ProgressMonitor; + +public class RuntimeFields extends LinkedHashMap { + + public RuntimeFields() { + super(); + } + + public List fields() { + return new ArrayList<>(values()); + } + + public void load(ControlDict controlDict, ProgressMonitor monitor) { + if (controlDict != null && controlDict.isDictionary(FUNCTIONS_KEY)) { + List functions = controlDict.subDict(FUNCTIONS_KEY).getDictionaries(); + for (Dictionary dictionary : functions) { + loadRuntimeField(dictionary); + } + } else if (controlDict != null && controlDict.isList(FUNCTIONS_KEY)) { + List functions = controlDict.getList(FUNCTIONS_KEY).getListElements(); + for (DefaultElement el : functions) { + if (el instanceof Dictionary) { + Dictionary dictionary = (Dictionary) el; + loadRuntimeField(dictionary); + } + } + } + } + + private void loadRuntimeField(Dictionary dictionary) { + if (dictionary.found(TYPE)) { + String type = dictionary.lookup(TYPE); + if (type.equals("fieldProcess")) { + ListField operations = dictionary.getList("operations"); + for (DefaultElement de : operations.getListElements()) { + if (de instanceof Dictionary) { + Dictionary opDict = (Dictionary) de; + String fieldName = opDict.lookup("fieldName"); + put(fieldName, new RuntimeField(fieldName)); + } + } + } + } + } + + public void removeFields(Dictionary dictionary) { + ListField operations = dictionary.getList("operations"); + for (DefaultElement de : operations.getListElements()) { + if (de instanceof Dictionary) { + Dictionary opDict = (Dictionary) de; + String fieldName = opDict.lookup("fieldName"); + remove(fieldName); + } + } + } + +} diff --git a/src/eu/engys/core/project/state/BuoyancyBuilder.java b/src/eu/engys/core/project/state/BuoyancyBuilder.java new file mode 100644 index 0000000..4e9a147 --- /dev/null +++ b/src/eu/engys/core/project/state/BuoyancyBuilder.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; + +public class BuoyancyBuilder { + + public static void save(Model model, double[] gValue) { + Dictionary g = model.getProject().getConstantFolder().getG(); + if (g != null) { + if (model.getState().getMultiphaseModel().isOn()) { + g.add("value", "(" + gValue[0] + " " + gValue[1] + " " + gValue[2] + ")"); + g.add("dimensions", "[0 1 -2 0 0 0 0]"); + } else if (model.getState().isEnergy()) { + if (model.getState().isBuoyant()) { + g.add("value", "(" + gValue[0] + " " + gValue[1] + " " + gValue[2] + ")"); + } else { + g.add("value", "(0 0 0)"); + } + g.add("dimensions", "[0 1 -2 0 0 0 0]"); + } else { + g.remove("value"); + g.remove("dimensions"); + } + } + // System.out.println("BuoyancyBuilder.save() "+g); + } + +} diff --git a/src/eu/engys/core/project/state/EngysTable15.java b/src/eu/engys/core/project/state/EngysTable15.java new file mode 100644 index 0000000..d2a08bd --- /dev/null +++ b/src/eu/engys/core/project/state/EngysTable15.java @@ -0,0 +1,129 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import java.util.Set; + +import javax.inject.Inject; + +public class EngysTable15 implements Table15 { + + public static final String RHO_CENTRAL_FOAM = "rhoCentralFoam"; + + @Inject + public EngysTable15() { + } + + @Override + public void updateSolverFamilies(State state, Set families) { + if (state.getSolverType().isSegregated()) { + if (state.isLowMach()) { + if (state.isSteady()) { + if (state.getMultiphaseModel().isMultiphase()) { + // NONE + } else { + families.add(SolverFamily.SIMPLE); + } + } else if (state.isTransient()) { + if (state.isCompressible()) { + families.add(SolverFamily.PIMPLE); + } else if (state.isIncompressible()) { + if (state.isEnergy() || state.getMultiphaseModel().isMultiphase()) { + families.add(SolverFamily.PIMPLE); + } else { + families.add(SolverFamily.PIMPLE); + families.add(SolverFamily.PISO); + } + } else { + // NONE + } + } else { + // NONE + } + } else if (state.isHighMach()) { + families.add(SolverFamily.PIMPLE); + families.add(SolverFamily.CENTRAL); + } else { + // NONE + } + } else { + // NONE + } + } + + @Override + public void updateSolver(State state) { + if (state.getSolverType().isSegregated()) { + String solverName = ""; + + if (state.getMultiphaseModel().isMultiphase()) { + /* in modules */ + } else if (state.getSolverFamily().isSimple() && state.isRANS()) { + if (state.isCompressible()) { + if (state.isBuoyant()) { + solverName = BUOYANT_SIMPLE_FOAM; + } else { + solverName = RHO_SIMPLE_FOAM; + } + } else if (state.isIncompressible()) { + if (state.isEnergy()) { + solverName = BUOYANT_BOUSSINESQ_SIMPLE_FOAM; + } else { + solverName = SIMPLE_FOAM; + } + } + } else if (state.getSolverFamily().isPiso()) { + if (state.isIncompressible()) { + solverName = PISO_FOAM; + } + } else if (state.getSolverFamily().isPimple()) { + if (state.isCompressible()) { + if (state.isBuoyant()) { + if (state.isRANS()) { + solverName = BUOYANT_PIMPLE_FOAM; + } + } else { + if (state.isHighMach()) { + solverName = SONIC_FOAM; + } else { + solverName = RHO_PIMPLE_FOAM; + } + } + } else if (state.isIncompressible()) { + if (state.isEnergy()) { + solverName = BUOYANT_BOUSSINESQ_PIMPLE_FOAM; + } else { + solverName = PIMPLE_FOAM; + } + } + } else if (state.getSolverFamily().isCentral()) { + solverName = RHO_CENTRAL_FOAM; + } + state.setSolver(new Solver(solverName)); + } + } + +} diff --git a/src/eu/engys/core/project/state/Flow.java b/src/eu/engys/core/project/state/Flow.java new file mode 100644 index 0000000..116296d --- /dev/null +++ b/src/eu/engys/core/project/state/Flow.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +public enum Flow { + COMPRESSIBLE("Compressible"), INCOMPRESSIBLE("Incompressible"), NONE("None"); + + private String text; + + private Flow(String text) { + this.text = text; + } + + public boolean isCompressible() { + return this == COMPRESSIBLE; + } + + public boolean isIncompressible() { + return this == INCOMPRESSIBLE; + } + + public boolean isNone() { + return this == NONE; + } + + @Override + public String toString() { + return text; + } +} diff --git a/src/eu/engys/core/project/state/Mach.java b/src/eu/engys/core/project/state/Mach.java new file mode 100644 index 0000000..1e2dbee --- /dev/null +++ b/src/eu/engys/core/project/state/Mach.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +public enum Mach { + LOW("Low"), HIGH("High"), NONE("None"); + + private String text; + + private Mach(String text) { + this.text = text; + } + + public boolean isLow() { + return this == LOW; + } + + public boolean isHigh() { + return this == HIGH; + } + + public boolean isNone() { + return this == NONE; + } + + @Override + public String toString() { + return text; + } +} diff --git a/src/eu/engys/core/project/state/Method.java b/src/eu/engys/core/project/state/Method.java new file mode 100644 index 0000000..386463d --- /dev/null +++ b/src/eu/engys/core/project/state/Method.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +public enum Method { + LES("Les"), RANS("Rans"), NONE("None"); + + private String text; + + private Method(String text) { + this.text = text; + } + + public boolean isLes() { + return this == LES; + } + + public boolean isRans() { + return this == RANS; + } + + public boolean isNone() { + return this == NONE; + } + + @Override + public String toString() { + return text; + } +} diff --git a/src/eu/engys/core/project/state/MultiphaseModel.java b/src/eu/engys/core/project/state/MultiphaseModel.java new file mode 100644 index 0000000..7ae2c35 --- /dev/null +++ b/src/eu/engys/core/project/state/MultiphaseModel.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +public class MultiphaseModel { + + public static final String OFF_LABEL = "Off"; + public static final MultiphaseModel OFF = new MultiphaseModel(OFF_LABEL, "", false, false); + + private String label; + private boolean multiphase; + private PhasesNumber phasesNumber; + private boolean dynamic; + private String key; + + public MultiphaseModel(String label, String key, boolean multiphase, boolean dynamic) { + this.label = label; + this.key = key; + this.multiphase = multiphase; + this.dynamic = dynamic; + } + + public String getLabel() { + return label; + } + + public String getKey() { + return key; + } + + public boolean isMultiphase() { + return multiphase; + } + + public boolean isDynamic() { + return dynamic; + } + + public boolean isOff() { + return label.equals(OFF_LABEL); + } + + public boolean isOn() { + return ! label.equals(OFF_LABEL); + } + + public PhasesNumber getPhasesNumber() { + return phasesNumber; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof MultiphaseModel) { + return label.equals(((MultiphaseModel) obj).label); + } + return super.equals(obj); + } +} diff --git a/src/eu/engys/core/project/state/PhaseBuilder.java b/src/eu/engys/core/project/state/PhaseBuilder.java new file mode 100644 index 0000000..72e3b84 --- /dev/null +++ b/src/eu/engys/core/project/state/PhaseBuilder.java @@ -0,0 +1,99 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import static eu.engys.core.modules.materials.MaterialsDatabase.AIR; +import static eu.engys.core.modules.materials.MaterialsDatabase.MERCURY; +import static eu.engys.core.modules.materials.MaterialsDatabase.OIL; +import static eu.engys.core.modules.materials.MaterialsDatabase.WATER; +import eu.engys.core.project.Model; +import eu.engys.core.project.materials.Material; +import eu.engys.core.project.materials.Materials; + +public class PhaseBuilder { + + public static void saveDefaultMaterialsToProject(Model model) { + model.getMaterials().clear(); + if (model.getState().getMultiphaseModel().isMultiphase()) { + checkMultiMaterials(model); + } else { + check1Material(model); + } + } + + private static void check1Material(Model model) { + Materials materials = model.getMaterials(); + if (materials.isEmpty()) { + materials.add(getMaterial(model, AIR)); + } else if (materials.size() > 1) { + int airIndex = 0; + for (int i = 0; i < materials.size(); i++) { + if (materials.get(i).getName().equals(AIR)) { + airIndex = i; + break; + } + } + for (int i = 0; i < materials.size(); i++) { + if (i != airIndex) { + materials.remove(i); + } + } + } + model.materialsChanged(); + } + + private static void checkMultiMaterials(Model model) { + Materials materials = model.getMaterials(); + materials.clear(); + + Material[] knownMaterials = null; + if(model.getState().isIncompressible()){ + knownMaterials = new Material[] { getMaterial(model, AIR), getMaterial(model, WATER), getMaterial(model, OIL), getMaterial(model, MERCURY) }; + } else { + knownMaterials = new Material[] { getMaterial(model, AIR), getMaterial(model, WATER) }; + } + + int phases = model.getState().getPhases(); + + for (int i = 0; i < Math.min(phases, knownMaterials.length); i++) { + materials.add(knownMaterials[i]); + } + for (int i = Math.min(phases, knownMaterials.length); i < phases; i++) { + materials.add(new Material("Air" + i, knownMaterials[0].getDictionary())); + } + + model.materialsChanged(); + } + + public static Material getMaterial(Model model, String materialName) { + if (model.getState().isCompressible()) { + return new Material(materialName, model.getMaterialsDatabase().getCompressibleMaterial(materialName)); + } else { + return new Material(materialName, model.getMaterialsDatabase().getIncompressibleMaterial(materialName)); + } + } + +} diff --git a/src/eu/engys/core/project/state/PhasesNumber.java b/src/eu/engys/core/project/state/PhasesNumber.java new file mode 100644 index 0000000..0a1d32f --- /dev/null +++ b/src/eu/engys/core/project/state/PhasesNumber.java @@ -0,0 +1,45 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +public class PhasesNumber { + private int preferredPhases; + private boolean changePhases; + + public PhasesNumber(int preferredPhases, boolean changePhases) { + this.preferredPhases = preferredPhases; + this.changePhases = changePhases; + } + + public int getPreferredPhases() { + return preferredPhases; + } + + public boolean canChangePhases() { + return changePhases; + } + +} diff --git a/src/eu/engys/core/project/state/ServerState.java b/src/eu/engys/core/project/state/ServerState.java new file mode 100644 index 0000000..c67ae7a --- /dev/null +++ b/src/eu/engys/core/project/state/ServerState.java @@ -0,0 +1,100 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import java.io.Serializable; + +import eu.engys.core.controller.Command; +import eu.engys.core.executor.ExecutorError; +import eu.engys.core.project.SolverState; + +public class ServerState implements Serializable { + + public static final String SOLVER_STATE = "solverState"; + public static final String COMMAND = "command"; + public static final String ERROR = "error"; + + private Command command = Command.NONE; + private SolverState solverState = SolverState.FINISHED; + private ExecutorError error = null; + + public ServerState() { + } + + public ServerState(Command command, SolverState solverState) { + this.command = command; + this.solverState = solverState; + } + + public ServerState(Command command, SolverState solverState, ExecutorError error) { + this.command = command; + this.solverState = solverState; + this.error = error; + } + + public ServerState(ServerState remoteState) { + this.command = remoteState.getCommand(); + this.solverState = remoteState.getSolverState(); + } + + public Command getCommand() { + return command; + } + + public void setCommand(Command command) { + this.command = command; + } + + public SolverState getSolverState() { + return solverState; + } + + public void setSolverState(SolverState solverState) { + this.solverState = solverState; + } + + public ExecutorError getError() { + return error; + } + + public void setError(ExecutorError error) { + this.error = error; + } + + @Override + public String toString() { + return command + " [State: " + solverState + ", Exit Value: " + (error != null ? error : "") + "]"; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ServerState) { + ServerState state = (ServerState) obj; + return this.command.equals(state.command) && this.solverState.equals(state.solverState); + } + return super.equals(obj); + } +} diff --git a/src/eu/engys/core/project/state/SolutionState.java b/src/eu/engys/core/project/state/SolutionState.java new file mode 100644 index 0000000..2855250 --- /dev/null +++ b/src/eu/engys/core/project/state/SolutionState.java @@ -0,0 +1,122 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import eu.engys.util.ui.ChooserPanel; + +public class SolutionState { + + public static final String NONE = "NONE"; + public static final String TRANSIENT = "Transient"; + public static final String STEADY = "Steady"; + public static final String INCOMPRESSIBLE = "Incompressible"; + public static final String COMPRESSIBLE = "Compressible"; + public static final String SEGREGATED = "Segregated"; + public static final String COUPLED = "Coupled"; + public static final String LES_DES = "LES/DES"; + public static final String RANS = "RANS"; + public static final String HI_MACH = "High"; + public static final String LO_MACH = "Low"; + + public String time; + public String flow; + public String turbulence; + public String solver; + public String mach; + + public SolutionState() { + this.time = NONE; + this.flow = NONE; + this.turbulence = NONE; + this.solver = NONE; + this.mach = NONE; + } + + public SolutionState(State state) { + this.time = state.isSteady() ? STEADY : state.isTransient() ? TRANSIENT : NONE; + this.flow = state.isCompressible() ? COMPRESSIBLE : state.isIncompressible() ? INCOMPRESSIBLE : NONE; + this.turbulence = state.isRANS() ? RANS : state.isLES() ? LES_DES : NONE; + this.solver = state.isCoupled() ? COUPLED : state.isSegregated() ? SEGREGATED : NONE; + this.mach = state.isHighMach() ? SolutionState.HI_MACH : state.isLowMach() ? SolutionState.LO_MACH : NONE; + } + + public boolean areSolverTypeAndTimeAndFlowAndTurbulenceChoosen() { + boolean timeChoosen = time != ChooserPanel.NONE; + boolean flowChoosen = flow != ChooserPanel.NONE; + boolean turbulenceChoosen = turbulence != ChooserPanel.NONE; + boolean solverTypeChoosen = solver != ChooserPanel.NONE; + return solverTypeChoosen && timeChoosen && flowChoosen && turbulenceChoosen; + } + + public boolean isLowMach() { + return mach.equals(SolutionState.LO_MACH); + } + public boolean isHighMach() { + return mach.equals(SolutionState.HI_MACH); + } + public boolean isMachNone() { + return mach.equals(NONE); + } + + public boolean isLES() { + return turbulence.equals(SolutionState.LES_DES); + } + public boolean isRANS() { + return turbulence.equals(SolutionState.RANS); + } + + public boolean isTransient() { + return time.equals(SolutionState.TRANSIENT); + } + public boolean isSteady() { + return time.equals(SolutionState.STEADY); + } + public boolean isTimeNone() { + return time.equals(NONE); + } + + + public boolean isSegregated() { + return solver == SolutionState.SEGREGATED; + } + public boolean isCoupled() { + return solver == SolutionState.COUPLED; + } + public boolean isSolverNone() { + return solver == NONE; + } + + public boolean isIncompressible() { + return flow == SolutionState.INCOMPRESSIBLE; + } + public boolean isCompressible() { + return flow == SolutionState.COMPRESSIBLE; + } + public boolean isFlowNone() { + return flow == NONE; + } + +} diff --git a/src/eu/engys/core/project/state/Solver.java b/src/eu/engys/core/project/state/Solver.java new file mode 100644 index 0000000..a0c9df3 --- /dev/null +++ b/src/eu/engys/core/project/state/Solver.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +public class Solver { + + private final String name; + + public static Solver NONE = new Solver(""); + + public Solver(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } + + public boolean isNone() { + return name.isEmpty(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Solver) { + if (obj == this) { + return true; + } + Solver solver = (Solver) obj; + return solver.getName().equals(name); + } + return false; + } + +} diff --git a/src/eu/engys/core/project/state/SolverFamily.java b/src/eu/engys/core/project/state/SolverFamily.java new file mode 100644 index 0000000..f7923ae --- /dev/null +++ b/src/eu/engys/core/project/state/SolverFamily.java @@ -0,0 +1,75 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +public enum SolverFamily { + + COUPLED("Coupled"), + SIMPLE("Simple"), + PISO("Piso"), + PIMPLE("Pimple"), + CENTRAL("Central"), + NONE("None"); + + private String text; + + private SolverFamily(String text) { + this.text = text; + } + + public boolean isCoupled() { + return this == COUPLED; + } + + public boolean isSimple() { + return this == SIMPLE; + } + + public boolean isPimple() { + return this == PIMPLE; + } + + public boolean isPiso() { + return this == PISO; + } + + public boolean isCentral() { + return this == CENTRAL; + } + + public boolean isNone() { + return this == NONE; + } + + public String getKey() { + return text.toUpperCase(); + } + + @Override + public String toString() { + return text; + } +} diff --git a/src/eu/engys/core/project/state/SolverType.java b/src/eu/engys/core/project/state/SolverType.java new file mode 100644 index 0000000..2591787 --- /dev/null +++ b/src/eu/engys/core/project/state/SolverType.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +public enum SolverType { + COUPLED("Coupled"), SEGREGATED("Segregated"), NONE("None"); + + private String text; + + private SolverType(String text) { + this.text = text; + } + + public boolean isCoupled() { + return this == COUPLED; + } + + public boolean isSegregated() { + return this == SEGREGATED; + } + + public boolean isNone() { + return this == NONE; + } + + @Override + public String toString() { + return text; + } +} diff --git a/src/eu/engys/core/project/state/State.java b/src/eu/engys/core/project/state/State.java new file mode 100644 index 0000000..59118ef --- /dev/null +++ b/src/eu/engys/core/project/state/State.java @@ -0,0 +1,405 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import eu.engys.core.project.TurbulenceModel; + +public class State { + + public State() { + + } + + private Time time = Time.NONE; + private Flow flow = Flow.NONE; + private Method method = Method.NONE; + private Mach mach = Mach.NONE; + private Solver solver = Solver.NONE; + private SolverType solverType = SolverType.NONE; + private SolverFamily solverFamily = SolverFamily.NONE; + + private boolean energy; + private boolean buoyant; + private MultiphaseModel multiphaseModel = MultiphaseModel.OFF; + + private int phases = 1; + + private TurbulenceModel turbulenceModel; + + @Override + public String toString() { + return solver + " - " + solverFamily + " - " + time + " - " + flow + " - " + method + (energy ? " - energy" : "") + (buoyant ? " - buoyant" : "") + " - multiphase: "+ multiphaseModel.getLabel() + " with " + phases + " phases" + " - " + mach + "_MACH"; + } + + public Mach getMach() { + return mach; + } + + public void setMach(Mach mach) { + this.mach = mach; + } + + public Method getMethod() { + return method; + } + + public void setMethod(Method method) { + this.method = method; + } + + public Time getTime() { + return time; + } + + public void setTime(Time time) { + this.time = time; + } + + public Flow getFlow() { + return flow; + } + + public void setFlow(Flow flow) { + this.flow = flow; + } + + public void setTimeToSteady() { + this.time = Time.STEADY; + } + + public void setTimeToTransient() { + this.time = Time.TRANSIENT; + } + + public void setTimeToNone() { + this.time = Time.NONE; + } + + public boolean isSteady() { + return time.isSteady(); + } + + public boolean isTransient() { + return time.isTransient(); + } + + public void setFlowToCompressible() { + this.flow = Flow.COMPRESSIBLE; + } + + public void setFlowToIncompressible() { + this.flow = Flow.INCOMPRESSIBLE; + } + + public void setFlowToNONE() { + this.flow = Flow.NONE; + } + + public boolean isCompressible() { + return flow.isCompressible(); + } + + public boolean isIncompressible() { + return flow.isIncompressible(); + } + + public void setMethodToLES() { + this.method = Method.LES; + } + + public void setMethodToRANS() { + this.method = Method.RANS; + } + + public void setMethodToNONE() { + this.method = Method.NONE; + } + + public boolean isLES() { + return method.isLes(); + } + + public boolean isRANS() { + return method.isRans(); + } + + public void setEnergy(boolean energy) { + this.energy = energy; + } + + public boolean isEnergy() { + return energy; + } + + public void setToHighMach() { + this.mach = Mach.HIGH; + } + + public void setToLowMach() { + this.mach = Mach.LOW; + } + + public boolean isLowMach() { + return mach.isLow(); + } + + public boolean isHighMach() { + return mach.isHigh(); + } + + public void setBuoyant(boolean buoyant) { + this.buoyant = buoyant; + } + + public boolean isBuoyant() { + return buoyant; + } + + public TurbulenceModel getTurbulenceModel() { + return turbulenceModel; + } + + public void setTurbulenceModel(TurbulenceModel turbulenceModel) { + this.turbulenceModel = turbulenceModel; + } + + public MultiphaseModel getMultiphaseModel() { + return multiphaseModel; + } + + public void setMultiphaseModel(MultiphaseModel multiphase) { + this.multiphaseModel = multiphase; + } + + public int getPhases() { + return phases; + } + + public void setPhases(int phases) { + this.phases = phases; + } + + public boolean areTimeAndFlowAndTurbulenceChoosen() { + boolean timeChoosen = !time.isNone(); + boolean flowChoosen = !flow.isNone(); + boolean turbulenceChoosen = !method.isNone(); + return timeChoosen && flowChoosen && turbulenceChoosen; + } + + public Solver getSolver() { + return solver; + } + + public void setSolver(Solver solver) { + this.solver = solver; + } + + public SolverType getSolverType() { + return solverType; + } + + public void setSolverType(SolverType solverType) { + this.solverType = solverType; + } + + public boolean isCoupled() { + return solverType.isCoupled(); + } + + public boolean isSegregated() { + return solverType.isSegregated(); + } + + public SolverFamily getSolverFamily() { + return solverFamily; + } + + public void setSolverFamily(SolverFamily solverFamily) { + this.solverFamily = solverFamily; + } + + public void stringToState(String string) { + String[] tokens = string.replace("(", "").replace(")", "").split("\\s+"); + + for (String token : tokens) { + switch (token.trim()) { + case "COUPLED": + setSolverType(SolverType.COUPLED); + setSolverFamily(SolverFamily.COUPLED); + break; + case "SIMPLE": + setTimeToSteady(); + setSolverType(SolverType.SEGREGATED); + setSolverFamily(SolverFamily.SIMPLE); + break; + case "PISO": + setTimeToTransient(); + setSolverType(SolverType.SEGREGATED); + setSolverFamily(SolverFamily.PISO); + break; + case "PIMPLE": + setTimeToTransient(); + setSolverType(SolverType.SEGREGATED); + setSolverFamily(SolverFamily.PIMPLE); + break; + case "CENTRAL": + setTimeToTransient(); + setSolverType(SolverType.SEGREGATED); + setSolverFamily(SolverFamily.CENTRAL); + break; + + case "steady": + setTimeToSteady(); + setSolverType(SolverType.SEGREGATED); + setSolverFamily(SolverFamily.SIMPLE); + break; + case "transient": + setTimeToTransient(); + setSolverType(SolverType.SEGREGATED); + setSolverFamily(SolverFamily.PIMPLE); + break; + + case "compressible": + setEnergy(true); + setFlowToCompressible(); + break; + case "incompressible": + setFlowToIncompressible(); + break; + + case "hiMach": + setToHighMach(); + break; + + case "buoyant": + setBuoyant(true); + setEnergy(true); + break; + +// case "multiphase": +// setMultiphase(true); +// setBuoyant(true); +// break; + + case "ras": + setMethodToRANS(); + setToLowMach(); + break; + case "les": + setMethodToLES(); + setToLowMach(); + break; + + default: + break; + } + } + Solver solver = new Solver(""); + setSolver(solver); + } + + private static final String SPACE = " "; + + /** + * + * @param state + * + * @return (steady incompressible ras) + */ + public String state2String() { + StringBuffer sb = new StringBuffer(); + + sb.append("( "); + + appendState(sb); + + sb.append(")"); + + return sb.toString(); + } + + public void appendState(StringBuffer sb) { + if (isSteady()) { + if (solverType.isCoupled()) { + sb.append("steady"); + sb.append(SPACE); + sb.append("COUPLED"); + } else { + sb.append("SIMPLE"); + } + } else if (isTransient()) { + if (solverType.isCoupled()) { + sb.append("transient"); + sb.append(SPACE); + sb.append("COUPLED"); + } else { + if (solverFamily.isPimple()) { + sb.append("PIMPLE"); + } else if (solverFamily.isCentral()) { + sb.append("CENTRAL"); + } else if (solverFamily.isPiso()) { + sb.append("PISO"); + } + } + } + + sb.append(SPACE); + + if (isCompressible()) + sb.append("compressible"); + else if (isIncompressible()) + sb.append("incompressible"); + + sb.append(SPACE); + + if (isLES()) + sb.append("les"); + else if (isRANS()) + sb.append("ras"); + + if (isHighMach()) { + sb.append(SPACE); + sb.append("hiMach"); + } + + if (getMultiphaseModel().isOn()) { + sb.append(SPACE); + sb.append(getMultiphaseModel().getKey()); + } else { + if (isCompressible()) { + if (isBuoyant()) { + sb.append(SPACE); + sb.append("buoyant"); + } + } else { + if (isEnergy()) { + sb.append(SPACE); + sb.append("buoyant"); + } + } + } + } +} diff --git a/src/eu/engys/core/project/state/StateBuilder.java b/src/eu/engys/core/project/state/StateBuilder.java new file mode 100644 index 0000000..f770c66 --- /dev/null +++ b/src/eu/engys/core/project/state/StateBuilder.java @@ -0,0 +1,542 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import static eu.engys.core.project.constant.ConstantFolder.CONSTANT; +import static eu.engys.core.project.constant.ConstantFolder.FREE_SURFACE_PROPERTIES; +import static eu.engys.core.project.constant.ConstantFolder.G; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMOPHYSICAL_PROPERTIES; +import static eu.engys.core.project.constant.TransportProperties.MATERIAL_NAME_KEY; +import static eu.engys.core.project.constant.TransportProperties.PHASE1_KEY; +import static eu.engys.core.project.constant.TransportProperties.PHASE2_KEY; +import static eu.engys.core.project.constant.TransportProperties.PHASES_KEY; +import static eu.engys.core.project.constant.TransportProperties.TRANSPORT_MODEL_KEY; +import static eu.engys.core.project.constant.TransportProperties.TRANSPORT_PROPERTIES; +import static eu.engys.core.project.constant.TurbulenceProperties.TURBULENCE_PROPERTIES; +import static eu.engys.core.project.system.ControlDict.CONTROL_DICT; +import static eu.engys.core.project.system.FvSchemes.BACKWARD; +import static eu.engys.core.project.system.FvSchemes.DEFAULT; +import static eu.engys.core.project.system.FvSchemes.EULER; +import static eu.engys.core.project.system.FvSchemes.FV_SCHEMES; +import static eu.engys.core.project.system.FvSchemes.LOCAL_EULER_RDELTAT; +import static eu.engys.core.project.system.FvSchemes.STEADY_STATE; +import static eu.engys.core.project.system.FvSolution.FV_SOLUTION; +import static eu.engys.core.project.system.SystemFolder.SYSTEM; + +import java.util.List; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.project.Model; +import eu.engys.core.project.TurbulenceModel; +import eu.engys.core.project.TurbulenceModels; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.constant.ConstantFolder; +import eu.engys.core.project.constant.ThermophysicalProperties; +import eu.engys.core.project.constant.TransportProperties; +import eu.engys.core.project.constant.TurbulenceProperties; +import eu.engys.core.project.defaults.DefaultsProvider; +import eu.engys.core.project.system.FvSchemes; +import eu.engys.core.project.system.FvSolution; +import eu.engys.core.project.system.SystemFolder; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.fields.FieldsDefaults; +import eu.engys.core.project.zero.patches.BoundaryConditionsDefaults; +import eu.engys.util.progress.ProgressMonitor; + +public class StateBuilder { + + private static final Logger logger = LoggerFactory.getLogger(StateBuilder.class); + + public static void changeState(Model model, Set modules) { + logger.info("Project: clear"); + clearProject(model); + + logger.info("Turbulence: saveDefaultsToProject"); + TurbulenceBuilder.saveDefaultsToProject(model, model.getDefaults()); + + logger.info("Modules: saveDefaultsTurbulenceModelsToProject"); + ModulesUtil.saveDefaultsTurbulenceModelsToProject(modules); + + logger.info("State: saveDefaultsToProject"); + StateBuilder.saveDefaultsToProject(model, model.getDefaults()); + + logger.info("Modules: saveDefaultsToProject"); + ModulesUtil.saveDefaultsToProject(modules); + + logger.info("Materials: saveMaterialsToProject"); + PhaseBuilder.saveDefaultMaterialsToProject(model); + + logger.info("Modules: saveMaterialsToProject"); + ModulesUtil.saveDefaultMaterialsToProject(modules); + + logger.info("Fields: clear"); + FieldsDefaults.prepareFields(model.getFields()); + + Fields fields = new Fields(); + if (model.getProject().isParallel()) { + fields.newParallelFields(model.getProject().getProcessors()); + } + + logger.info("Fields: loadFieldsFromDefaults"); + fields.merge(FieldsDefaults.loadFieldsFromDefaults(model.getState(), model.getDefaults(), model.getPatches(), null)); + + logger.info("Modules: loadFieldsFromDefaults"); + fields.merge(ModulesUtil.loadFieldsFromDefaults(modules, null)); + + fields.fixPVisibility(model.getState()); + + model.setFields(fields); + + logger.info("Boundary Conditions: loadBoundaryConditionsFromFields"); + BoundaryConditionsDefaults.loadBoundaryConditionsFromFields(model.getPatches(), model.getFields()); + + logger.info("Boundary Conditions: updateBoundaryConditionsDefaultsByFields"); + BoundaryConditionsDefaults.updateBoundaryConditionsDefaultsByFields(model); + + logger.info("Fire State Changed"); + model.stateChanged(); + + logger.info("FINISHED"); + } + + public static void changeMaterial(Model model, Set modules) { + logger.info("Modules: saveMaterialsToProject"); + ModulesUtil.saveDefaultMaterialsToProject(modules); + + logger.info("Fields: clear"); + FieldsDefaults.prepareFields(model.getFields()); + + Fields fields = new Fields(); + + logger.info("Fields: loadFieldsFromDefaults"); + fields.merge(FieldsDefaults.loadFieldsFromDefaults(model.getState(), model.getDefaults(), model.getPatches(), null)); + + logger.info("Modules: loadFieldsFromDefaults"); + fields.merge(ModulesUtil.loadFieldsFromDefaults(modules, null)); + + fields.fixPVisibility(model.getState()); + + model.setFields(fields); + + logger.info("Boundary Conditions: loadBoundaryConditionsFromFields"); + BoundaryConditionsDefaults.loadBoundaryConditionsFromFields(model.getPatches(), model.getFields()); + + logger.info("Boundary Conditions: updateBoundaryConditionsDefaultsByFields"); + BoundaryConditionsDefaults.updateBoundaryConditionsDefaultsByFields(model); + + logger.info("Fire Materials Changed"); + model.materialsChanged(); + + logger.info("FINISHED"); + } + + public static void saveDefaultsToProject(Model model, DefaultsProvider defaults) { + Dictionary stateDictionary = defaults.getDefaultsFor(model.getState()); + saveToProject(model, stateDictionary); + } + + private static void saveToProject(Model model, Dictionary stateDict) { + if (stateDict == null) + return; + + openFOAMProject prj = model.getProject(); + if (stateDict.found(SYSTEM)) { + Dictionary systemDict = stateDict.subDict(SYSTEM); + if (systemDict.isDictionary(CONTROL_DICT)) { + if (prj.getSystemFolder().getControlDict() == null) + prj.getSystemFolder().setControlDict(systemDict.subDict(CONTROL_DICT)); + else + prj.getSystemFolder().getControlDict().merge(systemDict.subDict(CONTROL_DICT)); + } else { + /* error */ + } + if (systemDict.isDictionary(FV_SCHEMES)) { + if (prj.getSystemFolder().getFvSchemes() == null) + prj.getSystemFolder().setFvSchemes(systemDict.subDict(FV_SCHEMES)); + else + prj.getSystemFolder().getFvSchemes().merge(systemDict.subDict(FV_SCHEMES)); + } else { + /* error */ + } + if (systemDict.isDictionary(FV_SOLUTION)) { + if (prj.getSystemFolder().getFvSolution() == null) { + prj.getSystemFolder().setFvSolution(systemDict.subDict(FV_SOLUTION)); + } else { + prj.getSystemFolder().getFvSolution().merge(systemDict.subDict(FV_SOLUTION)); + } + } else { + /* error */ + } + } + + if (stateDict.found(CONSTANT)) { + Dictionary constantDict = stateDict.subDict(CONSTANT); + + if (constantDict.isDictionary(G)) { + if (prj.getConstantFolder().getG() == null) + prj.getConstantFolder().setG(constantDict.subDict(G)); + else + prj.getConstantFolder().getG().merge(constantDict.subDict(G)); + } + if (constantDict.isDictionary(THERMOPHYSICAL_PROPERTIES)) { + if (prj.getConstantFolder().getThermophysicalProperties() == null) + prj.getConstantFolder().setThermophysicalProperties(constantDict.subDict(THERMOPHYSICAL_PROPERTIES)); + else + prj.getConstantFolder().getThermophysicalProperties().merge(constantDict.subDict(THERMOPHYSICAL_PROPERTIES)); + } + if (constantDict.isDictionary(TRANSPORT_PROPERTIES)) { + if (prj.getConstantFolder().getTransportProperties() == null) + prj.getConstantFolder().setTransportProperties(constantDict.subDict(TRANSPORT_PROPERTIES)); + else + prj.getConstantFolder().getTransportProperties().merge(constantDict.subDict(TRANSPORT_PROPERTIES)); + } + if (constantDict.isDictionary(TURBULENCE_PROPERTIES)) { + if (prj.getConstantFolder().getTurbulenceProperties() == null) + prj.getConstantFolder().setTurbulenceProperties(constantDict.subDict(TURBULENCE_PROPERTIES)); + else + prj.getConstantFolder().getTurbulenceProperties().merge(constantDict.subDict(TURBULENCE_PROPERTIES)); + } + } + } + + /* + * Load + */ + + public static void loadState(Model model, Table15 solversTable, ProgressMonitor monitor) { + SystemFolder systemFolder = model.getProject().getSystemFolder(); + + if (systemFolder != null) { + FvSchemes fvSchemes = systemFolder.getFvSchemes(); + FvSolution fvSolution = systemFolder.getFvSolution(); + + SolverType solverType = readSolverType(fvSolution); + model.getState().setSolverType(solverType); + + Time time = readTime(model, solverType, fvSchemes, monitor); + model.getState().setTime(time); + + Mach mach = readMach(fvSolution, monitor); + model.getState().setMach(mach); + } + + ConstantFolder constantFolder = model.getProject().getConstantFolder(); + if (constantFolder != null) { + Method method = readMethod(constantFolder); + model.getState().setMethod(method); + + ThermophysicalProperties compressible = constantFolder.getThermophysicalProperties(); + TransportProperties incompressible = constantFolder.getTransportProperties(); + + Flow flow = readFlow(compressible, incompressible); + model.getState().setFlow(flow); + + model.getState().setMultiphaseModel(MultiphaseModel.OFF); + + boolean multiphase = readMultiphase(constantFolder); + + boolean energy = readEnergy(model.getState(), constantFolder, multiphase); + model.getState().setEnergy(energy); + + boolean buoyancy = readBuoyancy(model.getState(), constantFolder, multiphase); + model.getState().setBuoyant(buoyancy); + + TurbulenceModel turbulenceModel = readTurbulenceModel(model, model.getState().getSolverType(), constantFolder, monitor); + model.getState().setTurbulenceModel(turbulenceModel); + } + + if (systemFolder != null) { + FvSolution fvSolution = systemFolder.getFvSolution(); + + SolverFamily solverFamily = readSolverFamily(model.getState(), fvSolution); + model.getState().setSolverFamily(solverFamily); + } + + monitor.info(model.getState().toString(), 1); + } + + private static SolverType readSolverType(FvSolution fvSolution) { + if (fvSolution != null) { + if (fvSolution.found(FvSolution.COUPLED)) { + return SolverType.COUPLED; + } else { + return SolverType.SEGREGATED; + } + } else { + return SolverType.NONE; + } + } + + private static SolverFamily readSolverFamily(State state, FvSolution fvSolution) { + if (state.getSolverType().isSegregated()) { + if (state.isLowMach()) { + if (state.isSteady()) { + if (fvSolution != null && fvSolution.found(FvSolution.PIMPLE)) { + return SolverFamily.PIMPLE; + } else { + return SolverFamily.SIMPLE; + } + } else if (state.isTransient()) { + if (state.isCompressible()) { + return SolverFamily.PIMPLE; + } else if (state.isIncompressible()) { + if (state.isEnergy() || state.getMultiphaseModel().isMultiphase()) { + return SolverFamily.PIMPLE; + } else { + if (fvSolution != null && fvSolution.found(FvSolution.PISO)) { + return SolverFamily.PISO; + } else { + return SolverFamily.PIMPLE; + } + } + } else { + return SolverFamily.NONE; + } + } else { + return SolverFamily.NONE; + } + } else if (state.isHighMach()) { + if (fvSolution != null && fvSolution.found(FvSolution.PIMPLE)) { + return SolverFamily.PIMPLE; + } else { + return SolverFamily.CENTRAL; + } + } else { + return SolverFamily.NONE; + } + } else if (state.getSolverType().isCoupled()) { + return SolverFamily.COUPLED; + } else { + return SolverFamily.NONE; + } + } + + private static Time readTime(Model model, SolverType solverType, FvSchemes fvSchemes, ProgressMonitor monitor) { + if (fvSchemes != null) { + Dictionary ddtSchemes = fvSchemes.getDdtSchemes(); + if (ddtSchemes != null) { + if (ddtSchemes.found(DEFAULT)) { + String timeField = ddtSchemes.lookup(DEFAULT); + if (solverType.isCoupled()) { + if (timeField.equals(EULER)) { + return Time.STEADY; + } else if (timeField.equals(BACKWARD)) { + return Time.TRANSIENT; + } + } else if (solverType.isSegregated()) { + if (timeField.equals(STEADY_STATE) || timeField.equals(LOCAL_EULER_RDELTAT)) { + return Time.STEADY; + } else { + return Time.TRANSIENT; + } + } + } else { + monitor.warning("ddtSchemes: bad file structure", 1); + } + } else { + monitor.warning("fvSchemes: no ddtScheme found.", 1); + } + } else { + monitor.warning("fvSchemes: not found", 1); + } + return Time.NONE; + } + + private static Mach readMach(FvSolution fvSolution, ProgressMonitor monitor) { + if (fvSolution != null) { + String sonic = fvSolution.lookup("sonic"); + if ("true".equals(sonic)) { + return Mach.HIGH; + } else { + return Mach.LOW; + } + } else { + monitor.warning("fvSolution: not found", 1); + return Mach.LOW; + } + } + + private static Method readMethod(ConstantFolder constantFolder) { + Dictionary turbPropDict = constantFolder.getTurbulenceProperties(); + if (turbPropDict != null && turbPropDict.found(TurbulenceProperties.SIMULATION_TYPE)) { + String turbType = turbPropDict.lookup(TurbulenceProperties.SIMULATION_TYPE); + if (turbType.startsWith(TurbulenceProperties.RAS)) { + return Method.RANS; + } else if (turbType.startsWith(TurbulenceProperties.LES)) { + return Method.LES; + } else if (turbType.startsWith(TurbulenceProperties.LAMINAR)) { + Dictionary RASProperties = constantFolder.getRASProperties(); + Dictionary LESProperties = constantFolder.getLESProperties(); + if (RASProperties != null && !RASProperties.isEmpty()) { + return Method.RANS; + } else if (LESProperties != null && !LESProperties.isEmpty()) { + return Method.LES; + } + } + } + return Method.NONE; + } + + private static Flow readFlow(ThermophysicalProperties compressible, TransportProperties incompressible) { + if (compressible != null && compressible.found(ThermophysicalProperties.THERMO_TYPE_KEY)) { + return Flow.COMPRESSIBLE; + } else if (incompressible != null) { + if (incompressible.found(TRANSPORT_MODEL_KEY) || incompressible.found(PHASE1_KEY) || incompressible.found(PHASES_KEY)) { + return Flow.INCOMPRESSIBLE; + } + } + return Flow.NONE; + } + + private static boolean readMultiphase(ConstantFolder constantFolder) { + TransportProperties incompressible = constantFolder.getTransportProperties(); + if (incompressible != null) { + if ((incompressible.found(PHASE1_KEY) && incompressible.found(PHASE2_KEY)) || incompressible.found(PHASES_KEY)) { + return true; + } else if (constantFolder.getFileManager().getFile(FREE_SURFACE_PROPERTIES).exists()) { + return true; + } else if (incompressible.found(MATERIAL_NAME_KEY)) { + return false; + } + } + return false; + } + + private static boolean readEnergy(State state, ConstantFolder constantFolder, boolean isMultiphase) { + Dictionary g = constantFolder.getG(); + if (g != null && g.found("value")) { + if (isMultiphase) { + return false; + } else { + return true; + } + } else { + return state.isCompressible(); + } + } + + private static boolean readBuoyancy(State state, ConstantFolder constantFolder, boolean isMultiphase) { + Dictionary g = constantFolder.getG(); + if (g != null && g.found("value")) { + if (isMultiphase) { + return false; + } else { + return isBuoyant(g); + } + } else { + return false; + } + } + + private static TurbulenceModel readTurbulenceModel(Model model, SolverType solverType, ConstantFolder constantFolder, ProgressMonitor monitor) { + if (model.getState().isLES()) { + Dictionary LESProperties = constantFolder.getLESProperties(); + if (LESProperties != null) { + String lesModel = LESProperties.lookup("LESModel"); + return readTurbulenceModelFromState(model, solverType, lesModel, monitor); + } + } else if (model.getState().isRANS()) { + Dictionary RASProperties = constantFolder.getRASProperties(); + if (RASProperties != null) { + String rasModel = RASProperties.lookup("RASModel"); + return readTurbulenceModelFromState(model, solverType, rasModel, monitor); + } + } + return null; + } + + public static TurbulenceModel readTurbulenceModelFromState(Model model, SolverType solverType, String modelName, ProgressMonitor monitor) { + TurbulenceModels turbulenceModels = model.getTurbulenceModels(); + Method method = model.getState().getMethod(); + Flow flow = model.getState().getFlow(); + logger.info("Loading Turbulence model for {} {} {}", solverType, method, flow); + List modelsForState = turbulenceModels.getModelsForState(solverType, method, flow); + if (modelsForState != null && !modelsForState.isEmpty()) { + + TurbulenceModel turbulenceModel = new TurbulenceModel(); + turbulenceModel.setName(modelName); + + int index = modelsForState.indexOf(turbulenceModel); + if (index >= 0) { + return modelsForState.get(index); + } else { + TurbulenceModel firstTurbulenceModel = modelsForState.get(0); + monitor.warning(String.format("%s not found. Changed to %s", modelName, firstTurbulenceModel), 1); + return firstTurbulenceModel; + } + } else { + monitor.warning("Turbulence models not loaded", 1); + return null; + } + } + + private static boolean isBuoyant(Dictionary g) { + String[] gValues = g.lookupArray("value"); + try { + double x = Double.parseDouble(gValues[0]); + double y = Double.parseDouble(gValues[1]); + double z = Double.parseDouble(gValues[2]); + + if (x == 0 && y == 0 && z == 0) { + return false; + } else { + return true; + } + } catch (Exception e) { + return true; + } + } + + /* + * Other + */ + + private static void clearProject(Model model) { + openFOAMProject prj = model.getProject(); + if (prj.getSystemFolder().getControlDict() != null) + prj.getSystemFolder().getControlDict().clear(); + if (prj.getSystemFolder().getFvSchemes() != null) + prj.getSystemFolder().getFvSchemes().clear(); + if (prj.getSystemFolder().getFvSolution() != null) + prj.getSystemFolder().getFvSolution().clear(); + + prj.getConstantFolder().setG(null); + + if (prj.getConstantFolder().getThermophysicalProperties() != null) + prj.getConstantFolder().getThermophysicalProperties(); + if (prj.getConstantFolder().getTransportProperties() != null) + prj.getConstantFolder().getTransportProperties(); + if (prj.getConstantFolder().getTurbulenceProperties() != null) + prj.getConstantFolder().getTurbulenceProperties().clear(); + } + +} diff --git a/src/eu/engys/core/project/state/StateComposer.java b/src/eu/engys/core/project/state/StateComposer.java new file mode 100644 index 0000000..748bac6 --- /dev/null +++ b/src/eu/engys/core/project/state/StateComposer.java @@ -0,0 +1,175 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import eu.engys.core.project.TurbulenceModel; +import eu.engys.core.project.TurbulenceModelType; + +public class StateComposer { + + private State state; + + public static StateComposer newState() { + StateComposer composer = new StateComposer(); + composer.state = new State(); + composer.state.setSolverType(SolverType.SEGREGATED); + return composer; + } + + public StateComposer coupled() { + state.setSolverType(SolverType.COUPLED); + state.setSolverFamily(SolverFamily.COUPLED); + state.setToLowMach(); + return this; + } + + public StateComposer segregated() { + state.setSolverType(SolverType.SEGREGATED); + return this; + } + + public StateComposer steady() { + state.setTimeToSteady(); + return this; + } + + public StateComposer trans() { + state.setTimeToTransient(); + return this; + } + + public StateComposer compressible() { + state.setFlowToCompressible(); + return this; + } + + public StateComposer incompressible() { + state.setFlowToIncompressible(); + return this; + } + + public StateComposer les() { + state.setMethodToLES(); + state.setToLowMach(); + return this; + } + + public StateComposer rans() { + state.setMethodToRANS(); + state.setToLowMach(); + return this; + } + + public StateComposer hiMach() { + state.setToHighMach(); + return this; + } + + public StateComposer buoyant() { + state.setBuoyant(true); + return this; + } + + public StateComposer energy() { + state.setEnergy(true); + return this; + } + + public StateComposer simple() { + state.setSolverFamily(SolverFamily.SIMPLE); + return this; + } + + public StateComposer pimple() { + state.setSolverFamily(SolverFamily.PIMPLE); + return this; + } + + public StateComposer central() { + state.setSolverFamily(SolverFamily.CENTRAL); + return this; + } + + public StateComposer piso() { + state.setSolverFamily(SolverFamily.PISO); + return this; + } + + public StateComposer multiphaseVOF() { + state.setMultiphaseModel(new MultiphaseModel("VOF", "VOF", true, true)); + return this; + } + + public StateComposer multiphaseEuler() { + state.setMultiphaseModel(new MultiphaseModel("Euler-Euler", "MEF", true, false)); + return this; + } + + public StateComposer multiphaseHydro() { + state.setMultiphaseModel(new MultiphaseModel("Hydro", "HYDRO", true, false)); + return this; + } + + public StateComposer multiphaseECOMARINE() { + state.setMultiphaseModel(new MultiphaseModel("ECOMARINE", "ECOMARINE", false, false)); + return this; + } + + public StateComposer laminar() { + state.setTurbulenceModel(new TurbulenceModel("laminar", TurbulenceModelType.LAMINAR)); + return this; + } + + public StateComposer kEquationEddy() { + state.setTurbulenceModel(new TurbulenceModel("k-Equation Eddy", TurbulenceModelType.K_Equation_Eddy)); + return this; + } + + public StateComposer kOmega() { + state.setTurbulenceModel(new TurbulenceModel("kOmegaSST", TurbulenceModelType.K_Omega)); + return this; + } + + public StateComposer kEpsilon() { + state.setTurbulenceModel(new TurbulenceModel("kEpsilon", TurbulenceModelType.K_Epsilon)); + return this; + } + + public StateComposer spalartAllmaras() { + state.setTurbulenceModel(new TurbulenceModel("SpalartAllmaras", TurbulenceModelType.Spalart_Allmaras)); + return this; + } + + public StateComposer phases(int i) { + state.setPhases(i); + return this; + } + + public State getState() { + return state; + } + +} diff --git a/src/eu/engys/core/project/state/Table15.java b/src/eu/engys/core/project/state/Table15.java new file mode 100644 index 0000000..277e844 --- /dev/null +++ b/src/eu/engys/core/project/state/Table15.java @@ -0,0 +1,48 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import java.util.Set; + +public interface Table15 { + + public static final String BUOYANT_BOUSSINESQ_PIMPLE_FOAM = "buoyantBoussinesqPimpleFoam"; + public static final String BUOYANT_BOUSSINESQ_SIMPLE_FOAM = "buoyantBoussinesqSimpleFoam"; + public static final String BUOYANT_PIMPLE_FOAM = "buoyantPimpleFoam"; + public static final String BUOYANT_SIMPLE_FOAM = "buoyantSimpleFoam"; + public static final String COMPRESSIBLE_INTER_FOAM = "compressibleInterFoam"; + public static final String PIMPLE_FOAM = "pimpleFoam"; + public static final String PISO_FOAM = "pisoFoam"; + public static final String RHO_PIMPLE_FOAM = "rhoPimpleFoam"; + public static final String RHO_SIMPLE_FOAM = "rhoSimpleFoam"; + public static final String SIMPLE_FOAM = "simpleFoam"; + public static final String SONIC_FOAM = "sonicFoam"; + + public void updateSolver(State state); + + public void updateSolverFamilies(State state, Set families); + +} diff --git a/src/eu/engys/core/project/state/ThermalState.java b/src/eu/engys/core/project/state/ThermalState.java new file mode 100644 index 0000000..3fea48f --- /dev/null +++ b/src/eu/engys/core/project/state/ThermalState.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + + +public class ThermalState { + private boolean energy; + private boolean buoyancy; + + public ThermalState() { + this.setEnergy(false); + this.setBuoyancy(false); + } + + public ThermalState(State state) { + this.setEnergy(state.isEnergy()); + this.setBuoyancy(state.isBuoyant()); + } + + public boolean isEnergy() { + return energy; + } + public boolean isBuoyancy() { + return buoyancy; + } + + public void setEnergy(boolean energy) { + this.energy = energy; + } + + public void setBuoyancy(boolean buoyancy) { + this.buoyancy = buoyancy; + } + + @Override + public String toString() { + return "Energy: " + (isEnergy()? "ON" : "OFF") + ", Buoyancy: " + (isBuoyancy()? "ON" : "OFF"); + } +} diff --git a/src/eu/engys/core/project/state/Time.java b/src/eu/engys/core/project/state/Time.java new file mode 100644 index 0000000..ade0d81 --- /dev/null +++ b/src/eu/engys/core/project/state/Time.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +public enum Time { + STEADY("Steady"), TRANSIENT("Transient"), NONE("None"); + + private String text; + + private Time(String text) { + this.text = text; + } + + public boolean isSteady() { + return this == STEADY; + } + + public boolean isTransient() { + return this == TRANSIENT; + } + + public boolean isNone() { + return this == NONE; + } + + @Override + public String toString() { + return text; + } +} diff --git a/src/eu/engys/core/project/state/TurbulenceBuilder.java b/src/eu/engys/core/project/state/TurbulenceBuilder.java new file mode 100644 index 0000000..4e6912a --- /dev/null +++ b/src/eu/engys/core/project/state/TurbulenceBuilder.java @@ -0,0 +1,113 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.state; + +import static eu.engys.core.project.constant.TurbulenceProperties.FIELD_MAPS_KEY; +import static eu.engys.core.project.constant.TurbulenceProperties.LES; +import static eu.engys.core.project.constant.TurbulenceProperties.RAS; +import static eu.engys.core.project.constant.TurbulenceProperties.TURBULENCE_PROPERTIES; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.constant.ConstantFolder; +import eu.engys.core.project.defaults.DefaultsProvider; + +public class TurbulenceBuilder { + + private static final Logger logger = LoggerFactory.getLogger(TurbulenceBuilder.class); + + public static void saveDefaultsToProject(Model model, DefaultsProvider defaults) { + State state = model.getState(); + openFOAMProject project = model.getProject(); + + Dictionary turbPropDict = new Dictionary(TURBULENCE_PROPERTIES); + String turbType = RAS; + if (state.isLES()) { + turbType = LES; + } + turbPropDict.add("simulationType", turbType + "Model"); + + if (state.getTurbulenceModel() != null) { + String modelName = state.getTurbulenceModel().getName(); + + Dictionary turbTypeProp = new Dictionary(turbType + "Properties"); + turbTypeProp.add(turbType + "Model", modelName); + turbTypeProp.add("turbulence", "on"); + turbTypeProp.add("printCoeffs", "on"); + + String dictName = ""; + if (state.getSolverType().isCoupled()) { + dictName = "coupledIncompressibleRAS"; + } else if (state.getSolverType().isSegregated()) { + dictName = (state.isCompressible() ? "compressible" : "incompressible") + turbType; + } + + Dictionary tpp = defaults.getDefaultTurbulenceProperties(); + if (tpp != null && tpp.isDictionary(dictName)) { + logger.info("[ {} provider ]: FOUND {} dictionary", defaults.getName(), dictName); + Dictionary subDict = tpp.subDict(dictName); + + if (subDict.isDictionary(modelName + "Coeffs")) { + // prendo i coefficienti del model dal file dei defaults + logger.info("[ {} provider ]: FOUND {} dictionary", defaults.getName(), modelName); + Dictionary defCoeff = subDict.subDict(modelName + "Coeffs"); + + turbTypeProp.add(new Dictionary(defCoeff)); + turbTypeProp.remove(FIELD_MAPS_KEY); + } else { + logger.warn("[ {} provider ]: Cannot find {} dictionary", defaults.getName(), modelName); + } + } else { + logger.warn("[ {} provider ]: Cannot find {} dictionary", defaults.getName(), dictName); + } + + if (state.isLES()) { + String deltaType = turbTypeProp.subDict(modelName + "Coeffs").lookup("delta"); + // System.out.println("TurbulenceBuilder.build() delta: "+deltaType); + turbTypeProp.add("delta", deltaType); + turbTypeProp.subDict(modelName + "Coeffs").remove("delta"); + + turbTypeProp.add(tpp.subDict(deltaType + "Coeffs")); + } + + ConstantFolder constantFolder = project.getConstantFolder(); + constantFolder.setTurbulenceProperties(turbPropDict); + + if (state.isLES()) { + constantFolder.setLESProperties(turbTypeProp); + } else { + constantFolder.setRASProperties(turbTypeProp); + } + } else { + logger.error("Turbulence Model is NULL!"); + } + + } +} diff --git a/src/eu/engys/core/project/system/BlockMeshDict.java b/src/eu/engys/core/project/system/BlockMeshDict.java new file mode 100644 index 0000000..229ab40 --- /dev/null +++ b/src/eu/engys/core/project/system/BlockMeshDict.java @@ -0,0 +1,198 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.system; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.apache.commons.io.FileUtils; + +import eu.engys.core.dictionary.BlockMeshWriter; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.core.dictionary.parser.DictionaryReader2; +import eu.engys.core.dictionary.parser.ListField2; +import eu.engys.core.project.geometry.BoundingBox; + +public class BlockMeshDict extends Dictionary { + + public static final String BLOCK_DICT = "blockMeshDict"; + + public static final String BLOCKS_KEY = "blocks"; + public static final String VERTICES_KEY = "vertices"; + public static final String PATCHES_KEY = "patches"; + public static final String SPACING_KEY = "spacing"; + // public static final String FROM_FILE_KEY = "fromFile"; + public static final String BOUNDARY_KEY = "boundary"; + public static final String ELEMENTS_KEY = "elements"; + + public static final String HEX_KEY = "hex"; + public static final String SIMPLE_GRADING_KEY = "simpleGrading"; + public static final String WALL_KEY = "wall"; + public static final String FROM_FILE_LINE = "fromFile true;"; + + private boolean fromFile; + + public BlockMeshDict() { + super(BLOCK_DICT); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, BLOCK_DICT)); + } + + public BlockMeshDict(File blockMeshFile) { + super(BLOCK_DICT, blockMeshFile); + } + + public void check() throws DictionaryException { + } + + @Override + protected void readDictionaryFromString(String text) { + new DictionaryReader2(this).read(text); + } + + @Override + public void readDictionary(File file) { + new DictionaryReader2(this).read(file); + } + + @Override + protected String write() { + return new BlockMeshWriter(this).write(); + } + + public void setBoundingBox(BoundingBox boundingBox) { + double xmin = boundingBox.getXmin(); + double xmax = boundingBox.getXmax(); + double ymin = boundingBox.getYmin(); + double ymax = boundingBox.getYmax(); + double zmin = boundingBox.getZmin(); + double zmax = boundingBox.getZmax(); + + if (found(SPACING_KEY)) {// only HELYX-OS + double spacing = Double.valueOf(lookup(SPACING_KEY)); + + boolean emptyBoundingBox = (xmin == 0) && (xmax == 0) && (ymin == 0) && (ymax == 0) && (zmin == 0) && (zmax == 0); + + /* aggiungo un po'di spacing */ + xmin -= spacing; + xmax += spacing; + ymin -= spacing; + ymax += spacing; + zmin -= spacing; + zmax += spacing; + + double xDelta = Math.abs(xmax - xmin); + double yDelta = Math.abs(ymax - ymin); + double zDelta = Math.abs(zmax - zmin); + + int xElements = emptyBoundingBox ? 10 : (int) Math.ceil(xDelta / spacing); + int yElements = emptyBoundingBox ? 10 : (int) Math.ceil(yDelta / spacing); + int zElements = emptyBoundingBox ? 10 : (int) Math.ceil(zDelta / spacing); + + // BLOCKS + + ListField2 blocksList = new ListField2(BLOCKS_KEY); + blocksList.add(new FieldElement("", HEX_KEY)); + + ListField2 hexList = new ListField2(""); + hexList.add(new FieldElement("", "0")); + hexList.add(new FieldElement("", "1")); + hexList.add(new FieldElement("", "2")); + hexList.add(new FieldElement("", "3")); + hexList.add(new FieldElement("", "4")); + hexList.add(new FieldElement("", "5")); + hexList.add(new FieldElement("", "6")); + hexList.add(new FieldElement("", "7")); + blocksList.add(hexList); + + ListField2 elementsList = new ListField2(""); + elementsList.add(new FieldElement("", String.valueOf(xElements))); + elementsList.add(new FieldElement("", String.valueOf(yElements))); + elementsList.add(new FieldElement("", String.valueOf(zElements))); + blocksList.add(elementsList); + + blocksList.add(new FieldElement("", SIMPLE_GRADING_KEY)); + + ListField2 lastList = new ListField2(""); + lastList.add(new FieldElement("", "1")); + lastList.add(new FieldElement("", "1")); + lastList.add(new FieldElement("", "1")); + blocksList.add(lastList); + + add(blocksList); + + // VERTICES + + double[] min = new double[] { xmin, ymin, zmin }; + double[] max = emptyBoundingBox ? new double[] { xmax, ymax, zmax } : new double[] { xmin + xElements * spacing, ymin + yElements * spacing, zmin + zElements * spacing }; + + ListField2 verticesList = new ListField2(VERTICES_KEY); + verticesList.add(getPointList(min[0], min[1], min[2])); + verticesList.add(getPointList(max[0], min[1], min[2])); + verticesList.add(getPointList(max[0], max[1], min[2])); + verticesList.add(getPointList(min[0], max[1], min[2])); + verticesList.add(getPointList(min[0], min[1], max[2])); + verticesList.add(getPointList(max[0], min[1], max[2])); + verticesList.add(getPointList(max[0], max[1], max[2])); + verticesList.add(getPointList(min[0], max[1], max[2])); + + add(verticesList); + } + } + + private ListField2 getPointList(double x, double y, double z) { + ListField2 list = new ListField2(""); + list.add(new FieldElement("", String.valueOf(x))); + list.add(new FieldElement("", String.valueOf(y))); + list.add(new FieldElement("", String.valueOf(z))); + return list; + } + + public boolean isFromFile() { + return fromFile; + } + + public void setFromFile(boolean fromFile) { + this.fromFile = fromFile; + } + + public static boolean containsFromFileLine(File file) { + try { + List lines = FileUtils.readLines(file); + for (String line : lines) { + if (line.trim().equals(BlockMeshDict.FROM_FILE_LINE)) { + return true; + } + } + } catch (IOException e) { + return false; + } + return false; + } +} diff --git a/src/eu/engys/core/project/system/CaseSetupDict.java b/src/eu/engys/core/project/system/CaseSetupDict.java new file mode 100644 index 0000000..fc27318 --- /dev/null +++ b/src/eu/engys/core/project/system/CaseSetupDict.java @@ -0,0 +1,48 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.system; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FoamFile; + +public class CaseSetupDict extends Dictionary { + + public static final String CASE_SETUP_DICT = "caseSetupDict"; + + public static final String MATERIALS_KEY = "materials"; + public static final String BINARY_PAIR_DATA_KEY = "binaryPairData"; + + public static final String GLOBAL_KEY = "global"; + + public CaseSetupDict() { + super(CASE_SETUP_DICT); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, CASE_SETUP_DICT)); + } + + public void check() throws DictionaryException { + } +} diff --git a/src/eu/engys/core/project/system/ControlDict.java b/src/eu/engys/core/project/system/ControlDict.java new file mode 100644 index 0000000..70fa657 --- /dev/null +++ b/src/eu/engys/core/project/system/ControlDict.java @@ -0,0 +1,202 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import java.io.File; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.core.dictionary.ListField; + +public class ControlDict extends Dictionary { + + public static final String CONTROL_DICT = "controlDict"; + +// public static final String JPLOT_VALUE = "jplot"; +// public static final String XMGR_VALUE = "xmgr"; +// public static final String GNUPLOT_VALUE = "gnuplot"; + public static final String RAW_VALUE = "raw"; +// public static final String SCIENTIFIC_VALUE = "scientific"; +// public static final String FIXED_VALUE = "fixed"; + public static final String GENERAL_VALUE = "general"; + public static final String COMPRESSED_VALUE = "compressed"; + public static final String UNCOMPRESSED_VALUE = "uncompressed"; +// public static final String BINARY_VALUE = "binary"; + public static final String ASCII_VALUE = "ascii"; + public static final String CLOCK_TIME_VALUE = "clockTime"; + public static final String CPU_TIME_VALUE = "cpuTime"; + public static final String TIME_STEP_VALUE = "timeStep"; + public static final String FIRST_TIME_VALUE = "firstTime"; + public static final String LATEST_TIME_VALUE = "latestTime"; + public static final String FUNCTIONS_KEY = "functions"; + public static final String ADJUSTABLE_RUN_TIME_KEY = "adjustableRunTime"; + public static final String RUN_TIME_VALUE = "runTime"; + public static final String WRITE_INTERVAL_KEY = "writeInterval"; + public static final String WRITE_CONTROL_KEY = "writeControl"; + public static final String PURGE_WRITE_KEY = "purgeWrite"; + public static final String WRITE_FORMAT_KEY = "writeFormat"; + public static final String WRITE_PRECISION_KEY = "writePrecision"; + public static final String WRITE_COMPRESSION_KEY = "writeCompression"; + public static final String TIME_FORMAT_KEY = "timeFormat"; + public static final String TIME_PRECISION_KEY = "timePrecision"; + public static final String GRAPH_FORMAT_KEY = "graphFormat"; + public static final String MAX_DELTA_T_KEY = "maxDeltaT"; + public static final String MAX_ALPHA_CO_KEY = "maxAlphaCo"; + public static final String MAX_CO_KEY = "maxCo"; + public static final String ADJUST_TIME_STEP_KEY = "adjustTimeStep"; + public static final String DELTA_T_KEY = "deltaT"; + public static final String END_TIME_KEY = "endTime"; + public static final String WRITE_NOW_KEY = "writeNow"; + public static final String START_TIME_KEY = "startTime"; + public static final String START_TIME_VALUE = "startTime"; + public static final String START_FROM_KEY = "startFrom"; + public static final String STOP_AT_KEY = "stopAt"; + public static final String RUNTIME_MODIFIABLE_KEY = "runTimeModifiable"; + public static final String INCLUDE_KEY = "include"; + public static final String[] START_FROM_VALUES = { FIRST_TIME_VALUE, LATEST_TIME_VALUE, START_TIME_VALUE }; + public static final String[] WRITE_CONTROL_VALUES = { TIME_STEP_VALUE, RUN_TIME_VALUE, CPU_TIME_VALUE, CLOCK_TIME_VALUE }; +// public static final String[] WRITE_FORMAT_VALUES = { ASCII_VALUE, BINARY_VALUE }; + public static final String[] WRITE_FORMAT_VALUES = { ASCII_VALUE }; + public static final String[] WRITE_COMPRESSION_VALUES = { UNCOMPRESSED_VALUE, COMPRESSED_VALUE }; + public static final String[] TIME_FORMAT_VALUES = { GENERAL_VALUE }; +// public static final String[] TIME_FORMAT_VALUES = { GENERAL_VALUE, FIXED_VALUE, SCIENTIFIC_VALUE }; + public static final String[] GRAPH_FORMAT_VALUE = { RAW_VALUE }; +// public static final String[] GRAPH_FORMAT_VALUE = { RAW_VALUE, GNUPLOT_VALUE, XMGR_VALUE, JPLOT_VALUE }; + + /* + * Radiation + */ + public static final String RADIATION = "radiation"; + public static final String REGION_KEY = "region"; + public static final String FUNCTION_OBJECTS_LIBS_KEY = "functionObjectLibs"; + public static final String SOLVER_OBJECTS_SO_KEY = "( \"libsolverFunctionObjects.so\" )"; + public static final String NON_PARTICIPATING_RADIATION_KEY = "nonParticipatingRadiation"; + + + public static final String SOLAR = "solar"; + public static final String SOLAR_RADIATION_KEY = "solarRadiation"; + public static final String SOURCES_KEY = "sources"; + public static final String TRANSMISSIVITY_KEY = "transmissivity"; + public static final String OUTPUT_CONTROL_KEY = "outputControl"; + public static final String OUTPUT_INTERVAL_KEY = "outputInterval"; + public static final String SOLAR_INTENSITY_KEY = "solarIntensity"; + public static final String SOLAR_DIRECTION_KEY = "solarDirection"; + + + /* + * ELEMENTS + */ + public static final String FA1 = "FA1"; + public static final String LDXZ = "LDxz"; + public static final String AVERAGING_START_TIME = "averagingStartTime"; + public static final String RHO_INF = "rhoInf"; + public static final String U_INF = "Uinf"; + + public ControlDict() { + super(CONTROL_DICT); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, CONTROL_DICT)); + } + + public ControlDict(ControlDict controlDict) { + super(controlDict); + } + + public ControlDict(File controlDictFile) { + this(); + readDictionary(controlDictFile); + } + + public void check() throws DictionaryException { + } + + public boolean isBinary() { + return found("writeFormat") && lookup("writeFormat").equals("binary"); + } + + @Override + public void merge(Dictionary dict) { + if (dict instanceof ControlDict) { + ((ControlDict) dict).functionObjectsToDict(); + } + functionObjectsToDict(); + super.merge(dict); + functionObjectsToList(); + if (dict instanceof ControlDict) { + ((ControlDict) dict).functionObjectsToList(); + } + } + + public void functionObjectsToDict() { + if (found(FUNCTIONS_KEY) && isList(FUNCTIONS_KEY)) { + ListField functionsList = getList(FUNCTIONS_KEY); + Dictionary functionsDict = new Dictionary(FUNCTIONS_KEY); + for (DefaultElement el : functionsList.getListElements()) { + functionsDict.add(el); + } + remove(FUNCTIONS_KEY); + add(functionsDict); + } + } + + public void functionObjectsToList() { + if (found(FUNCTIONS_KEY) && isDictionary(FUNCTIONS_KEY)) { + Dictionary functionsDict = subDict(FUNCTIONS_KEY); + remove(FUNCTIONS_KEY); + for (Dictionary dict : functionsDict.getDictionaries()) { + addToList(FUNCTIONS_KEY, dict); + } + } + } + + public String getValueOnFunctionObject(String foName, String key) { + if (isList(FUNCTIONS_KEY)) { + ListField functions = getList(FUNCTIONS_KEY); + Dictionary foDict = functions.getDictionary(foName); + if (foDict != null) { + if (foDict.found(key)) { + return foDict.lookup(key); + } + } + } else if (isDictionary(FUNCTIONS_KEY)) { + Dictionary functions = subDict(FUNCTIONS_KEY); + Dictionary foDict = functions.subDict(foName); + if (foDict != null) { + if (foDict.found(key)) { + return foDict.lookup(key); + } + } + } + return null; + } + + public void startFromZero() { + add(START_FROM_KEY, START_TIME_VALUE); + add(START_TIME_KEY, "0"); + } +} diff --git a/src/eu/engys/core/project/system/CustomNodeDict.java b/src/eu/engys/core/project/system/CustomNodeDict.java new file mode 100644 index 0000000..4f32cf5 --- /dev/null +++ b/src/eu/engys/core/project/system/CustomNodeDict.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import java.io.File; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FoamFile; + +public class CustomNodeDict extends Dictionary { + + public static final String CUSTOM_NODE_DICT = "customNodeDict"; + + public CustomNodeDict() { + super(CUSTOM_NODE_DICT); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, CUSTOM_NODE_DICT)); + } + + public CustomNodeDict(File customDictFile) { + this(); + readDictionary(customDictFile); + } + + @Override + public void check() throws DictionaryException { + } +} diff --git a/src/eu/engys/core/project/system/DecomposeParDict.java b/src/eu/engys/core/project/system/DecomposeParDict.java new file mode 100644 index 0000000..2f0bf62 --- /dev/null +++ b/src/eu/engys/core/project/system/DecomposeParDict.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.system; + +import java.io.File; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.core.project.Model; +import eu.engys.util.Util; + +public class DecomposeParDict extends Dictionary { + + public static final String DECOMPOSE_PAR_DICT = "decomposeParDict"; + + public static final String NUMBER_OF_SUBDOMAINS_KEY = "numberOfSubdomains"; + public static final String HIERARCHICAL_COEFFS_KEY = "hierarchicalCoeffs"; + public static final String METHOD_KEY = "method"; + public static final String DELTA_KEY = "delta"; + public static final String ORDER_KEY = "order"; + public static final String YXZ_KEY = "yxz"; + public static final String DISTRIBUTED_KEY = "distributed"; + public static final String N_KEY = "n"; + + public static final String HIERARCHICAL_KEY = "hierarchical"; + public static final String SCOTCH_KEY = "scotch"; + + public static final String[] TYPE_KEYS = { HIERARCHICAL_KEY, SCOTCH_KEY }; + + public DecomposeParDict() { + super(DECOMPOSE_PAR_DICT); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, DECOMPOSE_PAR_DICT)); + } + + public DecomposeParDict(DecomposeParDict newDict) { + super(newDict); + } + + public DecomposeParDict(File file) { + this(); + readDictionary(file); + } + + public void check() throws DictionaryException { + } + + public void toHierarchical(Model model) { + if (methodIsScotch()) { + Dictionary newHCDict = new Dictionary(model.getDefaults().getDefaultDecomposeParDict().subDict(HIERARCHICAL_COEFFS_KEY)); + int[] subdomainValues = calculateSubdomainValues(); + int x = subdomainValues[0]; + int y = subdomainValues[1]; + int z = subdomainValues[2]; + newHCDict.add(N_KEY, "(" + x + " " + y + " " + z + ")"); + + add(METHOD_KEY, HIERARCHICAL_KEY); + add(newHCDict); + DictionaryUtils.writeDictionary(model.getProject().getSystemFolder().getFileManager().getFile(), this, null); + } + } + + private int[] calculateSubdomainValues() { + int numberOfSubdomains = Integer.parseInt(lookup(NUMBER_OF_SUBDOMAINS_KEY)); + int[] subdomainValues = Util.getFactorsFor(numberOfSubdomains); + return subdomainValues; + } + + private boolean methodIsScotch() { + return found(METHOD_KEY) && SCOTCH_KEY.equals(lookup(METHOD_KEY)); + } +} diff --git a/src/eu/engys/core/project/system/FvOptions.java b/src/eu/engys/core/project/system/FvOptions.java new file mode 100644 index 0000000..18992a8 --- /dev/null +++ b/src/eu/engys/core/project/system/FvOptions.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FoamFile; + +public class FvOptions extends Dictionary { + public static final String FV_OPTIONS = "fvOptions"; + + public FvOptions() { + super(FV_OPTIONS); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, FV_OPTIONS)); + } + + @Override + public void check() throws DictionaryException { + } +} diff --git a/src/eu/engys/core/project/system/FvSchemes.java b/src/eu/engys/core/project/system/FvSchemes.java new file mode 100644 index 0000000..3660c94 --- /dev/null +++ b/src/eu/engys/core/project/system/FvSchemes.java @@ -0,0 +1,111 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FoamFile; + +public class FvSchemes extends Dictionary { + + public static final String FV_SCHEMES = "fvSchemes"; + public static final String SN_GRAD_SCHEMES = "snGradSchemes"; + public static final String INTERPOLATION_SCHEMES = "interpolationSchemes"; + public static final String LAPLACIAN_SCHEMES = "laplacianSchemes"; + public static final String DIV_SCHEMES = "divSchemes"; + public static final String GRAD_SCHEMES = "gradSchemes"; + public static final String DDT_SCHEMES = "ddtSchemes"; + public static final String DEFAULT = "default"; + public static final String STEADY_STATE = "steadyState"; + public static final String EULER = "Euler"; + public static final String BACKWARD = "backward"; + public static final String LOCAL_EULER_RDELTAT = "localEuler rDeltaT";//LTSInterfoam + + public FvSchemes() { + super(FV_SCHEMES); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, FV_SCHEMES)); + } + + public Dictionary getDdtSchemes() { + return subDict(DDT_SCHEMES); + } + + public Dictionary getGradSchemes() { + return subDict(GRAD_SCHEMES); + } + + public Dictionary getDivSchemes() { + return subDict(DIV_SCHEMES); + } + + public Dictionary getLaplacianSchemes() { + return subDict(LAPLACIAN_SCHEMES); + } + + public Dictionary getInterpolationSchemes() { + return subDict(INTERPOLATION_SCHEMES); + } + + public Dictionary getSnGradSchemes() { + return subDict(SN_GRAD_SCHEMES); + } + + @Override + public void check() throws DictionaryException { + if (found(DDT_SCHEMES)) { + + } else { + throw new DictionaryException(DDT_SCHEMES + " not found"); + } + if (found(GRAD_SCHEMES)) { + + } else { + throw new DictionaryException(GRAD_SCHEMES + " not found"); + } + if (found(DIV_SCHEMES)) { + + } else { + throw new DictionaryException(DIV_SCHEMES + " not found"); + } + if (found(LAPLACIAN_SCHEMES)) { + ; + } else { + throw new DictionaryException(LAPLACIAN_SCHEMES + " not found"); + } + if (found(INTERPOLATION_SCHEMES)) { + ; + } else { + throw new DictionaryException(INTERPOLATION_SCHEMES + " not found"); + } + if (found(SN_GRAD_SCHEMES)) { + ; + } else { + throw new DictionaryException(SN_GRAD_SCHEMES + " not found"); + } + } + +} diff --git a/src/eu/engys/core/project/system/FvSolution.java b/src/eu/engys/core/project/system/FvSolution.java new file mode 100644 index 0000000..62733ff --- /dev/null +++ b/src/eu/engys/core/project/system/FvSolution.java @@ -0,0 +1,67 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FoamFile; + +public class FvSolution extends Dictionary { + + public static final String FV_SOLUTION = "fvSolution"; + + public static final String SIMPLE = "SIMPLE"; + public static final String PIMPLE = "PIMPLE"; + public static final String PISO = "PISO"; + public static final String COUPLED = "COUPLED"; + + public static final String N_OUTER_CORRECTORS_KEY = "nOuterCorrectors"; + public static final String N_NON_ORTHOGONAL_CORRECTORS_KEY = "nNonOrthogonalCorrectors"; + public static final String N_CORRECTORS_KEY = "nCorrectors"; + public static final String RHO_MIN_KEY = "rhoMin"; + public static final String RHO_MAX_KEY = "rhoMax"; + public static final String RELAXATION_FACTORS_KEY = "relaxationFactors"; + public static final String RESIDUAL_CONTROL_KEY = "residualControl"; + public static final String REL_TOLERANCE_KEY = "relTol"; + public static final String TOLERANCE_KEY = "tolerance"; + + public static final String SONIC_KEY = "sonic"; + public static final String HYDRO_KEY = "hydro"; + + public static final String FIELDS_KEY = "fields"; + public static final String EQUATIONS_KEY = "equations"; + public static final String SOLVERS_KEY = "solvers"; + + public FvSolution() { + super(FV_SOLUTION); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, FV_SOLUTION)); + } + + @Override + public void check() throws DictionaryException { + } +} diff --git a/src/eu/engys/core/project/system/MapFieldsDict.java b/src/eu/engys/core/project/system/MapFieldsDict.java new file mode 100644 index 0000000..5108da5 --- /dev/null +++ b/src/eu/engys/core/project/system/MapFieldsDict.java @@ -0,0 +1,128 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import static eu.engys.core.project.system.SystemFolder.SYSTEM; + +import java.io.File; +import java.util.Map; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.dictionary.FoamFile; + +public class MapFieldsDict extends Dictionary { + + public static final String MAP_FIELDS_DICT = "mapFieldsDict"; + + public static final String PATCH_MAP_KEY = "patchMap"; + public static final String CUTTING_PATCHES_KEY = "cuttingPatches"; + public static final String SOURCE_CASE_KEY = "sourceCase"; + public static final String PARALLEL_SOURCE_KEY = "parallelSource"; + public static final String SOURCE_TIME_OPTION_KEY = "sourceTimeOption"; + public static final String SOURCE_TIME_VALUE_KEY = "sourceTimeValue"; + public static final String TARGET_TIME_OPTION_KEY = "targetTimeOption"; + public static final String TARGET_TIME_VALUE_KEY = "targetTimeValue"; + public static final String CONSISTENT_KEY = "consistent"; + + public static final String LATEST_TIME_KEY = "latestTime"; + public static final String ALL_TIMES_KEY = "allTimes"; + public static final String[] SOURCE_TIME_OPTION_KEYS = new String[] { LATEST_TIME_KEY, SOURCE_TIME_VALUE_KEY, ALL_TIMES_KEY }; + public static final String[] TARGET_TIME_OPTION_KEYS = new String[] { LATEST_TIME_KEY, TARGET_TIME_VALUE_KEY, SOURCE_TIME_VALUE_KEY }; + + public MapFieldsDict() { + super(MAP_FIELDS_DICT); + setFoamFile(FoamFile.getDictionaryFoamFile(SYSTEM, MAP_FIELDS_DICT)); + } + + public MapFieldsDict(File file) { + super(file); + } + + public MapFieldsDict(Dictionary dict) { + super(dict); + setFoamFile(FoamFile.getDictionaryFoamFile(SYSTEM, MAP_FIELDS_DICT)); + } + + @Override + public void check() throws DictionaryException { + } + + @Override + public void merge(Dictionary dict) { + if (dict instanceof MapFieldsDict) { + ((MapFieldsDict) dict).functionObjectsToDict(); + } + functionObjectsToDict(); + super.merge(dict); + functionObjectsToList(); + if (dict instanceof MapFieldsDict) { + ((MapFieldsDict) dict).functionObjectsToList(); + } + + } + + private void functionObjectsToDict() { + if (found(PATCH_MAP_KEY)) { + // () is recognized as empty list + boolean isEmptyList = isList(PATCH_MAP_KEY) && getList(PATCH_MAP_KEY).isEmpty(); + boolean isField = isField(PATCH_MAP_KEY); + if (isEmptyList || isField) { + Dictionary functionsDict = new Dictionary(PATCH_MAP_KEY); + if (isField) { + String patchMap = lookup(PATCH_MAP_KEY); + String[] patches = DictionaryUtils.string2StringArray(patchMap); + for (int i = 0; i < patches.length; i += 2) { + String el1 = patches[i]; + String el2 = patches[i + 1]; + functionsDict.add(new FieldElement(el1, el2)); + } + } + remove(PATCH_MAP_KEY); + add(functionsDict); + } + } + } + + private void functionObjectsToList() { + if (found(PATCH_MAP_KEY) && isDictionary(PATCH_MAP_KEY)) { + Dictionary functionsDict = subDict(PATCH_MAP_KEY); + remove(PATCH_MAP_KEY); + Map fieldsMap = functionsDict.getFieldsMap(); + StringBuilder sb = new StringBuilder("("); + for (String key : fieldsMap.keySet()) { + sb.append(key + " "); + sb.append(fieldsMap.get(key) + " "); + } + sb.append(")"); + add(PATCH_MAP_KEY, sb.toString()); + } + } + +} diff --git a/src/eu/engys/core/project/system/RunDict.java b/src/eu/engys/core/project/system/RunDict.java new file mode 100644 index 0000000..b83a2d4 --- /dev/null +++ b/src/eu/engys/core/project/system/RunDict.java @@ -0,0 +1,71 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import java.io.File; + +import eu.engys.core.dictionary.BeanToDict; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.core.project.SolverModel; + +public class RunDict extends Dictionary { + public static final String RUN_DICT = "runDict"; +// public static final String POST_PROC_FILE_MAP = "postProcFileMap"; + public static final String SERVER_STATE = "serverState"; + public static final String REMOTE = "remote"; + public static final String QUEUE = "queue"; + public static final String SERVER_ID = "serverID"; + public static final String LOG_FILE = "logFile"; + public static final String RMI_PORT = "rmiPort"; + public static final String LOG_PORT = "logPort"; + public static final String SSH_PARAMETERS = "sshParameters"; + public static final String QUEUE_PARAMETERS = "queueParameters"; + public static final String MULTI_MACHINE = "multiMachine"; + public static final String HOSTFILE_PATH = "hostfilePath"; + + public RunDict() { + super(RUN_DICT); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, RUN_DICT)); + } + + public RunDict(SolverModel solverModel) { + this(); + merge(BeanToDict.beanToDict(solverModel)); + } + + public RunDict(File runDictFile) { + this(); + readDictionary(runDictFile); + } + + @Override + public void check() throws DictionaryException { + } + +} diff --git a/src/eu/engys/core/project/system/SetFieldsDict.java b/src/eu/engys/core/project/system/SetFieldsDict.java new file mode 100644 index 0000000..744ab07 --- /dev/null +++ b/src/eu/engys/core/project/system/SetFieldsDict.java @@ -0,0 +1,72 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import static eu.engys.core.project.system.SystemFolder.SYSTEM; + +import java.io.File; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FoamFile; + +public class SetFieldsDict extends Dictionary { + + public static final String SET_FIELDS_DICT = "setFieldsDict"; + + public static final String CELL_SET_KEY = "cellSet"; + public static final String VOL_SCALAR_FIELD_VALUE_KEY = "volScalarFieldValue"; + public static final String FIELD_VALUES_KEY = "fieldValues"; + public static final String REGIONS_KEY = "regions"; + public static final String SET_SOURCES_KEY = "setSources"; + public static final String DEFAULT_FIELD_VALUES_KEY = "defaultFieldValues"; + public static final String DEFAULT_VALUE_KEY = "defaultValue"; + + public static final String BOX_TO_CELL_KEY ="boxToCell"; + public static final String SPHERE_TO_CELL_KEY ="sphereToCell"; + public static final String CYLINDER_TO_CELL_KEY ="cylinderToCell"; + public static final String RING_TO_CELL_KEY ="ringToCell"; + + public SetFieldsDict() { + super(SET_FIELDS_DICT); + setFoamFile(FoamFile.getDictionaryFoamFile(SYSTEM, SET_FIELDS_DICT)); + } + + public SetFieldsDict(File file) { + super(file); + } + + public SetFieldsDict(Dictionary dict) { + super(dict); + setFoamFile(FoamFile.getDictionaryFoamFile(SYSTEM, SET_FIELDS_DICT)); + } + + @Override + public void check() throws DictionaryException { + } + +} diff --git a/src/eu/engys/core/project/system/SnappyHexMeshDict.java b/src/eu/engys/core/project/system/SnappyHexMeshDict.java new file mode 100644 index 0000000..5975651 --- /dev/null +++ b/src/eu/engys/core/project/system/SnappyHexMeshDict.java @@ -0,0 +1,288 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import java.io.File; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.FoamFile; + +public class SnappyHexMeshDict extends Dictionary { + + + public static final String SNAPPY_DICT = "snappyHexMeshDict"; + + // GENERAL + public static final String CASTELLATED_MESH_KEY = "castellatedMesh"; + public static final String SNAP_KEY = "snap"; + public static final String ADD_LAYERS_KEY = "addLayers"; + public static final String AUTO_BLOCK_MESH_KEY = "autoBlockMesh"; + public static final String BLOCK_DATA_KEY = "blockData"; + public static final String CRACK_DETECTION_KEY = "crackDetection"; + public static final String CRACK_TOL_KEY = "crackTol"; + public static final String FINAL_DECOMPOSITION_KEY = "finalDecomposition"; + public static final String HIERARCHICAL_KEY = "hierarchical"; + public static final String PTSCOTCH_KEY = "ptscotch"; + public static final String[] DECOMPOSITION_KEYS = new String[] { PTSCOTCH_KEY, HIERARCHICAL_KEY }; + + // CASTELLATED + public static final String CASTELLATED_MESH_CONTROLS_KEY = "castellatedMeshControls"; + + public static final String LOCATION_IN_MESH = "locationInMesh"; + public static final String MAX_LOCAL_CELLS_KEY = "maxLocalCells"; + public static final String MAX_GLOBAL_CELLS_KEY = "maxGlobalCells"; + public static final String MIN_REFINEMENT_CELLS_KEY = "minRefinementCells"; + public static final String N_CELLS_BETWEEN_LEVELS_KEY = "nCellsBetweenLevels"; + public static final String RESOLVE_FEATURE_ANGLE_KEY = "resolveFeatureAngle"; + public static final String FEATURE_REFINE_ANGLE_KEY = "featureRefineAngle"; + public static final String REFINE_SURFACE_BOUNDARY_KEY = "refineSurfaceBoundary"; + public static final String MIN_BAFFLE_ANGLE_KEY = "minBaffleAngle"; + public static final String CURVATURE_REFINE_ANGLE_KEY = "curvatureRefineAngle"; + public static final String ALLOW_FREE_STANDING_ZONE_FACES_KEY = "allowFreeStandingZoneFaces"; + public static final String BALANCE_THEN_REFINE_KEY = "balanceThenRefine"; + public static final String MAX_LOAD_UNBALANCE_KEY = "maxLoadUnbalance"; + public static final String SPLIT_CELLS_KEY = "splitCells"; + public static final String MIN_ZONE_REGION_SIZE_KEY = "minZoneRegionSize"; + + // CASTELLATED-OS + public static final String PLANAR_ANGLE_KEY = "planarAngle"; + + // SNAP + public static final String SNAP_CONTROLS_KEY = "snapControls"; + + public static final String GLOBAL_FEATURE_EDGES_KEY = "globalFeatureEdges"; + public static final String N_SMOOTH_PATCH_KEY = "nSmoothPatch"; + public static final String DIRECT_FEATURE_SNAPPING_KEY = "directFeatureSnapping"; + public static final String TOLERANCE_KEY = "tolerance"; + public static final String REGION_FEATURE_LINES_KEY = "regionFeatureLines"; + public static final String N_RELAX_ITER_SNAP_KEY = "nRelaxIter"; + public static final String GLOBAL_REGION_SNAP_KEY = "globalRegionSnap"; + public static final String SNAP_SURF_BOUNDARY_KEY = "snapSurfBoundary"; + public static final String COLLAPSE_TOL_KEY = "collapseTol"; + public static final String SPLIT_DEGENERATE_CELLS_KEY = "splitDegenerateCells"; + public static final String N_PRE_FEATURE_ITER_KEY = "nPreFeatureIter"; + public static final String EXPLICIT_FEATURE_SNAP_KEY = "explicitFeatureSnap"; + public static final String IMPLICIT_FEATURE_SNAP_KEY = "implicitFeatureSnap"; + public static final String GEOMETRY_FEATURE_LINES_KEY = "geometryFeatureLines"; + public static final String ZONE_FEATURE_SNAPPING_KEY = "zoneFeatureSnapping"; + public static final String N_SOLVER_ITER_KEY = "nSolveIter"; + public static final String N_FEATURE_ITER_KEY = "nFeatureIter"; + public static final String N_OUTER_ITER_KEY = "nOuterIter"; + public static final String N_SLIVER_SMOOTHS_KEY = "nSliverSmooths"; + public static final String ENLARGE_STENCIL_KEY = "enlargeStencil"; + public static final String FEATURE_SNAP_CHECKS_KEY = "featureSnapChecks"; + public static final String SMOOTH_SNAPPED_SURFACE_KEY = "smoothSnappedSurface"; + + // SNAP-OS + public static final String MULTI_REGION_FEATURE_SNAP_KEY = "multiRegionFeatureSnap"; + public static final String N_FEATURE_SNAP_ITER_KEY = "nFeatureSnapIter"; + + // LAYERS + public static final String ADD_LAYERS_CONTROLS_KEY = "addLayersControls"; + + public static final String EXPANSION_RATIO_KEY = "expansionRatio"; + public static final String FINAL_LAYER_THICKNESS_KEY = "finalLayerThickness"; + public static final String RELATIVE_SIZES_KEY = "relativeSizes"; + public static final String MIN_THICKNESS_KEY = "minThickness"; + public static final String FEATURE_ANGLE_MERGE_KEY = "featureAngleMerge"; + public static final String FEATURE_ANGLE_TERMINATE_KEY = "featureAngleTerminate"; + public static final String N_RELAX_ITER_LAYERS_KEY = "nRelaxIter"; + public static final String N_RELAXED_ITER_KEY = "nRelaxedIter"; + public static final String MIN_MEDIAL_AXIS_ANGLE_KEY = "minMedialAxisAngle"; + public static final String NO_ERRORS_KEY = "noErrors"; + public static final String MAX_LAYER_ITER_KEY = "maxLayerIter"; + public static final String MAX_THICKNESS_TO_MEDIAL_RATIO_KEY = "maxThicknessToMedialRatio"; + public static final String MAX_FACE_THICKNESS_RATIO_KEY = "maxFaceThicknessRatio"; + public static final String WRITE_VTK_KEY = "writeVTK"; + public static final String PROJECT_GROWN_UP_KEY = "projectGrownUp"; + public static final String LAYER_RECOVERY_KEY = "layerRecovery"; + public static final String PRE_BALANCE_KEY = "preBalance"; + public static final String GROW_CONCAVE_EDGE_KEY = "growConcaveEdge"; + public static final String GROW_CONVEX_EDGE_KEY = "growConvexEdge"; + public static final String GROW_ZONE_LAYERS_KEY = "growZoneLayers"; + public static final String GROW_UP_PATCHES_KEY = "growUpPatches"; + public static final String N_SMOOTH_SURFACE_NORMALS_KEY = "nSmoothSurfaceNormals"; + public static final String N_SMOOTH_NORMALS_KEY = "nSmoothNormals"; + public static final String MAX_CELL_DISTORTION_KEY = "maxCellDistortion"; + public static final String MAX_PROJECTION_DISTANCE_KEY = "maxProjectionDistance"; + + // LAYERS-OS + public static final String N_GROW_KEY = "nGrow"; + public static final String N_LAYER_ITER_KEY = "nLayerIter"; + public static final String N_BUFFER_CELLS_NO_EXTRUDE_KEY = "nBufferCellsNoExtrude"; + public static final String N_SMOOTH_THICKNESS_KEY = "nSmoothThickness"; + public static final String SLIP_FEATURE_ANGLE_KEY = "slipFeatureAngle"; + public static final String FEATURE_ANGLE_KEY = "featureAngle"; + + // QUALITY + public static final String MESH_QUALITY_CONTROLS_KEY = "meshQualityControls"; + + public static final String N_VOL_SMOOTH_ITER_KEY = "nVolSmoothIter"; + public static final String MAX_NON_ORTHO_KEY = "maxNonOrtho"; + public static final String MAX_BOUNDARY_SKEWNESS_KEY = "maxBoundarySkewness"; + public static final String MAX_INTERNAL_SKEWNESS_KEY = "maxInternalSkewness"; + public static final String MAX_CONCAVE_KEY = "maxConcave"; + public static final String MIN_FLATNESS_KEY = "minFlatness"; + public static final String MIN_VOL_KEY = "minVol"; + public static final String MIN_TET_QUALITY_KEY = "minTetQuality"; + public static final String MIN_AREA_KEY = "minArea"; + public static final String MIN_TWIST_KEY = "minTwist"; + public static final String MIN_DETERMINANT_KEY = "minDeterminant"; + public static final String MIN_FACE_WEIGHT_KEY = "minFaceWeight"; + public static final String MIN_VOL_RATIO_KEY = "minVolRatio"; + public static final String MIN_TRIANGLE_TWIST_KEY = "minTriangleTwist"; + public static final String MIN_VOL_COLLAPSE_RATIO_KEY = "minVolCollapseRatio"; + public static final String MIN_INTERNAL_WARPAGE_KEY = "minInternalWarpage"; + public static final String MAX_BOUNDARY_WARPAGE_KEY = "maxBoundaryWarpage"; + public static final String FACE_FACE_CELLS_KEY = "faceFaceCells"; + public static final String MIN_SNAP_RELATIVE_VOLUME_KEY = "minSnapRelativeVolume"; + public static final String N_SMOOTH_SCALE_KEY = "nSmoothScale"; + public static final String SMOOTH_ALIGNED_EDGES_KEY = "smoothAlignedEdges"; + public static final String ERROR_REDUCTION_KEY = "errorReduction"; + public static final String MIN_SNAP_RELATIVE_TET_VOLUME_KEY = "minSnapRelativeTetVolume"; + public static final String MAX_GAUSS_GREEN_CENTROID_KEY = "maxGaussGreenCentroid"; + public static final String BAFFLE_ALL_POINTS_BOUNDARY_KEY = "baffleAllPointsBoundary"; + + // REPATCH + public static final String REPATCH_REGIONS_KEY = "repatchRegions"; + + public static final String LOCATION_KEY = "location"; + public static final String ZONE_KEY = "zone"; + public static final String EXCLUDE_PATCHES_KEY = "excludePatches"; + public static final String PATCH_KEY = "patch"; + + // WRAPPER + public static final String WRAPPER_KEY = "wrapper"; + + public static final String WRAP_KEY = "wrap"; + public static final String OUTLETS_KEY = "outlets"; + public static final String VOL_SOURCES_KEY = "volSources"; + public static final String VOL_DISTANCE_KEY = "volDistance"; + public static final String MESH_IN_MM_KEY = "meshInMM"; + public static final String MAX_ITER_KEY = "maxIter"; + public static final String WRITE_FIELDS_KEY = "writeFields"; + public static final String INVERT_KEY = "invert"; + public static final String SIGMA_KEY = "sigma"; + public static final String CUTOFF_KEY = "cutoff"; + public static final String EXCLUDE_POINTS_KEY = "excludePoints"; + + // MISC + public static final String DEBUG_KEY = "debug"; + public static final String MERGE_TOLERANCE_KEY = "mergeTolerance"; + + // FEATURES LINES + public static final String FILE_KEY = "file"; + public static final String FEATURES_KEY = "features"; + public static final String REFINE_FEATURE_EDGES_ONLY_KEY = "refineFeatureEdgesOnly"; + + // REFINEMENT SURFACES + REGIONS + public static final String REFINEMENTS_SURFACES_KEY = "refinementSurfaces"; + public static final String REFINEMENTS_REGIONS_KEY = "refinementRegions"; + public static final String PROXIMITY_INCREMENT_KEY = "proximityIncrement"; + + // GEOMETRY + public static final String GEOMETRY_KEY = "geometry"; + public static final String LAYERS_KEY = "layers"; + public static final String GAP_LEVEL_INCREMENT_KEY = "gapLevelIncrement"; + public static final String MAX_CELLS_ACROSS_GAP_KEY = "maxCellsAcrossGap"; + public static final String MAX_LAYER_THICKNESS_KEY = "maxLayerThickness"; + public static final String FCH_KEY = "fch"; + public static final String GROWN_UP_KEY = "grownUp"; + public static final String N_SURFACE_LAYERS_KEY = "nSurfaceLayers"; + + public static final String MODE_KEY = "mode"; + public static final String INSIDE = "inside"; + public static final String OUTSIDE_KEY = "outside"; + public static final String DISTANCE_KEY = "distance"; + public static final String NONE_KEY = "none"; + public static final String TWO_SIDED_KEY = "twoSided"; + + // ZONES + public static final String FACE_TYPE_KEY = "faceType"; + public static final String LEVEL_KEY = "level"; + public static final String LEVELS_KEY = "levels"; + public static final String REGIONS_KEY = "regions"; + public static final String CELL_ZONE_KEY = "cellZone"; + public static final String FACE_ZONE_KEY = "faceZone"; + public static final String CELL_ZONE_INSIDE = "cellZoneInside"; + public static final String IS_CELL_ZONE = "isCellZone"; + + public static final String INTERNAL_KEY = "internal"; + public static final String BOUNDARY_KEY = "boundary"; + public static final String BAFFLE_KEY = "baffle"; + + public static final String BAFFLE_CHECKS_KEY = "baffleChecks"; + + public SnappyHexMeshDict() { + super(SNAPPY_DICT); + setFoamFile(FoamFile.getDictionaryFoamFile(SystemFolder.SYSTEM, SNAPPY_DICT)); + } + + public SnappyHexMeshDict(File snappyHexMeshFile) { + super(snappyHexMeshFile); + } + + public SnappyHexMeshDict(SnappyHexMeshDict snappyHexMeshDict) { + super(snappyHexMeshDict); + } + + public void check() throws DictionaryException { + } + + public Dictionary getGeometry() { + return subDict(GEOMETRY_KEY); + } + + public boolean isAutoBlockMesh() { + return found(AUTO_BLOCK_MESH_KEY) && Boolean.parseBoolean(lookup(AUTO_BLOCK_MESH_KEY)); + } + + // protected void parseDictionary(String text) { + // Pattern pattern = Pattern.compile("features\\s+\\(([^)]*)\\s*\\)\\s*;"); + // Matcher matcher = pattern.matcher(text); + // StringBuffer result = new StringBuffer(); + // String group = null; + // if (matcher.find()) { + // if (matcher.groupCount() == 1) { + // group = matcher.group(1); + // //System.out.println("SnappyHexMeshDict.parseDictionary() "+group); + // } + // matcher.appendReplacement(result, ""); + // matcher.appendTail(result); + // + // text = result.toString(); + // } + // super.parseDictionary(text); + // + // if (group != null && found("castellatedMeshControls")) { + // subDict("castellatedMeshControls").add("features", "("+group+")"); + // } + // + // } + // +} diff --git a/src/eu/engys/core/project/system/SystemFolder.java b/src/eu/engys/core/project/system/SystemFolder.java new file mode 100644 index 0000000..0778f4e --- /dev/null +++ b/src/eu/engys/core/project/system/SystemFolder.java @@ -0,0 +1,463 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system; + +import java.io.File; +import java.util.Set; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryException; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.files.DefaultFileManager; +import eu.engys.core.project.files.FileManager; +import eu.engys.core.project.files.Folder; +import eu.engys.core.project.system.fieldmanipulationfunctionobjects.FieldManipulationFunctionObjectType; +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObjectType; +import eu.engys.util.progress.ProgressMonitor; + +public class SystemFolder implements Folder { + + public static final String SYSTEM = "system"; + + //ECOMARINE + public static final String REGION_KEY = "region"; + public static final String PATCHES_KEY = "patches"; + public static final String EXTRUDE_TO_REGION_MESH_DICT = "extrudeToRegionMeshDict"; + + private BlockMeshDict blockMeshDict; + private SnappyHexMeshDict snappyHexMeshDict; + private FvSchemes fvSchemes; + private FvSolution fvSolution; + private FvOptions fvOptions; + private ControlDict controlDict; + private RunDict runDict; + private SetFieldsDict setFieldsDict; + private MapFieldsDict mapFieldsDict; + private DecomposeParDict decomposeParDict; + + private FileManager fileManager; + + private CustomNodeDict customDict; + + public SystemFolder(openFOAMProject prj) { + fileManager = new DefaultFileManager(new File(prj.getBaseDir(), SYSTEM)); + } + + public SystemFolder(File baseDir, SystemFolder systemFolder) { + fileManager = new DefaultFileManager(new File(baseDir, SYSTEM)); + setBlockMeshDict(systemFolder.getBlockMeshDict()); + setSnappyHexMeshDict(systemFolder.getSnappyHexMeshDict()); + setFvSchemes(systemFolder.getFvSchemes()); + setFvSolution(systemFolder.getFvSolution()); + setFvOptions(systemFolder.getFvOptions()); + setControlDict(systemFolder.getControlDict()); + setRunDict(systemFolder.getRunDict()); +// setSetFieldsDict(systemFolder.getSetFieldsDict()); + setMapFieldsDict(systemFolder.getMapFieldsDict()); + setDecomposeParDict(systemFolder.getDecomposeParDict()); + setCustomNodeDict(systemFolder.getCustomNodeDict()); + } + + @Override + public FileManager getFileManager() { + return fileManager; + } + + public BlockMeshDict getBlockMeshDict() { + return blockMeshDict; + } + + public void setBlockMeshDict(BlockMeshDict dict) throws DictionaryException { + if (dict != null && dict.isFromFile()) { + this.blockMeshDict = dict; + } else { + this.blockMeshDict = new BlockMeshDict(); + blockMeshDict.merge(dict); + } + } + + public SnappyHexMeshDict getSnappyHexMeshDict() { + return snappyHexMeshDict; + } + + public void setSnappyHexMeshDict(Dictionary dict) throws DictionaryException { + this.snappyHexMeshDict = new SnappyHexMeshDict(); + snappyHexMeshDict.merge(dict); + } + + public FvSchemes getFvSchemes() { + return fvSchemes; + } + + public void setFvSchemes(Dictionary dict) throws DictionaryException { + this.fvSchemes = new FvSchemes(); + fvSchemes.merge(dict); + } + + public FvSolution getFvSolution() { + return fvSolution; + } + + public void setFvSolution(Dictionary dict) throws DictionaryException { + this.fvSolution = new FvSolution(); + fvSolution.merge(dict); + fvSolution.check(); + } + + public FvOptions getFvOptions() { + return fvOptions; + } + + public void setFvOptions(Dictionary dict) { + this.fvOptions = new FvOptions(); + fvOptions.merge(dict); + fvOptions.check(); + } + + public ControlDict getControlDict() { + return controlDict; + } + + public void setControlDict(Dictionary dict) throws DictionaryException { + this.controlDict = new ControlDict(); + controlDict.merge(dict); + controlDict.check(); + } + + public RunDict getRunDict() { + return runDict; + } + + public void setRunDict(Dictionary dict) { + this.runDict = new RunDict(); + runDict.merge(dict); + runDict.check(); + } + + public SetFieldsDict getSetFieldsDict() { + return setFieldsDict; + } + + public void setSetFieldsDict(Dictionary dict) { + this.setFieldsDict = new SetFieldsDict(dict); + } + + public MapFieldsDict getMapFieldsDict() { + return mapFieldsDict; + } + + public void setMapFieldsDict(Dictionary dict) { + this.mapFieldsDict = new MapFieldsDict(); + mapFieldsDict.merge(dict); + mapFieldsDict.check(); + } + + public DecomposeParDict getDecomposeParDict() { + return decomposeParDict; + } + + public void setDecomposeParDict(Dictionary dict) throws DictionaryException { + this.decomposeParDict = new DecomposeParDict(); + decomposeParDict.merge(dict); + } + + public CustomNodeDict getCustomNodeDict() { + return customDict; + } + + public void setCustomNodeDict(Dictionary dict) { + this.customDict = new CustomNodeDict(); + customDict.merge(dict); + customDict.check(); + } + + public void write(Model model, ProgressMonitor monitor) { + File systemDir = fileManager.getFile(); + writeBlockMeshDict(monitor); + DictionaryUtils.writeDictionary(systemDir, snappyHexMeshDict, monitor); + DictionaryUtils.writeDictionary(systemDir, decomposeParDict, monitor); + writeControlDict(monitor); + DictionaryUtils.writeDictionary(systemDir, fvSolution, monitor); + DictionaryUtils.writeDictionary(systemDir, fvSchemes, monitor); + DictionaryUtils.writeDictionary(systemDir, fvOptions, monitor); + DictionaryUtils.writeDictionary(systemDir, setFieldsDict, monitor); + DictionaryUtils.writeDictionary(systemDir, runDict, monitor); + DictionaryUtils.writeDictionary(systemDir, customDict, monitor); + DictionaryUtils.writeDictionary(systemDir, mapFieldsDict, monitor); + } + + public void writeControlDict(ProgressMonitor monitor) { + DictionaryUtils.writeDictionary(fileManager.getFile(), controlDict, monitor); + } + + public void writeBlockMeshDict(ProgressMonitor monitor) { + if (!blockMeshDict.isFromFile()) { + DictionaryUtils.writeDictionary(fileManager.getFile(), blockMeshDict, monitor); + } + } + + public void read(Model model, Set ffoTypes, Set mfoTypes, ProgressMonitor monitor) { + File systemFolder = new File(model.getProject().getBaseDir(), SYSTEM); + if (systemFolder.exists() && systemFolder.isDirectory()) { + + readControlDict(model, monitor, systemFolder); + + readFvSolution(model, monitor, systemFolder); + + readFvSchemes(model, monitor, systemFolder); + + readFvOptions(model, monitor, systemFolder); + + readSnappyHexMeshDict(model, monitor, systemFolder); + + readBlockMeshDict(model, monitor, systemFolder); + + readDecomposeParDict(model, monitor, systemFolder); + + readSetFieldsDict(model, monitor, systemFolder); + + readMapFiedsDict(model, monitor, systemFolder); + + readRunDict(model, monitor, systemFolder); + + readCustomDict(model, monitor, systemFolder); + + model.getRuntimeFields().load(controlDict, monitor); + model.runtimeFieldsChanged(); + + model.getFieldManipulationFunctionObjects().load(controlDict, ffoTypes, monitor); + model.fieldManipulationFunctionObjectsChanged(); + + model.getMonitoringFunctionObjects().load(controlDict, mfoTypes, monitor); + model.monitoringFunctionObjectsChanged(); + + if (customDict != null) { + model.getCustom().read(model, customDict, monitor); + model.customChanged(); + } + } + } + + private void readControlDict(Model model, ProgressMonitor monitor, File systemFolder) { + File controlDictFile = new File(systemFolder, ControlDict.CONTROL_DICT); + if (controlDictFile.exists()) { + ControlDict controlDict = new ControlDict(controlDictFile); + try { + setControlDict(controlDict); + controlDict.check(); + monitor.info(ControlDict.CONTROL_DICT, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + getControlDict().functionObjectsToDict(); + } else { + setControlDict(model.getDefaults().getDefaultControlDict()); + monitor.warning(ControlDict.CONTROL_DICT + " not found, the default one will be used", 1); + } + } + + private void readFvSolution(Model model, ProgressMonitor monitor, File systemFolder) { + File fvSolutionFile = new File(systemFolder, FvSolution.FV_SOLUTION); + if (fvSolutionFile.exists()) { + Dictionary fvSolution = new Dictionary(fvSolutionFile); + try { + setFvSolution(fvSolution); + fvSolution.check(); + monitor.info(FvSolution.FV_SOLUTION, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + setFvSolution(model.getDefaults().getDefaultFvSolution()); + monitor.warning(FvSolution.FV_SOLUTION + " not found, the default one will be used", 1); + } + } + + private void readFvSchemes(Model model, ProgressMonitor monitor, File systemFolder) { + File fvSchemesFile = new File(systemFolder, FvSchemes.FV_SCHEMES); + if (fvSchemesFile.exists()) { + Dictionary fvSchemes = new Dictionary(fvSchemesFile); + try { + setFvSchemes(fvSchemes); + fvSchemes.check(); + monitor.info(FvSchemes.FV_SCHEMES, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + setFvSchemes(model.getDefaults().getDefaultFvSchemes()); + monitor.warning(FvSchemes.FV_SCHEMES + " not found, the default one will be used", 1); + } + } + + private void readFvOptions(Model model, ProgressMonitor monitor, File systemFolder) { + File fvOptionsFile = new File(systemFolder, FvOptions.FV_OPTIONS); + if (fvOptionsFile.exists()) { + Dictionary fvOptions = new Dictionary(fvOptionsFile); + try { + setFvOptions(fvOptions); + fvOptions.check(); + monitor.info(FvOptions.FV_OPTIONS, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + setFvOptions(new Dictionary(FvOptions.FV_OPTIONS)); + monitor.warning(FvOptions.FV_OPTIONS + " not found, the default one will be used", 1); + } + } + + private void readSnappyHexMeshDict(Model model, ProgressMonitor monitor, File systemFolder) { + File snappyHexMeshFile = new File(systemFolder, SnappyHexMeshDict.SNAPPY_DICT); + SnappyHexMeshDict snappy = model.getDefaults().getDefaultSnappyHexMeshDict(); + + if (snappyHexMeshFile.exists()) { + SnappyHexMeshDict snappyFromFile = new SnappyHexMeshDict(snappyHexMeshFile); + snappy.merge(snappyFromFile); + setSnappyHexMeshDict(snappy); + try { + snappyHexMeshDict.check(); + monitor.info(SnappyHexMeshDict.SNAPPY_DICT, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + setSnappyHexMeshDict(snappy); + monitor.warning(SnappyHexMeshDict.SNAPPY_DICT + " not found, the default one will be used", 1); + } + } + + private void readBlockMeshDict(Model model, ProgressMonitor monitor, File systemFolder) { + File blockMeshFile = new File(systemFolder, BlockMeshDict.BLOCK_DICT); + if (blockMeshFile.exists()) { + BlockMeshDict dict = null; + if (BlockMeshDict.containsFromFileLine(blockMeshFile)) { + dict = new BlockMeshDict(); + dict.setFromFile(true); + } else { + dict = new BlockMeshDict(blockMeshFile); + dict.setFromFile(false); + } + + try { + setBlockMeshDict(dict); + blockMeshDict.check(); + monitor.info(BlockMeshDict.BLOCK_DICT, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + setBlockMeshDict(model.getDefaults().getDefaultBlockMeshDict()); + monitor.warning(BlockMeshDict.BLOCK_DICT + " not found, the default one will be used", 1); + } + } + + private void readDecomposeParDict(Model model, ProgressMonitor monitor, File systemFolder) { + File decomposeParFile = new File(systemFolder, DecomposeParDict.DECOMPOSE_PAR_DICT); + if (decomposeParFile.exists()) { + Dictionary dict = new DecomposeParDict(decomposeParFile); + try { + setDecomposeParDict(dict); + decomposeParDict.check(); + monitor.info(DecomposeParDict.DECOMPOSE_PAR_DICT, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + setDecomposeParDict(model.getDefaults().getDefaultDecomposeParDict()); + monitor.warning(DecomposeParDict.DECOMPOSE_PAR_DICT+ " not found, the default one will be used", 1); + } + } + + private void readSetFieldsDict(Model model, ProgressMonitor monitor, File systemFolder) { + File setFieldsDictFile = new File(systemFolder, SetFieldsDict.SET_FIELDS_DICT); + if (setFieldsDictFile.exists()) { + Dictionary dict = new SetFieldsDict(setFieldsDictFile); + try { + setSetFieldsDict(dict); + setFieldsDict.check(); + monitor.info(SetFieldsDict.SET_FIELDS_DICT, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + monitor.warning(SetFieldsDict.SET_FIELDS_DICT + " NOT FOUND", 1); + } + } + + private void readMapFiedsDict(Model model, ProgressMonitor monitor, File systemFolder) { + File mapFieldsDictFile = new File(systemFolder, MapFieldsDict.MAP_FIELDS_DICT); + if (mapFieldsDictFile.exists()) { + Dictionary dict = new MapFieldsDict(mapFieldsDictFile); + try { + setMapFieldsDict(dict); + mapFieldsDict.check(); + monitor.info(MapFieldsDict.MAP_FIELDS_DICT, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + setMapFieldsDict(model.getDefaults().getDefaultMapFieldsDict()); + monitor.warning(MapFieldsDict.MAP_FIELDS_DICT + " not found, the default one will be used", 1); + } + } + + private void readRunDict(Model model, ProgressMonitor monitor, File systemFolder) { + File runDictFile = new File(systemFolder, RunDict.RUN_DICT); + if (runDictFile.exists()) { + RunDict dict = new RunDict(runDictFile); + try { + setRunDict(dict); + runDict.check(); + monitor.info(RunDict.RUN_DICT, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + monitor.warning(RunDict.RUN_DICT + " NOT FOUND", 1); + } + } + + private void readCustomDict(Model model, ProgressMonitor monitor, File systemFolder) { + File customNodeDictFile = new File(systemFolder, CustomNodeDict.CUSTOM_NODE_DICT); + if (customNodeDictFile.exists()) { + try { + Dictionary dict = new CustomNodeDict(customNodeDictFile); + setCustomNodeDict(dict); + customDict.check(); + monitor.info(CustomNodeDict.CUSTOM_NODE_DICT, 1); + } catch (DictionaryException e) { + monitor.warning(e.getMessage(), 1); + } + } else { + monitor.warning(CustomNodeDict.CUSTOM_NODE_DICT + " NOT FOUND", 1); + } + } + +} diff --git a/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObject.java b/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObject.java new file mode 100644 index 0000000..88c491c --- /dev/null +++ b/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObject.java @@ -0,0 +1,61 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.fieldmanipulationfunctionobjects; + +import eu.engys.core.dictionary.Dictionary; + +public class FieldManipulationFunctionObject { + + private FieldManipulationFunctionObjectType type; + private Dictionary dictionary; + + public FieldManipulationFunctionObject(FieldManipulationFunctionObjectType type, Dictionary dictionary) { + this.type = type; + this.dictionary = dictionary; + } + + public String getName() { + return dictionary.getName(); + } + + public FieldManipulationFunctionObjectType getType() { + return type; + } + + public Dictionary getDictionary() { + return dictionary; + } + + public void setDictionary(Dictionary dictionary) { + this.dictionary = dictionary; + } + + @Override + public String toString() { + return getName(); + } +} diff --git a/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObjectPanel.java b/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObjectPanel.java new file mode 100644 index 0000000..88d7516 --- /dev/null +++ b/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObjectPanel.java @@ -0,0 +1,47 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.fieldmanipulationfunctionobjects; + +import javax.swing.JComponent; + +public interface FieldManipulationFunctionObjectPanel { + + void layoutPanel(); + + void load(FieldManipulationFunctionObject... fos); + + void save(FieldManipulationFunctionObject fo); + + JComponent getPanel(); + + void update(); + + void start(); + + void stop(); + +} diff --git a/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObjectType.java b/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObjectType.java new file mode 100644 index 0000000..bfe6bab --- /dev/null +++ b/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObjectType.java @@ -0,0 +1,40 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.system.fieldmanipulationfunctionobjects; + +import eu.engys.core.dictionary.Dictionary; + +public interface FieldManipulationFunctionObjectType { + + public abstract String getLabel(); + + public abstract String getKey(); + + public abstract Dictionary getDefaultDictionary(); + + public abstract FieldManipulationFunctionObjectPanel createPanel(); + +} diff --git a/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObjects.java b/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObjects.java new file mode 100644 index 0000000..02ff6bc --- /dev/null +++ b/src/eu/engys/core/project/system/fieldmanipulationfunctionobjects/FieldManipulationFunctionObjects.java @@ -0,0 +1,165 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.system.fieldmanipulationfunctionobjects; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.core.project.system.ControlDict.FUNCTIONS_KEY; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.ControlDict; +import eu.engys.util.progress.ProgressMonitor; + +public class FieldManipulationFunctionObjects extends ArrayList { + + private static Logger logger = LoggerFactory.getLogger(FieldManipulationFunctionObjects.class); + + public FieldManipulationFunctionObjects() { + super(); + } + + /* + * Save + */ + + public void save(Model model, Set types, ProgressMonitor monitor) { + ControlDict controlDict = model.getProject().getSystemFolder().getControlDict(); + controlDict.functionObjectsToDict(); + Dictionary newFunctions = new Dictionary(FUNCTIONS_KEY); + + if (controlDict.found(FUNCTIONS_KEY)) { + + Dictionary oldFunctions = controlDict.subDict(FUNCTIONS_KEY); + + keepOldFunctionObjects_UnknownType(types, oldFunctions, newFunctions); + + } + + for (FieldManipulationFunctionObject fo : this) { + newFunctions.add(fo.getDictionary()); + } + + addFunctionObjectLibs(model, newFunctions); + + controlDict.add(newFunctions); + controlDict.functionObjectsToList(); + } + + public void keepOldFunctionObjects_UnknownType(Set types, Dictionary oldFunctions, Dictionary newFunctions) { + for (Dictionary d : oldFunctions.getDictionaries()) { + if (d.found(TYPE)) { + String type = d.lookup(TYPE); + if (!isKnownFunctionObjectType(types, type)) { + newFunctions.add(new Dictionary(d)); + } + } + } + } + + private void addFunctionObjectLibs(Model model, Dictionary newFunctions) { + Dictionary defaultFunctions = model.getDefaults().getDefaultFunctions(); + for (Dictionary function : newFunctions.getDictionaries()) { + String type = function.lookup(TYPE); + if (defaultFunctions.found(type)) { + function.add("functionObjectLibs", defaultFunctions.subDict(type).lookup("functionObjectLibs")); + } + } + } + + /* + * LOAD + */ + + public void load(ControlDict controlDict, Set types, ProgressMonitor monitor) { + if (controlDict != null && controlDict.isDictionary(FUNCTIONS_KEY)) { + List functions = controlDict.subDict(FUNCTIONS_KEY).getDictionaries(); + for (Dictionary dictionary : functions) { + dictionaryToFunction(dictionary, types); + } + } else if (controlDict != null && controlDict.isList(FUNCTIONS_KEY)) { + List functions = controlDict.getList(FUNCTIONS_KEY).getListElements(); + for (DefaultElement el : functions) { + if (el instanceof Dictionary) { + Dictionary dictionary = (Dictionary) el; + dictionaryToFunction(dictionary, types); + } + } + } + } + + private void dictionaryToFunction(Dictionary dictionary, Set types) { + if (dictionary.found(TYPE)) { + String type = dictionary.lookup(TYPE); + if (isKnownFunctionObjectType(types, type)) { + add(createFunctionObject(dictionary, types, type)); + } else { + logger.warn("Unknown Function Object TYPE {}", type); + } + } + } + + private FieldManipulationFunctionObject createFunctionObject(Dictionary dictionary, Set types, String type) { + FieldManipulationFunctionObjectType foType = getFunctionObjectTypeByKey(types, type); + return new FieldManipulationFunctionObject(foType, dictionary); + } + + public Map toMap() { + Map map = new HashMap(); + for (FieldManipulationFunctionObject zone : this) { + map.put(zone.getName(), zone); + } + return Collections.unmodifiableMap(map); + } + + public boolean isKnownFunctionObjectType(Set types, String typeKey) { + for (FieldManipulationFunctionObjectType type : types) { + if (type.getKey().equals(typeKey)) { + return true; + } + } + return false; + } + + private FieldManipulationFunctionObjectType getFunctionObjectTypeByKey(Set types, String typeKey) { + for (FieldManipulationFunctionObjectType type : types) { + if (type.getKey().equals(typeKey)) { + return type; + } + } + return null; + } +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/FakeParser.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/FakeParser.java new file mode 100644 index 0000000..0e0ab76 --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/FakeParser.java @@ -0,0 +1,74 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import java.io.File; + +public class FakeParser implements Parser { + + @Override + public void init() { + } + + @Override + public void end() { + } + + @Override + public TimeBlocks updateParsing() throws Exception { + return null; + } + + @Override + public boolean checkTimeBlockConsistency(TimeBlocks newTimeBlocks) { + return true; + } + + @Override + public void clear() { + } + + @Override + public File getFile() { + return null; + } + + @Override + public boolean isValidTimeRow(String row) { + return false; + } + + @Override + public boolean isValidDataRow(String row) { + return false; + } + + @Override + public String getKey() { + return ""; + } +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObject.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObject.java new file mode 100644 index 0000000..5a4450e --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObject.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import eu.engys.core.dictionary.Dictionary; + +public class MonitoringFunctionObject { + + private MonitoringFunctionObjectType type; + private Dictionary dictionary; + private ParserView view; + + public MonitoringFunctionObject(MonitoringFunctionObjectType type, Dictionary dictionary) { + this.type = type; + this.dictionary = dictionary; + } + + public String getName() { + return dictionary.getName(); + } + + public MonitoringFunctionObjectType getType() { + return type; + } + + public Dictionary getDictionary() { + return dictionary; + } + + public void setDictionary(Dictionary dictionary) { + this.dictionary = dictionary; + } + + @Override + public String toString() { + return getName(); + } + + public ParserView getView() { + return view; + } + + public void setView(ParserView view) { + this.view = view; + } +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObjectPanel.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObjectPanel.java new file mode 100644 index 0000000..00052b9 --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObjectPanel.java @@ -0,0 +1,49 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import javax.swing.JComponent; + +public interface MonitoringFunctionObjectPanel { + + void layoutPanel(); + + void load(MonitoringFunctionObject... fos); + + void save(MonitoringFunctionObject fo); + + JComponent getPanel(); + + MonitoringFunctionObjectPanel getDisabledPanel(MonitoringFunctionObject fos); + + void update(); + + void start(); + + void stop(); + +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObjectType.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObjectType.java new file mode 100644 index 0000000..b832921 --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObjectType.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import eu.engys.core.dictionary.Dictionary; + +public interface MonitoringFunctionObjectType { + + public abstract String getLabel(); + + public abstract String getKey(); + + public abstract Dictionary getDefaultDictionary(); + + public abstract MonitoringFunctionObjectPanel createPanel(); + + public abstract ParserFactory getFactory(); + +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObjects.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObjects.java new file mode 100644 index 0000000..6aff8e1 --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/MonitoringFunctionObjects.java @@ -0,0 +1,198 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.core.project.system.ControlDict.FUNCTIONS_KEY; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.system.ControlDict; +import eu.engys.util.progress.ProgressMonitor; + +public class MonitoringFunctionObjects extends ArrayList { + + private static Logger logger = LoggerFactory.getLogger(MonitoringFunctionObjects.class); + + public MonitoringFunctionObjects() { + super(); + } + + /* + * Save + */ + + public void save(Model model, Set types, ProgressMonitor monitor) { + ControlDict controlDict = model.getProject().getSystemFolder().getControlDict(); + controlDict.functionObjectsToDict(); + Dictionary newFunctions = new Dictionary(FUNCTIONS_KEY); + + if (controlDict.found(FUNCTIONS_KEY)) { + + Dictionary oldFunctions = controlDict.subDict(FUNCTIONS_KEY); + + keepOldFunctionObjects_UnknownType(types, oldFunctions, newFunctions); + + deleteOldFunctionObjects_KnownType_Removed(model, types, oldFunctions); + } + + for (MonitoringFunctionObject fo : this) { + newFunctions.add(fo.getDictionary()); + } + + addFunctionObjectLibs(model, newFunctions); + + controlDict.add(newFunctions); + controlDict.functionObjectsToList(); + } + + public void keepOldFunctionObjects_UnknownType(Set types, Dictionary oldFunctions, Dictionary newFunctions) { + for (Dictionary d : oldFunctions.getDictionaries()) { + if (d.found(TYPE)) { + String type = d.lookup(TYPE); + if (!isKnownFunctionObjectType(types, type)) { + newFunctions.add(new Dictionary(d)); + } + } + } + } + + public void deleteOldFunctionObjects_KnownType_Removed(Model model, Set types, Dictionary oldFunctions) { + for (Dictionary d : oldFunctions.getDictionaries()) { + if (d.found(TYPE)) { + String type = d.lookup(TYPE); + if (isKnownFunctionObjectType(types, type)) { + if (!contains(d.getName())) { + File postProcFolder = new File(model.getProject().getBaseDir(), openFOAMProject.POST_PROC); + File foFolder = new File(postProcFolder, d.getName()); + if (foFolder.exists()) { + logger.warn("{} function object deleted", d.getName()); + FileUtils.deleteQuietly(foFolder); + } + } + } + } + } + } + + private boolean contains(String foName) { + for (MonitoringFunctionObject fo : this) { + if (fo.getName().equals(foName)) { + return true; + } + } + return false; + } + + private void addFunctionObjectLibs(Model model, Dictionary newFunctions) { + Dictionary defaultFunctions = model.getDefaults().getDefaultFunctions(); + for (Dictionary function : newFunctions.getDictionaries()) { + String type = function.lookup(TYPE); + if (defaultFunctions.found(type)) { + function.add("functionObjectLibs", defaultFunctions.subDict(type).lookup("functionObjectLibs")); + } + } + } + + /* + * LOAD + */ + + public void load(ControlDict controlDict, Set types, ProgressMonitor monitor) { + if (controlDict != null && controlDict.isDictionary(FUNCTIONS_KEY)) { + List functions = controlDict.subDict(FUNCTIONS_KEY).getDictionaries(); + for (Dictionary dictionary : functions) { + dictionaryToFunction(dictionary, types); + } + } else if (controlDict != null && controlDict.isList(FUNCTIONS_KEY)) { + List functions = controlDict.getList(FUNCTIONS_KEY).getListElements(); + for (DefaultElement el : functions) { + if (el instanceof Dictionary) { + Dictionary dictionary = (Dictionary) el; + dictionaryToFunction(dictionary, types); + } + } + } + } + + private void dictionaryToFunction(Dictionary dictionary, Set types) { + if (dictionary.found(TYPE)) { + String type = dictionary.lookup(TYPE); + if (isKnownFunctionObjectType(types, type)) { + add(createFunctionObject(dictionary, types, type)); + } else { + logger.warn("Unknown Function Object TYPE {}", type); + } + } + } + + private MonitoringFunctionObject createFunctionObject(Dictionary dictionary, Set types, String type) { + MonitoringFunctionObjectType foType = getFunctionObjectTypeByKey(types, type); + MonitoringFunctionObject fo = new MonitoringFunctionObject(foType, dictionary); + return fo; + } + + public Map toMap() { + Map map = new HashMap(); + for (MonitoringFunctionObject zone : this) { + map.put(zone.getName(), zone); + } + return Collections.unmodifiableMap(map); + } + + public boolean isKnownFunctionObjectType(Set types, String typeKey) { + for (MonitoringFunctionObjectType type : types) { + if (type.getKey().equals(typeKey)) { + return true; + } + } + return false; + } + + private MonitoringFunctionObjectType getFunctionObjectTypeByKey(Set types, String typeKey) { + for (MonitoringFunctionObjectType type : types) { + if (type.getKey().equals(typeKey)) { + return type; + } + } + return null; + } +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/Parser.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/Parser.java new file mode 100644 index 0000000..f84510d --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/Parser.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import java.io.File; + +public interface Parser { + + void init(); + + void end(); + + void clear(); + + File getFile(); + + TimeBlocks updateParsing() throws Exception; + + boolean isValidTimeRow(String row); + + boolean isValidDataRow(String row); + + String getKey(); + + boolean checkTimeBlockConsistency(TimeBlocks newTimeBlocks); + +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/ParserFactory.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/ParserFactory.java new file mode 100644 index 0000000..efe831a --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/ParserFactory.java @@ -0,0 +1,39 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import java.util.List; + +public interface ParserFactory { + + void deleteUselessLogFiles(MonitoringFunctionObject functionObject); + + List createParsers(MonitoringFunctionObject functionObject); + + ParserView createView(MonitoringFunctionObject functionObject); + +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/ParserView.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/ParserView.java new file mode 100644 index 0000000..53e5bfa --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/ParserView.java @@ -0,0 +1,73 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import java.util.List; + +import javax.swing.JComponent; + +import eu.engys.core.report.Exporter; + +public interface ParserView { + + public void reset(); + public void showLoading(); + public void stopLoading(); + public void handleSolverStarted(); + void clearData(); + + public void handleFunctionObjectChanged(); + + public JComponent getPanel(); + + public boolean isParsingEnabled(); + + public void setParsingEnabled(boolean parsingEnabled); + + void updateParsing(List newTimeBlocks); + + public String getKey(); + + public void stop(); + + void showLogFile(); + + void setCrosshairVisibile(boolean visible); + + void exportToExcel(); + + void exportToCSV(); + + void exportToPNG(); + + List gerReportParsersList(); + + Exporter getExporter(); + + + +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/TimeBlock.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/TimeBlock.java new file mode 100644 index 0000000..bbdff86 --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/TimeBlock.java @@ -0,0 +1,67 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; + +public class TimeBlock implements Serializable { + + private Double time; + private Map unitsMap; + + public TimeBlock(Double time) { + this.time = time; + this.unitsMap = new LinkedHashMap(); + } + + public Map getUnitsMap() { + return unitsMap; + } + + public int getSize() { + return unitsMap.size(); + } + + public Double getTime() { + return time; + } + + public void setTime(Double time) { + this.time = time; + } + + @Override + public String toString() { + StringBuffer rowstring = new StringBuffer(); + for (String var : getUnitsMap().keySet()) { + rowstring.append(var + " "); + } + return "TIME BLOCK " + getTime() + " ROW KEYS: " + rowstring.toString(); + } +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/TimeBlockUnit.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/TimeBlockUnit.java new file mode 100644 index 0000000..d5175b3 --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/TimeBlockUnit.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import java.io.Serializable; + +public abstract class TimeBlockUnit implements Serializable { + + private String varName; + + public TimeBlockUnit(String varName) { + this.varName = varName; + } + + public String getVarName() { + return varName; + } + + public void setVarName(String varName) { + this.varName = varName; + } + + @Override + public String toString() { + return "[" + getVarName() + "]"; + } + +} diff --git a/src/eu/engys/core/project/system/monitoringfunctionobjects/TimeBlocks.java b/src/eu/engys/core/project/system/monitoringfunctionobjects/TimeBlocks.java new file mode 100644 index 0000000..a2b84d6 --- /dev/null +++ b/src/eu/engys/core/project/system/monitoringfunctionobjects/TimeBlocks.java @@ -0,0 +1,158 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.system.monitoringfunctionobjects; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import com.google.common.collect.Lists; + +public class TimeBlocks implements Iterable, Serializable { + + private static final long serialVersionUID = 42L; + + private List list; + Object mutex; + + private String key; + + public TimeBlocks(String key) { + this.key = key; + list = new LinkedList<>(); + mutex = this; + } + + public TimeBlocks() { + this(""); + } + + public TimeBlocks(List blocks) { + this(); + if (!blocks.isEmpty()) { + for (TimeBlocks tb : blocks) { + addAll(tb); + } + this.key = blocks.get(0).getKey(); + } + } + + public void setKey(String key) { + synchronized (mutex) { + this.key = key; + } + } + + public String getKey() { + synchronized (mutex) { + return key; + } + } + + public void clear() { + synchronized (mutex) { + list.clear(); + } + } + + public String toString() { + synchronized (mutex) { + return list.toString(); + } + } + + public int size() { + synchronized (mutex) { + return list.size(); + } + } + + public boolean isEmpty() { + synchronized (mutex) { + return list.isEmpty(); + } + } + + public boolean addAll(TimeBlocks blocks) { + synchronized (mutex) { + return list.addAll(Lists.newArrayList(blocks)); + } + } + + public boolean add(TimeBlock block) { + synchronized (mutex) { + return list.add(block); + } + } + + public TimeBlock get(int index) { + synchronized (mutex) { + return list.get(index); + } + } + + public TimeBlock remove(int index) { + synchronized (mutex) { + return list.remove(index); + } + } + + public int indexOf(Object o) { + synchronized (mutex) { + return list.indexOf(o); + } + } + + public int lastIndexOf(Object o) { + synchronized (mutex) { + return list.lastIndexOf(o); + } + } + + public TimeBlock getLast() { + return get(list.size() - 1); + } + + public TimeBlock removeLast() { + return remove(list.size() - 1); + } + + public Iterator iterator() { + synchronized (mutex) { + return list.iterator(); + } + } + + // private void writeObject(java.io.ObjectOutputStream out) throws + // IOException { + // + // } + // private void readObject(java.io.ObjectInputStream in) throws IOException, + // ClassNotFoundException { + // + // } +} diff --git a/src/eu/engys/core/project/zero/MeshRegion.java b/src/eu/engys/core/project/zero/MeshRegion.java new file mode 100644 index 0000000..0357077 --- /dev/null +++ b/src/eu/engys/core/project/zero/MeshRegion.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero; + +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.patches.Patches; + +public class MeshRegion { + + private Patches patches; + private Fields fields; + + public void setPatches(Patches patches) { + this.patches = patches; + } + + public Patches getPatches() { + return patches; + } + + public void setFields(Fields fields) { + this.fields = fields; + } + + public Fields getFields() { + return fields; + } +} diff --git a/src/eu/engys/core/project/zero/ParallelZeroFileManager.java b/src/eu/engys/core/project/zero/ParallelZeroFileManager.java new file mode 100644 index 0000000..7cb2293 --- /dev/null +++ b/src/eu/engys/core/project/zero/ParallelZeroFileManager.java @@ -0,0 +1,276 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero; + +import static eu.engys.core.project.zero.ZeroFolderUtil.clearFiles; +import static eu.engys.core.project.zero.ZeroFolderUtil.delete; +import static eu.engys.core.project.zero.ZeroFolderUtil.getBoundaryFile; +import static eu.engys.core.project.zero.ZeroFolderUtil.getCellZonesFile; +import static eu.engys.core.project.zero.ZeroFolderUtil.getFaceZonesFile; +import static eu.engys.core.project.zero.ZeroFolderUtil.getPolyMeshDir; +import static eu.engys.core.project.zero.ZeroFolderUtil.getRegionDir; +import static eu.engys.core.project.zero.ZeroFolderUtil.newZeroDir; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.List; + +import eu.engys.core.project.files.DefaultFileManager; +import eu.engys.core.project.system.ControlDict; + +public class ParallelZeroFileManager extends DefaultFileManager implements ZeroFileManager { + + public ParallelZeroFileManager(File file, int nProcessors) { + super(file); + newZeroDirs(nProcessors); + } + + @Override + public void newZeroDirs(int nProcessors) { + if (nProcessors > 1) { + for (int i = 0; i < nProcessors; i++) { + File processorDir = newFile("processor" + i); + if (!processorDir.exists()) { + processorDir.mkdir(); + logger.warn("-> New Folder {}", processorDir); + } + newZeroDir(processorDir); + } + } + } + + @Override + public void clearZeroDirs(String timeStep) { + logger.debug("Clear zero folder!"); + for (File file : getZeroDirs(timeStep)) { + clearFiles(file); + } + } + + @Override + public String findTimeValue(ControlDict controlDict) { + File processor = newFile("processor0"); + if (processor.exists()) { + String zero = ZeroFolderUtil.findTimeValue(processor, controlDict); + logger.debug("Find Time Value: {}", zero); + return zero; + } else { + return "0"; + } + } + + @Override + public File[] getZeroDirs(String timeStep) { + List zeroFolders = new ArrayList(); + for (int i = 0;; i++) { + File processor = newFile("processor" + i); + if (processor.exists()) { + File zeroFolder = new File(processor, ZeroFolderUtil.getTimeStepString(timeStep)); + + if (zeroFolder.exists() && zeroFolder.isDirectory()) { + zeroFolders.add(zeroFolder); + } else { + logger.warn("Folder {} is missing", zeroFolder.getAbsolutePath()); + } + + File constantFolder = new File(processor, "constant"); + if (!constantFolder.exists()) { + constantFolder.mkdir(); + logger.warn("Folder {} is missing", constantFolder.getAbsolutePath()); + } + } else { + break; + } + } + return zeroFolders.toArray(new File[zeroFolders.size()]); + } + + @Override + public File[] getConstantDirs() { + List constantFolders = new ArrayList(); + + for (int i = 0;; i++) { + File processor = newFile("processor" + i); + if (processor.exists()) { + File constantFolder = new File(processor, "constant"); + + if (constantFolder.exists() && constantFolder.isDirectory()) { + constantFolders.add(constantFolder); + } + } else { + break; + } + } + return constantFolders.toArray(new File[constantFolders.size()]); + } + + @Override + public File[] getRegionDirs(String region, File[] zeroDir) { + File[] polyMesh = new File[zeroDir.length]; + for (int i = 0; i < polyMesh.length; i++) { + polyMesh[i] = getRegionDir(zeroDir[i], region); + } + return polyMesh; + } + + @Override + public File[] getPolyMeshDirs(File[] zeroDir) { + File[] polyMesh = new File[zeroDir.length]; + for (int i = 0; i < polyMesh.length; i++) { + polyMesh[i] = getPolyMeshDir(zeroDir[i]); + } + return polyMesh; + } + + @Override + public File[] getBoundaryFiles(File[] polyMesh) { + File[] boundary = new File[polyMesh.length]; + for (int i = 0; i < boundary.length; i++) { + boundary[i] = getBoundaryFile(polyMesh[i]); + } + return boundary; + } + + @Override + public File[] getCellZonesFiles(File[] polyMesh) { + File[] cellZones = new File[polyMesh.length]; + for (int i = 0; i < cellZones.length; i++) { + cellZones[i] = getCellZonesFile(polyMesh[i]); + } + return cellZones; + } + + @Override + public File[] getFaceZonesFiles(File[] polyMesh) { + File[] faceZones = new File[polyMesh.length]; + for (int i = 0; i < faceZones.length; i++) { + faceZones[i] = getFaceZonesFile(polyMesh[i]); + } + return faceZones; + } + + @Override + public ZeroFolderStructure checkFileSystem() { + ZeroFolderStructure check = new ZeroFolderStructure(); + + String timeStep = findTimeValue(null); + + File[] zeroDirs = getZeroDirs(timeStep); + File[] polyMeshes = getPolyMeshDirs(zeroDirs); + File[] boundaryFiles = getBoundaryFiles(polyMeshes); + + if (ZeroFolderUtil.exists(boundaryFiles)) { + check.setBoundaryFieldInZero(true); + } else { + File[] constantDirs = getConstantDirs(); + polyMeshes = getPolyMeshDirs(constantDirs); + boundaryFiles = getBoundaryFiles(polyMeshes); + + if (ZeroFolderUtil.exists(boundaryFiles)) { + check.setBoundaryFieldInConstant(true); + } + } + return check; + } + + @Override + public void deleteAll() { + removeRegionsZeroDirs(); + removeRegionsConstantDirs(); + removeZeroDirs("0"); + removeConstantDirs(); + removeNonZeroDirs("0"); + } + + private void removeRegionsZeroDirs() { + File[] zeroDirs = getZeroDirs("0"); + String[] regionNames = ZeroFolderUtil.getRegions(zeroDirs); + for (String regionName : regionNames) { + File[] regionDirs = getRegionDirs(regionName, zeroDirs); + delete(regionDirs); + } + } + + private void removeRegionsConstantDirs() { + File[] constantDirs = getConstantDirs(); + String[] regionNames = ZeroFolderUtil.getRegions(constantDirs); + for (String regionName : regionNames) { + File[] regionDirs = getRegionDirs(regionName, constantDirs); + delete(regionDirs); + } + } + + @Override + public void removeZeroDirs(String timeStep) { + File[] zeroDirs = getZeroDirs(timeStep); + delete(zeroDirs); + } + + public void removeConstantDirs() { + File[] constantDirs = getConstantDirs(); + delete(constantDirs); + } + + @Override + public void removeNonZeroDirs(String timeStep) { + File[] nonZeroDirs = getNonZeroDirs(timeStep); + delete(nonZeroDirs); + } + + @Override + public File[] getNonZeroDirs(String timeStep) { + List nonZeroFolders = new ArrayList(); + for (int i = 0;; i++) { + File processor = newFile("processor" + i); + if (processor.exists()) { + File[] foldersWithANumberName = processor.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + try { + Double.parseDouble(name); + return true; + } catch (NumberFormatException nfee) { + return false; + } + } + }); + if (foldersWithANumberName.length > 0) { + for (File folder : foldersWithANumberName) { + double folderValue = Double.parseDouble(folder.getName()); + double timeStepValue = Double.parseDouble(timeStep); + if (folderValue > timeStepValue) { + nonZeroFolders.add(folder); + } + } + } + } else { + break; + } + } + return nonZeroFolders.toArray(new File[nonZeroFolders.size()]); + } +} diff --git a/src/eu/engys/core/project/zero/SerialZeroFileManager.java b/src/eu/engys/core/project/zero/SerialZeroFileManager.java new file mode 100644 index 0000000..6e80c32 --- /dev/null +++ b/src/eu/engys/core/project/zero/SerialZeroFileManager.java @@ -0,0 +1,237 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero; + +import static eu.engys.core.project.zero.ZeroFolderUtil.clearFiles; +import static eu.engys.core.project.zero.ZeroFolderUtil.delete; +import static eu.engys.core.project.zero.ZeroFolderUtil.getBoundaryFile; +import static eu.engys.core.project.zero.ZeroFolderUtil.getCellZonesFile; +import static eu.engys.core.project.zero.ZeroFolderUtil.getConstantDir; +import static eu.engys.core.project.zero.ZeroFolderUtil.getFaceZonesFile; +import static eu.engys.core.project.zero.ZeroFolderUtil.getPolyMeshDir; +import static eu.engys.core.project.zero.ZeroFolderUtil.getRegionDir; +import static eu.engys.core.project.zero.ZeroFolderUtil.newZeroDir; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FileUtils; + +import eu.engys.core.project.files.DefaultFileManager; +import eu.engys.core.project.system.ControlDict; + +public class SerialZeroFileManager extends DefaultFileManager implements ZeroFileManager { + + public SerialZeroFileManager(File file) { + super(file); + newZeroDirs(1); + } + + @Override + public void newZeroDirs(int nProcessors) { + if (nProcessors == 1) { + newZeroDir(getFile()); + } + } + + @Override + public void clearZeroDirs(String timeStep) { + for (File file : getZeroDirs(timeStep)) { + clearFiles(file); + } + } + + @Override + public String findTimeValue(ControlDict controlDict) { + return ZeroFolderUtil.findTimeValue(getFile(), controlDict); + } + + @Override + public File[] getZeroDirs(String timeStep) { + return arrayOf(newFile(ZeroFolderUtil.getTimeStepString(timeStep))); + } + + @Override + public File[] getConstantDirs() { + return arrayOf(getConstantDir(getFile())); + } + + @Override + public File[] getRegionDirs(String region, File[] zeroDirs) { + if (isOne(zeroDirs)) { + File zeroDir = zeroDirs[0]; + return arrayOf(getRegionDir(zeroDir, region)); + } else { + throw new RuntimeException(""); + } + } + + @Override + public File[] getPolyMeshDirs(File[] zeroDirs) { + if (isOne(zeroDirs)) { + File zeroDir = zeroDirs[0]; + return arrayOf(getPolyMeshDir(zeroDir)); + } else { + throw new RuntimeException(""); + } + } + + @Override + public File[] getBoundaryFiles(File[] polyMeshDirs) { + if (isOne(polyMeshDirs)) { + File polyMesh = polyMeshDirs[0]; + return arrayOf(getBoundaryFile(polyMesh)); + } else { + throw new RuntimeException(""); + } + } + + @Override + public File[] getCellZonesFiles(File[] polyMeshDirs) { + if (isOne(polyMeshDirs)) { + File polyMesh = polyMeshDirs[0]; + return arrayOf(getCellZonesFile(polyMesh)); + } else { + throw new RuntimeException(""); + } + } + + @Override + public File[] getFaceZonesFiles(File[] polyMeshDirs) { + if (isOne(polyMeshDirs)) { + File polyMesh = polyMeshDirs[0]; + return arrayOf(getFaceZonesFile(polyMesh)); + } else { + throw new RuntimeException(""); + } + } + + private File[] arrayOf(File file) { + return new File[] { file }; + } + + private boolean isOne(File[] files) { + return files.length == 1; + } + + @Override + public ZeroFolderStructure checkFileSystem() { + ZeroFolderStructure check = new ZeroFolderStructure(); + + String timeStep = findTimeValue(null); + + File zeroDir = getZeroDirs(timeStep)[0]; + File polyMesh = getPolyMeshDir(zeroDir); + File boundaryFile = getBoundaryFile(polyMesh); + + if (boundaryFile.exists()) { + check.setBoundaryFieldInZero(true); + } else { + File constantDir = getConstantDir(getFile()); + polyMesh = getPolyMeshDir(constantDir); + boundaryFile = getBoundaryFile(polyMesh); + + if (boundaryFile.exists()) { + check.setBoundaryFieldInConstant(true); + } + } + + return check; + } + + @Override + public void deleteAll() { + removeRegionsZeroDirs(); + removeRegionsConstantDirs(); + removeZeroDirs("0"); + removeConstantPolyMeshDirs(); + removeNonZeroDirs("0"); + } + + private void removeRegionsZeroDirs() { + File[] zeroDirs = getZeroDirs("0"); + String[] regionNames = ZeroFolderUtil.getRegions(zeroDirs); + for (String regionName : regionNames) { + File[] regionDirs = getRegionDirs(regionName, zeroDirs); + delete(regionDirs); + } + } + + private void removeRegionsConstantDirs() { + File[] constantDirs = getConstantDirs(); + String[] regionNames = ZeroFolderUtil.getRegions(constantDirs); + for (String regionName : regionNames) { + File[] regionDirs = getRegionDirs(regionName, constantDirs); + delete(regionDirs); + } + } + + @Override + public void removeZeroDirs(String timeStep) { + File zeroDir = new File(getFile(), ZeroFolderUtil.getTimeStepString(timeStep)); + FileUtils.deleteQuietly(zeroDir); + } + + @Override + public void removeNonZeroDirs(String timeStep) { + File[] nonZeroDirs = getNonZeroDirs(timeStep); + delete(nonZeroDirs); + } + + private void removeConstantPolyMeshDirs() { + File[] constantDirs = getConstantDirs(); + File[] polyMeshes = getPolyMeshDirs(constantDirs); + delete(polyMeshes); + } + + @Override + public File[] getNonZeroDirs(String timeStep) { + List nonZeroFolders = new ArrayList(); + File[] foldersWithANumberName = getFile().listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + try { + Double.parseDouble(name); + return true; + } catch (NumberFormatException nfee) { + return false; + } + } + }); + if (foldersWithANumberName.length > 0) { + for (File folder : foldersWithANumberName) { + double folderValue = Double.parseDouble(folder.getName()); + double timeStepValue = Double.parseDouble(timeStep); + if (folderValue > timeStepValue) { + nonZeroFolders.add(folder); + } + } + } + return nonZeroFolders.toArray(new File[nonZeroFolders.size()]); + } +} diff --git a/src/eu/engys/core/project/zero/ZeroFileManager.java b/src/eu/engys/core/project/zero/ZeroFileManager.java new file mode 100644 index 0000000..a3aeb79 --- /dev/null +++ b/src/eu/engys/core/project/zero/ZeroFileManager.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero; + +import java.io.File; + +import eu.engys.core.project.files.FileManager; +import eu.engys.core.project.system.ControlDict; + +public interface ZeroFileManager extends FileManager { + + File[] getZeroDirs(String timeStep); + + File[] getNonZeroDirs(String timeStep); + + File[] getPolyMeshDirs(File[] zeroDirs); + + File[] getBoundaryFiles(File[] polyMeshes); + + File[] getCellZonesFiles(File[] polyMeshes); + + File[] getFaceZonesFiles(File[] polyMeshes); + + File[] getConstantDirs(); + + File[] getRegionDirs(String region, File[] zeroDirs); + + void newZeroDirs(int nProcessors); + + void clearZeroDirs(String timeStep); + + ZeroFolderStructure checkFileSystem(); + + void removeZeroDirs(String timeStep); + + void removeNonZeroDirs(String timeStep); + + String findTimeValue(ControlDict controlDict); + +} diff --git a/src/eu/engys/core/project/zero/ZeroFolder.java b/src/eu/engys/core/project/zero/ZeroFolder.java new file mode 100644 index 0000000..9e92dd0 --- /dev/null +++ b/src/eu/engys/core/project/zero/ZeroFolder.java @@ -0,0 +1,438 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero; + +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.defaults.DefaultsProvider; +import eu.engys.core.project.files.FileManager; +import eu.engys.core.project.files.Folder; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.cellzones.CellZones; +import eu.engys.core.project.zero.cellzones.CellZonesBuilder; +import eu.engys.core.project.zero.cellzones.CellZonesReader; +import eu.engys.core.project.zero.cellzones.CellZonesWriter; +import eu.engys.core.project.zero.facezones.FaceZones; +import eu.engys.core.project.zero.facezones.FaceZonesReader; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.fields.FieldsDefaults; +import eu.engys.core.project.zero.fields.FieldsReader; +import eu.engys.core.project.zero.fields.FieldsWriter; +import eu.engys.core.project.zero.fields.Initialisations; +import eu.engys.core.project.zero.patches.BoundaryConditionsDefaults; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.core.project.zero.patches.PatchesReader; +import eu.engys.core.project.zero.patches.PatchesWriter; +import eu.engys.util.progress.ConsoleMonitor; +import eu.engys.util.progress.ProgressMonitor; + +public class ZeroFolder implements Folder { + + private static final Logger logger = LoggerFactory.getLogger(ZeroFolder.class); + + private ZeroFileManager zeroFileManager; + + private Map regions = new HashMap<>(); + + private String timeValue = "0"; + + public ZeroFolder(openFOAMProject prj) { + zeroFileManager = prj.isParallel() ? new ParallelZeroFileManager(prj.getBaseDir(), prj.getProcessors()) : new SerialZeroFileManager(prj.getBaseDir()); + } + + public ZeroFolder(File baseDir, ZeroFolder zeroFolder) { + if (zeroFolder.getFileManager() instanceof ParallelZeroFileManager) { + ParallelZeroFileManager pZero = (ParallelZeroFileManager) zeroFolder.getFileManager(); + zeroFileManager = new ParallelZeroFileManager(baseDir, pZero.getZeroDirs(zeroFolder.getTimeValue()).length); + } else { + zeroFileManager = new SerialZeroFileManager(baseDir); + } + this.timeValue = zeroFolder.getTimeValue(); + } + + public void read(Model model, CellZonesBuilder builder, Set modules, Initialisations initialisations, ProgressMonitor monitor) { + try { + timeValue = zeroFileManager.findTimeValue(model.getProject().getSystemFolder().getControlDict()); + + File[] zeroDirs = zeroFileManager.getZeroDirs("0"); + File[] timeDirs = zeroFileManager.getZeroDirs(timeValue); + File[] polyMeshes = zeroFileManager.getPolyMeshDirs(zeroDirs); + File[] boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + File[] cellZonesFiles = zeroFileManager.getCellZonesFiles(polyMeshes); + File[] faceZonesFiles = zeroFileManager.getFaceZonesFiles(polyMeshes); + String[] regionNames = ZeroFolderUtil.getRegions(zeroDirs); + + if (!ZeroFolderUtil.exists(boundaryFiles)) { + File[] constantDirs = zeroFileManager.getConstantDirs(); + polyMeshes = zeroFileManager.getPolyMeshDirs(constantDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + cellZonesFiles = zeroFileManager.getCellZonesFiles(polyMeshes); + faceZonesFiles = zeroFileManager.getFaceZonesFiles(polyMeshes); + regionNames = ZeroFolderUtil.getRegions(constantDirs); + } + + monitor.setIndeterminate(false); + + model.setPatches(readPatches(monitor, boundaryFiles)); + model.setCellZones(readCellZones(model, builder, monitor, cellZonesFiles, modules)); + model.setFaceZones(readFaceZones(monitor, faceZonesFiles)); + model.setFields(readFields(null, model.getProject(), model.getState(), model.getDefaults(), model.getPatches(), modules, initialisations, monitor, timeDirs, boundaryFiles)); + + BoundaryConditionsDefaults.loadBoundaryConditionsFromFields(model.getPatches(), model.getFields()); + + regions.clear(); + if (regionNames != null && regionNames.length > 0) { + logger.info("REGIONS: found regions {}", Arrays.toString(regionNames)); + for (String regionName : regionNames) { + zeroDirs = zeroFileManager.getZeroDirs("0"); + timeDirs = zeroFileManager.getZeroDirs(timeValue); + File[] regionTimeDirs = zeroFileManager.getRegionDirs(regionName, timeDirs); + + ZeroFolderUtil.mkDirs(regionTimeDirs); + + File[] regionDirs = zeroFileManager.getRegionDirs(regionName, zeroDirs); + polyMeshes = zeroFileManager.getPolyMeshDirs(regionDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + cellZonesFiles = zeroFileManager.getCellZonesFiles(polyMeshes); + faceZonesFiles = zeroFileManager.getFaceZonesFiles(polyMeshes); + + if (!ZeroFolderUtil.exists(boundaryFiles)) { + File[] constantDirs = zeroFileManager.getConstantDirs(); + regionDirs = zeroFileManager.getRegionDirs(regionName, constantDirs); + polyMeshes = zeroFileManager.getPolyMeshDirs(regionDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + cellZonesFiles = zeroFileManager.getCellZonesFiles(polyMeshes); + faceZonesFiles = zeroFileManager.getFaceZonesFiles(polyMeshes); + } + + Patches patches = readPatches(monitor, boundaryFiles); + Fields fields = readFields(regionName, model.getProject(), model.getState(), model.getDefaults(), patches, modules, initialisations, monitor, regionTimeDirs, boundaryFiles); + MeshRegion region = new MeshRegion(); + region.setPatches(patches); + region.setFields(fields); + + BoundaryConditionsDefaults.loadBoundaryConditionsFromFields(patches, fields); + regions.put(regionName, region); + } + } + } catch (Exception e) { + logger.error("Error in load", e); + monitor.error(e.getMessage(), 1); + } + model.patchesChanged(); + model.cellZonesChanged(); + model.faceZonesChanged(); + } + + public Patches readPatches() { + File[] zeroDirs = zeroFileManager.getZeroDirs("0"); + File[] polyMeshes = zeroFileManager.getPolyMeshDirs(zeroDirs); + File[] boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + + if (!ZeroFolderUtil.exists(boundaryFiles)) { + File[] constantDirs = zeroFileManager.getConstantDirs(); + polyMeshes = zeroFileManager.getPolyMeshDirs(constantDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + } + + return readPatches(new ConsoleMonitor(), boundaryFiles); + } + + public Patches readPatches(String regionName) { + File[] zeroDirs = zeroFileManager.getZeroDirs("0"); + File[] regionDirs = zeroFileManager.getRegionDirs(regionName, zeroDirs); + File[] polyMeshes = zeroFileManager.getPolyMeshDirs(regionDirs); + File[] boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + + if (!ZeroFolderUtil.exists(boundaryFiles)) { + File[] constantDirs = zeroFileManager.getConstantDirs(); + regionDirs = zeroFileManager.getRegionDirs(regionName, constantDirs); + polyMeshes = zeroFileManager.getPolyMeshDirs(regionDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + } + + return readPatches(new ConsoleMonitor(), boundaryFiles); + } + + private Patches readPatches(ProgressMonitor monitor, File[] boundaryFiles) { + if (ZeroFolderUtil.exists(boundaryFiles)) { + monitor.setCurrent("Reading patches", 0, boundaryFiles.length, 1); + Patches patches = new PatchesReader(monitor).read(boundaryFiles); + monitor.info("Patches: " + patches.filterProcBoundary().patchesNames().toString(), 1); + return patches; + } else { + monitor.warning("Missing boundary fields", 1); + logger.warn(Arrays.toString(boundaryFiles) + " does not exist"); + return new Patches(); + } + } + + private CellZones readCellZones(Model model, CellZonesBuilder builder, ProgressMonitor monitor, File[] cellZonesFiles, Set modules) { + if (ZeroFolderUtil.exists(cellZonesFiles)) { + monitor.setCurrent("Reading cell zones", 0, cellZonesFiles.length, 1); + CellZones cellZones = new CellZonesReader(model, builder, modules, monitor).read(cellZonesFiles); + monitor.info("Cell Zones: " + cellZones.zonesNames().toString(), 1); + return cellZones; + } else { + monitor.warning("Missing cellZones file", 1); + logger.warn(Arrays.toString(cellZonesFiles) + " does not exist"); + return new CellZones(); + } + } + + private FaceZones readFaceZones(ProgressMonitor monitor, File[] faceZonesFiles) { + if (ZeroFolderUtil.exists(faceZonesFiles)) { + monitor.setCurrent("Reading face zones", 0, faceZonesFiles.length, 1); + FaceZones faceZones = new FaceZonesReader(monitor).read(faceZonesFiles); + monitor.info("Face Zones: " + faceZones.zonesNames().toString(), 1); + return faceZones; + } else { + monitor.warning("Missing faceZones file", 1); + logger.warn(Arrays.toString(faceZonesFiles) + " does not exist"); + return new FaceZones(); + } + } + + private Fields readFields(String region, openFOAMProject prj, State state, DefaultsProvider defaults, Patches patches, Set modules, Initialisations initialisations, ProgressMonitor monitor, File[] timeDirs, File[] boundaryFiles) { + if (initialisations != null && ZeroFolderUtil.exists(timeDirs) && ZeroFolderUtil.exists(boundaryFiles)) { + Fields fields = new Fields(); + if (prj.isParallel()) { + fields.newParallelFields(prj.getProcessors()); + } + logger.debug("Loading fields from defaults"); + fields.merge(FieldsDefaults.loadFieldsFromDefaults(state, defaults, patches, region)); + logger.debug("Loading fields from MODULE defaults"); + fields.merge(ModulesUtil.loadFieldsFromDefaults(modules, region)); + logger.debug("Reading field from case"); + fields.merge(new FieldsReader(initialisations, monitor).read(fields.keySet(), timeDirs)); + fields.fixPVisibility(state); + + monitor.info("Fields: " + fields.fieldNames().toString(), 1); + return fields; + } else { + monitor.warning("Missing fields", 1); + logger.warn(Arrays.toString(timeDirs) + " does not exist"); + return new Fields(); + } + } + + /* + * Write + */ + + public void write(Model model, CellZonesBuilder cellZonesBuilder, Set modules, Initialisations initialisations, ProgressMonitor monitor) { + if (avoidSave(model)) + return; + + try { + String currentTimeValue = zeroFileManager.findTimeValue(model.getProject().getSystemFolder().getControlDict()); + boolean timeStepHasChanged = !currentTimeValue.equals(timeValue); + if (timeStepHasChanged) { + logger.info("Timestep has changed {} -> {}", timeValue, currentTimeValue); + this.timeValue = currentTimeValue; + } + + File[] zeroDirs = zeroFileManager.getZeroDirs("0"); + File[] timeDirs = zeroFileManager.getZeroDirs(timeValue); + File[] polyMeshes = zeroFileManager.getPolyMeshDirs(zeroDirs); + File[] boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + File[] cellZonesFiles = zeroFileManager.getCellZonesFiles(polyMeshes); + + if (!ZeroFolderUtil.exists(boundaryFiles)) { + File[] constantDirs = zeroFileManager.getConstantDirs(); + polyMeshes = zeroFileManager.getPolyMeshDirs(constantDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + cellZonesFiles = zeroFileManager.getCellZonesFiles(polyMeshes); + } + + writePatches(model.getPatches(), model, monitor, boundaryFiles); + writeCellZones(model, cellZonesBuilder, monitor, cellZonesFiles, modules); + writeFields(model.getFields(), model.getPatches(), modules, initialisations, monitor, timeDirs, boundaryFiles, timeStepHasChanged); + + if (!regions.isEmpty()) { + for (String regionName : regions.keySet()) { + MeshRegion region = regions.get(regionName); + + zeroDirs = zeroFileManager.getZeroDirs("0"); + File[] regionTimeDirs = zeroFileManager.getRegionDirs(regionName, timeDirs); + File[] regionDirs = zeroFileManager.getRegionDirs(regionName, zeroDirs); + polyMeshes = zeroFileManager.getPolyMeshDirs(regionDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + cellZonesFiles = zeroFileManager.getCellZonesFiles(polyMeshes); + + if (!ZeroFolderUtil.exists(boundaryFiles)) { + File[] constantDirs = zeroFileManager.getConstantDirs(); + regionDirs = zeroFileManager.getRegionDirs(regionName, constantDirs); + polyMeshes = zeroFileManager.getPolyMeshDirs(regionDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + cellZonesFiles = zeroFileManager.getCellZonesFiles(polyMeshes); + } + + writePatches(region.getPatches(), model, monitor, boundaryFiles); + writeFields(region.getFields(), region.getPatches(), modules, initialisations, monitor, regionTimeDirs, boundaryFiles, timeStepHasChanged); + } + } + } catch (Exception e) { + logger.error("Error in write", e); + monitor.error("Zero folder error: " + e.getMessage(), 2); + } + } + + public void writePatches(Model model, Patches patches) { + File[] zeroDirs = zeroFileManager.getZeroDirs("0"); + File[] polyMeshes = zeroFileManager.getPolyMeshDirs(zeroDirs); + File[] boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + + if (!ZeroFolderUtil.exists(boundaryFiles)) { + File[] constantDirs = zeroFileManager.getConstantDirs(); + polyMeshes = zeroFileManager.getPolyMeshDirs(constantDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + } + + writePatches(patches, model, new ConsoleMonitor(), boundaryFiles); + } + + public void writePatches(Model model, Patches patches, String regionName) { + File[] zeroDirs = zeroFileManager.getZeroDirs("0"); + File[] regionDirs = zeroFileManager.getRegionDirs(regionName, zeroDirs); + File[] polyMeshes = zeroFileManager.getPolyMeshDirs(regionDirs); + File[] boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + + if (!ZeroFolderUtil.exists(boundaryFiles)) { + File[] constantDirs = zeroFileManager.getConstantDirs(); + regionDirs = zeroFileManager.getRegionDirs(regionName, constantDirs); + polyMeshes = zeroFileManager.getPolyMeshDirs(regionDirs); + boundaryFiles = zeroFileManager.getBoundaryFiles(polyMeshes); + } + + writePatches(patches, model, new ConsoleMonitor(), boundaryFiles); + } + + private void writePatches(Patches patches, Model model, ProgressMonitor monitor, File[] boundaryFiles) { + if (ZeroFolderUtil.exists(boundaryFiles)) { + monitor.setCurrent("Saving patches", 0, boundaryFiles.length, 1); + new PatchesWriter(model, monitor).write(patches, boundaryFiles); + } else { + monitor.warning("Missing boundary fields", 1); + logger.warn(Arrays.toString(boundaryFiles) + " does not exist"); + } + } + + private void writeCellZones(Model model, CellZonesBuilder builder, ProgressMonitor monitor, File[] cellZonesFiles, Set modules) { + CellZonesWriter cellZonesWriter = new CellZonesWriter(builder, modules, monitor); + cellZonesWriter.writeFvOptions(model); + if (ZeroFolderUtil.exists(cellZonesFiles)) { + monitor.setCurrent("Saving cell zones", 0, cellZonesFiles.length, 1); + cellZonesWriter.writeCellZoneFiles(model, cellZonesFiles); + monitor.info("Cell Zones: " + model.getCellZones().zonesNames().toString(), 1); + } else { + monitor.warning("Missing cellZones file", 1); + logger.warn(Arrays.toString(cellZonesFiles) + " does not exist"); + } + } + + private void writeFields(Fields fields, Patches patches, Set modules, Initialisations initialisations, ProgressMonitor monitor, File[] timeDirs, File[] boundaryFiles, boolean timeStepHasChanged) { + if (initialisations != null && ZeroFolderUtil.exists(timeDirs) && ZeroFolderUtil.exists(boundaryFiles)) { + if (timeStepHasChanged) { + monitor.setCurrent("Re-Reading fields", 0, timeDirs.length, 1); + fields = new FieldsReader(initialisations, monitor).read(fields.keySet(), timeDirs); + BoundaryConditionsDefaults.fieldsToBoundaryConditions(patches, fields); + } + monitor.setCurrent("Saving fields", 0, timeDirs.length, 1); + BoundaryConditionsDefaults.saveBoundaryConditionsToFields(patches, fields); + new FieldsWriter(monitor).write(fields, timeDirs); + monitor.info("Fields: " + fields.fieldNames().toString(), 1); + } else { + monitor.warning("Missing fields", 1); + logger.warn(Arrays.toString(timeDirs) + " does not exist"); + } + } + + String getTimeValue() { + return timeValue; + } + + @Override + public FileManager getFileManager() { + return zeroFileManager; + } + + public void deleteMesh() { + regions.clear(); + zeroFileManager.deleteAll(); + if (zeroFileManager instanceof ParallelZeroFileManager) { + new SerialZeroFileManager(zeroFileManager.getFile()).deleteAll(); + } + } + + protected boolean avoidSave(Model model) { + return model.getCellZones().isEmpty() && model.getPatches().isEmpty() && model.getFields().isEmpty(); + } + + public void clearFields() { + zeroFileManager.clearZeroDirs(timeValue); + } + + public void removeNonZeroTimeFolders_GreaterThanActualTimeStep() { + zeroFileManager.removeNonZeroDirs(timeValue); + } + + public boolean hasNonZeroTimeFolders() { + return zeroFileManager.getNonZeroDirs("0").length > 0; + } + + public MeshRegion getRegion(String regionName) { + return regions.get(regionName); + } + + public boolean hasRegion(String regionName) { + return regions.containsKey(regionName); + } + + // For tests purposes only!!! + public void setTimeValue(String timeValue) { + this.timeValue = timeValue; + } + + public ZeroFileManager getZeroFileManager() { + return zeroFileManager; + } + + public boolean hasRegions() { + return !regions.isEmpty(); + } +} diff --git a/src/eu/engys/core/project/zero/ZeroFolderStructure.java b/src/eu/engys/core/project/zero/ZeroFolderStructure.java new file mode 100644 index 0000000..75e7154 --- /dev/null +++ b/src/eu/engys/core/project/zero/ZeroFolderStructure.java @@ -0,0 +1,49 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero; + +public class ZeroFolderStructure { + + private boolean boundaryFieldInZero; + private boolean boundaryFieldInConstant; + + public boolean isBoundaryFieldInZero() { + return boundaryFieldInZero; + } + + public void setBoundaryFieldInZero(boolean boundaryFieldInZero) { + this.boundaryFieldInZero = boundaryFieldInZero; + } + + public boolean isBoundaryFieldInConstant() { + return boundaryFieldInConstant; + } + + public void setBoundaryFieldInConstant(boolean boundaryFieldInConstant) { + this.boundaryFieldInConstant = boundaryFieldInConstant; + } + +} diff --git a/src/eu/engys/core/project/zero/ZeroFolderUtil.java b/src/eu/engys/core/project/zero/ZeroFolderUtil.java new file mode 100644 index 0000000..fffad45 --- /dev/null +++ b/src/eu/engys/core/project/zero/ZeroFolderUtil.java @@ -0,0 +1,311 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero; + +import static eu.engys.core.project.system.ControlDict.START_FROM_KEY; +import static eu.engys.core.project.system.ControlDict.START_TIME_VALUE; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Comparator; +import java.util.zip.GZIPInputStream; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.RegexFileFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.system.ControlDict; +import eu.engys.util.RegexpUtils; + +public class ZeroFolderUtil { + + private static final Logger logger = LoggerFactory.getLogger(ZeroFolderUtil.class); + + public static final String CELL_ZONES = "cellZones"; + public static final String FACE_ZONES = "faceZones"; + public static final String BOUNDARY = "boundary"; + public static final String POLY_MESH = "polyMesh"; + public static final String CONSTANT = "constant"; + public static final String PROCESSOR = "processor"; + public static final String ZERO = "0"; + + public static String PROCESSOR(int i) { + return PROCESSOR + i; + } + + public static void clearFiles(File parent) { + if (parent.list().length != 0) { + File[] files = parent.listFiles(); + for (File file : files) { + if (file.isFile()) { + logger.debug("Deleting {}", file); + file.delete(); + } + } + } + } + + public static void newZeroDir(File parent) { + File zeroDir = getZeroDir(parent); + if (!zeroDir.exists()) { + zeroDir.mkdir(); + logger.warn("New Folder {}", zeroDir); + } + File constantDir = getConstantDir(parent); + if (!constantDir.exists()) { + constantDir.mkdir(); + logger.warn("New Folder {}", constantDir); + } + File polyMesh = getPolyMeshDir(zeroDir); + if (!polyMesh.exists()) { + polyMesh.mkdir(); + logger.warn("New Folder {}", polyMesh); + } + } + + public static File getZeroDir(File parent) { + return new File(parent, ZERO); + } + + public static File getPolyMeshDir(File zeroDir) { + return new File(zeroDir, POLY_MESH); + } + + public static File getConstantDir(File zeroDir) { + return new File(zeroDir, CONSTANT); + } + + public static File getRegionDir(File zeroDir, String region) { + return new File(zeroDir, region); + } + + public static File getBoundaryFile(File polyMesh) { + File boundary = new File(polyMesh, BOUNDARY); + File boundary_gz = new File(polyMesh, BOUNDARY + ".gz"); + if (boundary.exists() && boundary.length() > 0) { + return boundary; + } else if (boundary_gz.exists()) { + gunzip(boundary_gz, boundary); + return boundary; + } else { + return boundary; + } + } + + public static File getCellZonesFile(File polyMesh) { + File cellZones = new File(polyMesh, CELL_ZONES); + File cellZones_gz = new File(polyMesh, CELL_ZONES + ".gz"); + if (cellZones.exists() && cellZones.length() > 0) { + return cellZones; + } else if (cellZones_gz.exists()) { + gunzip(cellZones_gz, cellZones); + return cellZones; + } else { + return cellZones; + } + } + + public static File getFaceZonesFile(File polyMesh) { + File faceZones = new File(polyMesh, FACE_ZONES); + File faceZones_gz = new File(polyMesh, FACE_ZONES + ".gz"); + if (faceZones.exists() && faceZones.length() > 0) { + return faceZones; + } else if (faceZones_gz.exists()) { + gunzip(faceZones_gz, faceZones); + return faceZones; + } else { + return faceZones; + } + } + + public static String getActualTimeValue(openFOAMProject project) { + return getTimeStepString(project.getZeroFolder().getTimeValue()); + } + + public static String findTimeValue(File proc0, ControlDict controlDict) { + if (controlDict == null || !controlDict.isField(START_FROM_KEY)) { + return getFirstFolderName(proc0); + } + + String startFrom = controlDict.lookup(START_FROM_KEY); + String time = "0"; + switch (startFrom) { + case ControlDict.FIRST_TIME_VALUE: + time = getFirstFolderName(proc0); + break; + case ControlDict.LATEST_TIME_VALUE: + time = getLastFolderName(proc0); + break; + case ControlDict.START_TIME_VALUE: + time = controlDict.lookup(START_TIME_VALUE); + break; + default: + time = getFirstFolderName(proc0); + break; + } + logger.info("Start From: " + startFrom + " T: " + time); + return time; + } + + private static String getFirstFolderName(File proc0) { + String[] directories = getDirectories(proc0); + String firstFolderName = "0"; + if (directories.length > 0) { + Arrays.sort(directories, new Comparator() { + public int compare(String s1, String s2) { + return Double.valueOf(s1).compareTo(Double.valueOf(s2)); + } + }); + firstFolderName = directories[0]; + } + return firstFolderName; + } + + private static String getLastFolderName(File proc0) { + String[] directories = getDirectories(proc0); + String lastFolderName = "0"; + if (directories != null && directories.length > 0) { + Arrays.sort(directories, new Comparator() { + public int compare(String s1, String s2) { + return Double.valueOf(s1).compareTo(Double.valueOf(s2)); + } + }); + lastFolderName = directories[directories.length - 1]; + } + return lastFolderName; + } + + private static String[] getDirectories(File proc0) { + RegexFileFilter filter = new RegexFileFilter(RegexpUtils.DOUBLE); + return proc0.list(filter); + } + + // private static String getStartTimeValue(String value) { + // return Double.parseDouble(value); + // } + + public static String[] getRegions(File... zeroDirs) { + if (zeroDirs == null || zeroDirs.length == 0) { + return new String[0]; + } + File zeroDir = zeroDirs[0]; + String[] regionDirs = zeroDir.list(new IsAValidRegionFolder()); + if (regionDirs == null) { + return new String[0]; + } + return regionDirs; + } + + private static class IsAValidRegionFolder implements FilenameFilter { + @Override + public boolean accept(File dir, String name) { + if (name.equals(POLY_MESH)) { + return false; + } + + File folder = new File(dir, name); + if (folder.isDirectory()) { + File polyMesh = getPolyMeshDir(folder); + if (polyMesh.exists()) { + File boundaryFile = getBoundaryFile(polyMesh); + if (boundaryFile.exists()) { + return true; + } + } + } + + return false; + } + } + + public static boolean exists(File... boundaryFiles) { + if (boundaryFiles == null || boundaryFiles.length == 0) { + return false; + } + boolean value = true; + for (File file : boundaryFiles) { + value = value && file.exists(); + } + return value; + } + + private static void gunzip(File inputFile, File outputFile) { + try { + GZIPInputStream gzipInputStream = null; + + gzipInputStream = new GZIPInputStream(new FileInputStream(inputFile)); + + OutputStream out = new FileOutputStream(outputFile); + + byte[] buf = new byte[1024]; + int len; + + while ((len = gzipInputStream.read(buf)) > 0) { + out.write(buf, 0, len); + } + + gzipInputStream.close(); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static String getTimeStepString(String timeStep) { + try { + Integer i = Integer.valueOf(timeStep); + return String.valueOf(i); + } catch (NumberFormatException e) { + return timeStep; + } + } + + public static void mkDirs(File[] dirs) { + if (dirs != null) { + for (File file : dirs) { + if (!file.exists()) { + file.mkdir(); + } + } + } + } + + public static void delete(File[] dirs) { + if (dirs != null) { + for (File file : dirs) { + logger.debug("Deleting {}", file); + FileUtils.deleteQuietly(file); + } + } + } +} diff --git a/src/eu/engys/core/project/zero/cellzones/CellZone.java b/src/eu/engys/core/project/zero/cellzones/CellZone.java new file mode 100644 index 0000000..26c6285 --- /dev/null +++ b/src/eu/engys/core/project/zero/cellzones/CellZone.java @@ -0,0 +1,137 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.cellzones; + +import java.util.HashSet; +import java.util.Set; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.util.ui.checkboxtree.LoadableItem; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class CellZone implements VisibleItem, LoadableItem { + + private final String originalName; + private String name; + private Set types = new HashSet<>(); + private boolean visible; + private boolean loaded; + private Dictionary dictionary; + + public CellZone(String originalName) { + this.originalName = originalName; + this.name = originalName; + } + + public String getOriginalName() { + return originalName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setTypes(Set types) { + this.types = types; + } + + public Set getTypes() { + return types; + } + + @Override + public boolean isVisible() { + return visible; + } + + @Override + public void setVisible(boolean selected) { + this.visible = selected; + } + + @Override + public boolean isLoaded() { + return loaded; + } + + @Override + public void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + public void setDictionary(String key, Dictionary d) { + if (dictionary == null) { + this.dictionary = new Dictionary(originalName); + } + this.dictionary.add(new Dictionary(key, d)); + } + + public Dictionary getDictionary(String key) { + return dictionary.subDict(key); + } + + public void removeDictionary(String key) { + if (hasDictionary(key)) { + dictionary.remove(key); + } + } + + public boolean hasDictionary(String key) { + return dictionary != null && dictionary.found(key); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(name); + sb.append(" ["); + for (String type : types) { + sb.append(type); + sb.append("\n"); + } + sb.append("] "); + sb.append(visible); + + return sb.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof CellZone) { + return ((CellZone) obj).getName().equals(name); + } + return super.equals(obj); + } + + public boolean hasType(String key) { + return types.contains(key); + } +} diff --git a/src/eu/engys/core/project/zero/cellzones/CellZoneType.java b/src/eu/engys/core/project/zero/cellzones/CellZoneType.java new file mode 100644 index 0000000..f9bc96d --- /dev/null +++ b/src/eu/engys/core/project/zero/cellzones/CellZoneType.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.cellzones; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.cellzones.CellZonePanel; + +public interface CellZoneType extends Comparable { + + public static final String MRF_KEY = "mrf"; + public static final String POROUS_KEY = "porous"; + public static final String THERMAL_KEY = "thermal"; + public static final String HUMIDITY_KEY = "humidity"; + public static final String SLIDING_MESH_KEY = "sliding"; + + public abstract String getKey(); + + public abstract String getLabel(); + + public abstract Dictionary getDefaultDictionary(); + + public abstract CellZonePanel getPanel(); + + public abstract boolean isEnabled(); + + public abstract void setEnabled(boolean enabled); + + public abstract void updateStatusByState(); + +}; diff --git a/src/eu/engys/core/project/zero/cellzones/CellZones.java b/src/eu/engys/core/project/zero/cellzones/CellZones.java new file mode 100644 index 0000000..866ceef --- /dev/null +++ b/src/eu/engys/core/project/zero/cellzones/CellZones.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.cellzones; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CellZones extends ArrayList { + + public CellZones() { + super(); + } + + public List zonesNames() { + List names = new ArrayList<>(); + for (CellZone zone : this) { + names.add(zone.getName()); + } + return names; + } + + public Map toMap() { + Map zonesMap = new HashMap(); + for (CellZone zone : this) { + zonesMap.put(zone.getName(), zone); + } + return Collections.unmodifiableMap(zonesMap); + } + + public void addZones(List cellZones) { + addAll(cellZones); + } + + public boolean hasPorous() { + for (CellZone zone : this) { + if (zone.getTypes().contains(CellZoneType.POROUS_KEY)) { + return true; + } + } + return false; + } + + public boolean hasMRF() { + for (CellZone zone : this) { + if (zone.getTypes().contains(CellZoneType.MRF_KEY)) { + return true; + } + } + return false; + } + + public boolean hasSliding() { + for (CellZone zone : this) { + if (zone.getTypes().contains(CellZoneType.SLIDING_MESH_KEY)) { + return true; + } + } + return false; + } + + public boolean hasThermal() { + for (CellZone zone : this) { + if (zone.getTypes().contains(CellZoneType.THERMAL_KEY)) { + return true; + } + } + return false; + } +} diff --git a/src/eu/engys/core/project/zero/cellzones/CellZones200To210Converter.java b/src/eu/engys/core/project/zero/cellzones/CellZones200To210Converter.java new file mode 100644 index 0000000..3989549 --- /dev/null +++ b/src/eu/engys/core/project/zero/cellzones/CellZones200To210Converter.java @@ -0,0 +1,226 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.cellzones; + +import java.util.ArrayList; +import java.util.List; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.ListField; +import eu.engys.core.project.Project200To210Converter.MRFZones; +import eu.engys.core.project.Project200To210Converter.PorousZones; + +public class CellZones200To210Converter { + + public static List loadMRFDictionary(MRFZones MRFZones) { + List zones = new ArrayList<>(); + if (MRFZones != null) { + Dictionary zonesDictionary = null; + if (MRFZones.isList("")) { + ListField list = MRFZones.getListFields().get(0); + zonesDictionary = new Dictionary(""); + for (DefaultElement el : list.getListElements()) { + if (el instanceof Dictionary) { + zonesDictionary.add((Dictionary) el); + } + } + } else { + zonesDictionary = MRFZones; + } + + if (zonesDictionary != null) { + for (Dictionary d : zonesDictionary.getDictionaries()) { + String zoneName = d.getName(); + Dictionary encodedDictionary = new Dictionary(d); + encodedDictionary.add(Dictionary.TYPE, "mrf"); + + CellZone zone = new CellZone(zoneName); + zone.setName(zoneName); + zone.getTypes().add(CellZoneType.MRF_KEY); + zone.setDictionary(CellZoneType.MRF_KEY, encodedDictionary); + + zones.add(zone); + } + } + } + return zones; + } + +// public static void saveMRFDictionary(ArrayList cellZones, MRFZones MRFZones) { +// boolean asList = true; +// if (MRFZones != null) { +// MRFZones.clear(); +// for (CellZone cellZone : cellZones) { +// String zoneName = cellZone.getName(); +// +// if (cellZone.getType() == CellZoneType.MRF) { +// Dictionary encodedDictionary = cellZone.getDictionary(); +// +// Dictionary toBeDecoded = new Dictionary(zoneName); +// toBeDecoded.merge(encodedDictionary); +// toBeDecoded.remove(Dictionary.TYPE); +// +// if (asList) { +// MRFZones.addToList(toBeDecoded); +// } else { +// MRFZones.add(toBeDecoded); +// } +// } else { +// //System.err.println(zoneName + " NOT A MRF Zone"); +// } +// } +// } +// } + + public static List loadPorousDictionary(PorousZones porousZones) { + List zones = new ArrayList<>(); + if (porousZones != null) { + Dictionary zonesDictionary = null; + if (porousZones.isList("")) { + ListField list = porousZones.getListFields().get(0); + zonesDictionary = new Dictionary(""); + for (DefaultElement el : list.getListElements()) { + if (el instanceof Dictionary) { + zonesDictionary.add((Dictionary) el); + } + } + } else { + zonesDictionary = porousZones; + } + + if (zonesDictionary != null) { + + } + for (Dictionary toBeEncoded : zonesDictionary.getDictionaries()) { + String zoneName = toBeEncoded.getName(); + + Dictionary encodedDictionary = new Dictionary("porous"); + + if (toBeEncoded.found("Darcy")) { + Dictionary darcyDict = toBeEncoded.subDict("Darcy"); + //System.out.println("CellZoneBuilder.encodePorousDictionary() darcyDict: "+darcyDict); + encodedDictionary.add(darcyDict.lookupScalar("d")); + encodedDictionary.add(darcyDict.lookupScalar("f")); + encodedDictionary.add("e1", toBeEncoded.lookup("e1")); + encodedDictionary.add("e2", toBeEncoded.lookup("e2")); + encodedDictionary.add("porosity", toBeEncoded.lookup("porosity")); + encodedDictionary.add(Dictionary.TYPE, "porousDarcy"); + } else if (toBeEncoded.found("powerLaw")) { + Dictionary powerLawDict = toBeEncoded.subDict("powerLaw"); + encodedDictionary.add("C0", powerLawDict.lookup("C0")); + encodedDictionary.add("C1", powerLawDict.lookup("C1")); + encodedDictionary.add("porosity", toBeEncoded.lookup("porosity")); + encodedDictionary.add(Dictionary.TYPE, "porousPowerLaw"); + } else { + //bad + } + + CellZone zone = new CellZone(zoneName); + zone.setName(zoneName); + zone.getTypes().add(CellZoneType.POROUS_KEY); + zone.setDictionary(CellZoneType.POROUS_KEY, encodedDictionary); + + if (toBeEncoded.found("thermalModel")) { + Dictionary thermalDict = new Dictionary("thermalModel"); + + if (toBeEncoded.subDict("thermalModel").found("powerLaw")) { + Dictionary powerLaw = toBeEncoded.subDict("powerLaw"); + thermalDict.merge(powerLaw); + thermalDict.add(Dictionary.TYPE, "powerLaw"); + } else if (toBeEncoded.subDict("thermalModel").found(Dictionary.TYPE)) { + thermalDict.merge(toBeEncoded.subDict("thermalModel")); + } + + zone.getTypes().add(CellZoneType.THERMAL_KEY); + zone.setDictionary(CellZoneType.THERMAL_KEY, thermalDict); + } + + + zones.add(zone); + } + } + + return zones; + } + +// public static void savePorousDictionary(ArrayList cellZones, PorousZones porousZones) { +// boolean asList = true; +// if (porousZones != null) { +// porousZones.clear(); +// for (CellZone cellZone : cellZones) { +// String zoneName = cellZone.getName(); +// if (cellZone.getType() == CellZoneType.POROUS || cellZone.getType() == CellZoneType.THERMAL_POROUS || cellZone.getType() == CellZoneType.THERMAL) { +// Dictionary encodedDictionary = cellZone.getDictionary(); +// String typeString = encodedDictionary.lookup(Dictionary.TYPE); +// +// Dictionary toBeDecoded = new Dictionary(zoneName); +// if (typeString.equals("porousDarcy")) { +// Dictionary darcyDict = new Dictionary("Darcy"); +// darcyDict.add(encodedDictionary.lookupScalar("d")); +// darcyDict.add(encodedDictionary.lookupScalar("f")); +// +// toBeDecoded.add(darcyDict); +// toBeDecoded.add("e1", encodedDictionary.lookup("e1")); +// toBeDecoded.add("e2", encodedDictionary.lookup("e2")); +// toBeDecoded.add("porosity", encodedDictionary.lookup("porosity")); +// +// } else if (typeString.equals("porousPowerLaw")) { +// Dictionary powerLawDict = new Dictionary("powerLaw"); +// powerLawDict.add("C0", encodedDictionary.lookup("C0")); +// powerLawDict.add("C1", encodedDictionary.lookup("C1")); +// toBeDecoded.add(powerLawDict); +// toBeDecoded.add("porosity", encodedDictionary.lookup("porosity")); +// } +// toBeDecoded.remove(Dictionary.TYPE); +// +// /* in case of thermal porous zone */ +// if (encodedDictionary.found("thermalModel")) { +// Dictionary thermalDict = new Dictionary("thermalModel"); +// +// Dictionary thermalModel = encodedDictionary.subDict("thermalModel"); +// String thermalType = thermalModel.lookup(Dictionary.TYPE); +// if (thermalType.equals("powerLaw")) { +// thermalDict.merge(thermalModel); +// } else if (thermalType.equals("fixedTemperature")) { +// thermalDict.merge(thermalModel); +// } +// toBeDecoded.add(thermalDict); +// } +// +// if (asList) { +// porousZones.addToList(toBeDecoded); +// } else { +// porousZones.add(toBeDecoded); +// } +// } else { +// //System.err.println(zoneName + " NOT A Thermal Zone"); +// } +// } +// } +// } + +} diff --git a/src/eu/engys/core/project/zero/cellzones/CellZonesBuilder.java b/src/eu/engys/core/project/zero/cellzones/CellZonesBuilder.java new file mode 100644 index 0000000..206d32b --- /dev/null +++ b/src/eu/engys/core/project/zero/cellzones/CellZonesBuilder.java @@ -0,0 +1,50 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.cellzones; + +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.core.project.system.FvOptions; + +public interface CellZonesBuilder { + + public void loadMRFDictionary(Model model); + public void loadMRFDictionary(CellZones cellZones, FvOptions fvOptions); + public void saveMRFDictionary(CellZones cellZones, FvOptions fvOptions); + public void saveMRFDictionary(Model model); + + public void loadPorousDictionary(CellZones cellZones, FvOptions fvOptions); + public void loadPorousDictionary(Model model); + public void savePorousDictionary(CellZones cellZones, FvOptions fvOptions); + public void savePorousDictionary(Model model); + + + public void loadThermalDictionary(Model model); + public void loadThermalDictionary(CellZones cellZones, FvOptions fvOptions, State state); + public void saveThermalDictionary(CellZones cellZones, FvOptions fvOptions, State state); + public void saveThermalDictionary(Model model); + +} diff --git a/src/eu/engys/core/project/zero/cellzones/CellZonesReader.java b/src/eu/engys/core/project/zero/cellzones/CellZonesReader.java new file mode 100644 index 0000000..98571a2 --- /dev/null +++ b/src/eu/engys/core/project/zero/cellzones/CellZonesReader.java @@ -0,0 +1,164 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.cellzones; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.FvOptions; +import eu.engys.util.IOUtils; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; + +public class CellZonesReader { + + private static Logger logger = LoggerFactory.getLogger(CellZones.class); + private Set modules; + private ProgressMonitor monitor; + private Model model; + private CellZonesBuilder builder; + + public CellZonesReader(Model model, CellZonesBuilder builder, Set modules, ProgressMonitor monitor) { + this.model = model; + this.builder = builder; + this.modules = modules; + this.monitor = monitor; + } + + public CellZones read(File... cellZonesFiles) { + CellZones cellZones = readCellZoneFiles(cellZonesFiles); + readCellZoneTypeAndDictionary(cellZones); + return cellZones; + } + + public CellZones readCellZoneFiles(File... cellZonesFiles) { + CellZones cellZones = new CellZones(); + List zones = null; + if (cellZonesFiles.length == 1) { + zones = readCellZones(cellZonesFiles[0]); + } else { + zones = readParallelCellZones(cellZonesFiles); + } + cellZones.addAll(zones); + return cellZones; + } + + private void readCellZoneTypeAndDictionary(CellZones cellZones) { + FvOptions fvOptions = model.getProject().getSystemFolder().getFvOptions(); + builder.loadMRFDictionary(cellZones, fvOptions); + builder.loadPorousDictionary(cellZones, fvOptions); + builder.loadThermalDictionary(cellZones, fvOptions, model.getState()); + ModulesUtil.updateCellZonesFromModel(modules, cellZones); + } + + private List readParallelCellZones(File[] cellZonesFiles) { + final List zones = Collections.synchronizedList(new ArrayList()); + Runnable[] runnables = new Runnable[cellZonesFiles.length]; + for (int i = 0; i < cellZonesFiles.length; i++) { + final File cellZoneFile = cellZonesFiles[i]; + runnables[i] = new Runnable() { + @Override + public void run() { + merge(zones, readCellZones(cellZoneFile)); + } + }; + } + ExecUtil.execParallelAndWait(runnables); + return zones; + } + + private void merge(List zones, List readZones) { + for (CellZone zone : readZones) { + if (!zones.contains(zone)) { + zones.add(zone); + } + } + } + + private List readCellZones(File cellZones) throws IllegalStateException { + monitor.setCurrent(null, monitor.getCurrent() + 1, 2); + logger.info("READ: CellZones {}", cellZones.getAbsolutePath()); + List zones = new ArrayList(); + + if (cellZones.exists()) { + try { + String cellZonesString = IOUtils.readStringFromFile(cellZones); + // remove comments + cellZonesString = cellZonesString.replaceAll("/\\*(?:.|[\\n\\r])*?\\*/", ""); + + Pattern pattern = Pattern.compile("(\\d+)\\s*\\("); + Matcher matcher = pattern.matcher(cellZonesString); + + if (matcher.find()) { + + if (matcher.groupCount() == 1) { + String nZones = matcher.group(1); + + Pattern patternForType = Pattern.compile("([\\S]+)\\s*\\{\\s*type\\s*(\\w+);"); + Matcher matcherForType = patternForType.matcher(cellZonesString); + int zonesCounter = 0; + while (matcherForType.find()) { + zonesCounter++; + if (matcherForType.groupCount() == 2) { + String zoneName = matcherForType.group(1); + String zoneType = matcherForType.group(2); + + CellZone cz = new CellZone(zoneName); + cz.setName(zoneName); + cz.setVisible(true); + + zones.add(cz); + } + } + if (Integer.parseInt(nZones) != zonesCounter) { + monitor.error(String.format("Number of read patches (%d) is invalid (expected %d).", zonesCounter, nZones), 2); + } + } + } + } catch (Exception e) { + monitor.warning("Cannot read the file: " + e.getMessage(), 2); + logger.warn("Cannot read the file", e); + } + } else { + monitor.warning("File does not exist", 2); + logger.warn("CellZones file does not exist"); + } + + return zones; + } +} diff --git a/src/eu/engys/core/project/zero/cellzones/CellZonesUtils.java b/src/eu/engys/core/project/zero/cellzones/CellZonesUtils.java new file mode 100644 index 0000000..317141f --- /dev/null +++ b/src/eu/engys/core/project/zero/cellzones/CellZonesUtils.java @@ -0,0 +1,108 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.cellzones; + +public class CellZonesUtils { + + /* + * MRF + */ + public static final String MRF_SOURCE_KEY = "MRFSource"; + public static final String ORIGIN_KEY = "origin"; + public static final String OMEGA_KEY = "omega"; + public static final String AXIS_KEY = "axis"; + public static final String ATTACHED_PATCHES_KEY = "attachedPatches"; + public static final String ROTATING_PATCHES_KEY = "rotatingPatches"; + public static final String NON_ROTATING_PATCHES_KEY = "nonRotatingPatches"; + + /* + * POROUS + */ + public static final String POROUS_DARCY_KEY = "porousDarcy"; + public static final String POROUS_POWER_LAW_KEY = "porousPowerLaw"; + public static final String EXPLICIT_POROSITY_SOURCE_KEY = "explicitPorositySource"; + public static final String E1_KEY = "e1"; + public static final String E2_KEY = "e2"; + public static final String D_KEY = "d"; + public static final String F_KEY = "f"; + public static final String C0_KEY = "C0"; + public static final String C1_KEY = "C1"; + public static final String POWER_LAW_KEY = "powerLaw"; + public static final String DARCY_FORCHHEIMER_KEY = "DarcyForchheimer"; + public static final String COORDINATE_SYSTEM_KEY = "coordinateSystem"; + public static final String COORDINATE_ROTATION_KEY = "coordinateRotation"; + public static final String CARTESIAN_KEY = "cartesian"; + public static final String AXES_ROTATION_KEY = "axesRotation"; + + /* + * Thermal + */ + + public static final String THERMAL_FIXED_KEY = "thermalFixed"; + public static final String THERMAL_SCALAR_KEY = "thermalScalar"; + public static final String THERMAL_EXPONENTIAL_KEY = "thermalExponential"; + public static final String FIXED_TEMPERATURE_CONSTRAINT_KEY = "fixedTemperatureConstraint"; + public static final String EXPONENTIAL_THERMAL_SOURCE_KEY = "exponentialThermalSource"; + public static final String SCALAR_SEMI_IMPLICT_SOURCE_KEY = "scalarSemiImplicitSource"; + public static final String SCALAR_EXPLICIT_SET_VALUE_KEY = "scalarExplicitSetValue"; + public static final String TEMPERATURE_KEY = "temperature"; + public static final String CE_KEY = "Ce"; + public static final String CM_KEY = "Cm"; + public static final String T0_KEY = "T0"; + public static final String MODE_KEY = "mode"; + public static final String VOLUME_MODE_KEY = "volumeMode"; + public static final String PLACE_HOLDER_KEY = "placeHolder"; + public static final String H_KEY = "h"; + public static final String T_KEY = "T"; + public static final String INJECTION_RATE_KEY = "injectionRate"; + public static final String INJECTION_RATE_SU_SP_KEY = "injectionRateSuSp"; + public static final String SPECIFIC_KEY = "specific"; + public static final String UNIFORM_KEY = "uniform"; + + /* + * Humidity + */ + public static final String W_KEY = "w"; + + /* + * Sliding + */ + public static final String t0_KEY = "t0"; + public static final String THETA_KEY = "theta"; + public static final String PERIOD_KEY = "period"; + public static final String ABSOLUTE_KEY = "absolute"; + public static final String[] VOLUME_MODE_KEYS = new String[] { ABSOLUTE_KEY, SPECIFIC_KEY }; + + /* + * OTHER KEYS + */ + public static final String COEFFS_KEY = "Coeffs"; + public static final String ACTIVE_KEY = "active"; + public static final String SELECTION_MODE_KEY = "selectionMode"; + public static final String CELL_ZONE_KEY = "cellZone"; + + +} diff --git a/src/eu/engys/core/project/zero/cellzones/CellZonesWriter.java b/src/eu/engys/core/project/zero/cellzones/CellZonesWriter.java new file mode 100644 index 0000000..c48445d --- /dev/null +++ b/src/eu/engys/core/project/zero/cellzones/CellZonesWriter.java @@ -0,0 +1,141 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.cellzones; + +import java.io.File; +import java.io.FileWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.DictionaryWriter; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.FvOptions; +import eu.engys.util.IOUtils; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; + +public class CellZonesWriter { + + private static final Logger logger = LoggerFactory.getLogger(CellZones.class); + + private ProgressMonitor monitor; + + private Set modules; + + private CellZonesBuilder builder; + + public CellZonesWriter(CellZonesBuilder builder, Set modules, ProgressMonitor monitor) { + this.builder = builder; + this.modules = modules; + this.monitor = monitor; + } + + public void writeFvOptions(Model model) { + FvOptions fvOptions = model.getProject().getSystemFolder().getFvOptions(); + if(fvOptions != null){ + fvOptions.clear(); + } + builder.saveMRFDictionary(model); + builder.savePorousDictionary(model); + builder.saveThermalDictionary(model); + ModulesUtil.updateModelFromCellZones(modules); + } + + public void writeCellZoneFiles(Model model, File... cellZonesFiles) { + final CellZones cellZones = model.getCellZones(); + Runnable[] runnables = new Runnable[cellZonesFiles.length]; + for (int i = 0; i < cellZonesFiles.length; i++) { + final File cellZoneFile = cellZonesFiles[i]; + runnables[i] = new Runnable() { + public void run() { + writeCellZones(cellZones, cellZoneFile); + } + }; + } + ExecUtil.execSerial(runnables); + } + + private void writeCellZones(CellZones cellZones, File cellZonesFile) { + monitor.setCurrent(null, monitor.getCurrent() + 1, 2); + logger.info("WRITE: CellZones {}", cellZonesFile.getAbsolutePath()); + + Map zonesOriginalNames = new HashMap(); + for (CellZone zone : cellZones) { + zonesOriginalNames.put(zone.getOriginalName(), zone.getName()); + } + + try { + String cellZonesString = IOUtils.readStringFromFile(cellZonesFile); + + StringBuffer sb = new StringBuffer(cellZonesString.length()); + + cellZonesString = cellZonesString.replaceAll("/\\*(?:.|[\\n\\r])*?\\*/", ""); + + Pattern pattern = Pattern.compile("(\\d+)\\s*?\\(((?:[\\s\\S])*?\\s*?\\})\\s*?\\)"); + Matcher matcher = pattern.matcher(cellZonesString); + + if (matcher.find()) { + if (matcher.groupCount() == 2) { + String nZones = matcher.group(1); + String zonesString = matcher.group(2); + + FoamFile foamFile = FoamFile.getDictionaryFoamFile("regIOobject", "\"0/polyMesh\"", "cellZones"); + new DictionaryWriter(foamFile).writeDictionary(sb, ""); + + sb.append(nZones + "("); + Pattern patternForType = Pattern.compile("([\\S]+)\\s*?\\{\\s*?type\\s*?(\\w+);"); + Matcher matcherForType = patternForType.matcher(zonesString); + + while (matcherForType.find()) { + String originalName = matcherForType.group(1); + String newName = zonesOriginalNames.get(originalName); + String replacement = newName + "\n {\n type cellZone;"; + matcherForType.appendReplacement(sb, replacement); + } + matcherForType.appendTail(sb); + sb.append(")"); + } + + FileWriter outStream = new FileWriter(cellZonesFile); + outStream.write(sb.toString()); + outStream.close(); + } + } catch (Exception e) { + monitor.warning("Error writing cell zones file " + e.getMessage()); + logger.warn("Error writing cell zones file {}", e.getMessage()); + } + } +} diff --git a/src/eu/engys/core/project/zero/facezones/FaceZone.java b/src/eu/engys/core/project/zero/facezones/FaceZone.java new file mode 100644 index 0000000..a26c15c --- /dev/null +++ b/src/eu/engys/core/project/zero/facezones/FaceZone.java @@ -0,0 +1,98 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.facezones; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.util.ui.checkboxtree.LoadableItem; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class FaceZone implements VisibleItem, LoadableItem { + + private final String originalName; + private String name; + private boolean visible; + private boolean loaded; + private Dictionary dictionary; + + public FaceZone(String originalName) { + this.originalName = originalName; + this.name = originalName; + } + + public String getOriginalName() { + return originalName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean isVisible() { + return visible; + } + + @Override + public void setVisible(boolean selected) { + this.visible = selected; + } + + @Override + public boolean isLoaded() { + return loaded; + } + + @Override + public void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + public void setDictionary(Dictionary d) { + this.dictionary = d; + } + + public Dictionary getDictionary() { + return dictionary; + } + + @Override + public String toString() { + return name + " [" + getName() + ", " + visible + "]"; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof FaceZone) { + return ((FaceZone) obj).getName().equals(name); + } + return super.equals(obj); + } +} diff --git a/src/eu/engys/core/project/zero/facezones/FaceZones.java b/src/eu/engys/core/project/zero/facezones/FaceZones.java new file mode 100644 index 0000000..9807fce --- /dev/null +++ b/src/eu/engys/core/project/zero/facezones/FaceZones.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.facezones; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FaceZones extends ArrayList { + + public FaceZones() { + super(); + } + + public List zonesNames() { + List names = new ArrayList<>(); + for (FaceZone zone : this) { + names.add(zone.getName()); + } + return names; + } + + public Map toMap() { + HashMap zonesMap = new HashMap(); + for (FaceZone zone : this) { + zonesMap.put(zone.getName(), zone); + } + return Collections.unmodifiableMap(zonesMap); + } + + public void addZones(List faceZones) { + addAll(faceZones); + } +} diff --git a/src/eu/engys/core/project/zero/facezones/FaceZonesReader.java b/src/eu/engys/core/project/zero/facezones/FaceZonesReader.java new file mode 100644 index 0000000..3953e81 --- /dev/null +++ b/src/eu/engys/core/project/zero/facezones/FaceZonesReader.java @@ -0,0 +1,142 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.facezones; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.IOUtils; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; + +public class FaceZonesReader { + + private static Logger logger = LoggerFactory.getLogger(FaceZones.class); + private ProgressMonitor monitor; + + public FaceZonesReader(ProgressMonitor monitor) { + this.monitor = monitor; + } + + public FaceZones read(File... faceZonesFiles) { + FaceZones faceZones = new FaceZones(); + if (faceZonesFiles.length == 1) { + faceZones.addAll(readFaceZones(faceZonesFiles[0])); + } else { + faceZones.addAll(readParallelCellZones(faceZonesFiles)); + } + + return faceZones; + } + + private List readParallelCellZones(File[] faceZonesFiles) { + final List zones = Collections.synchronizedList(new ArrayList()); + Runnable[] readZonesRunnables = new Runnable[faceZonesFiles.length]; + for (int i = 0; i < faceZonesFiles.length; i++) { + final File faceZoneFile = faceZonesFiles[i]; + readZonesRunnables[i] = new Runnable() { + @Override + public void run() { + merge(zones, readFaceZones(faceZoneFile)); + } + }; + } + ExecUtil.execParallelAndWait(readZonesRunnables); + return zones; + } + + private void merge(Collection zones, List readZones) { + for (FaceZone zone : readZones) { + if (!zones.contains(zone)) { + zones.add(zone); + } + } + } + + private List readFaceZones(File faceZones) throws IllegalStateException { + monitor.setCurrent(null, monitor.getCurrent() + 1, 2); + logger.info("READ: FaceZones {}", faceZones.getAbsolutePath()); + List zones = new ArrayList(); + + if (faceZones.exists()) { + + try { + String cellZonesString = IOUtils.readStringFromFile(faceZones); + + cellZonesString = cellZonesString.replaceAll("/\\*(?:.|[\\n\\r])*?\\*/", "");// rimuovo + // i + // commenti + + Pattern pattern = Pattern.compile("(\\d+)\\s*\\("); + Matcher matcher = pattern.matcher(cellZonesString); + + if (matcher.find()) { + + if (matcher.groupCount() == 1) { + String nZones = matcher.group(1); + + Pattern patternForType = Pattern.compile("([\\S]+)\\s*\\{\\s*type\\s*(\\w+);"); + Matcher matcherForType = patternForType.matcher(cellZonesString); + int zonesCounter = 0; + while (matcherForType.find()) { + zonesCounter++; + if (matcherForType.groupCount() == 2) { + String zoneName = matcherForType.group(1); + String zoneType = matcherForType.group(2); + + FaceZone cz = new FaceZone(zoneName); + cz.setName(zoneName); + cz.setVisible(true); + + zones.add(cz); + } + } + if (Integer.parseInt(nZones) != zonesCounter) { + monitor.error(String.format("Number of read patches (%d) is invalid (expected %d).", zonesCounter, nZones), 2); + } + } + } + } catch (Exception e) { + monitor.warning("Cannot read the file: " + e.getMessage(), 2); + logger.warn("Cannot read the file", e); + } + } else { + monitor.warning("File does not exist", 2); + logger.warn("FaceZones file does not exist"); + } + + return zones; + } +} diff --git a/src/eu/engys/core/project/zero/fields/AbstractInitialisations.java b/src/eu/engys/core/project/zero/fields/AbstractInitialisations.java new file mode 100644 index 0000000..220374b --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/AbstractInitialisations.java @@ -0,0 +1,80 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.util.ArchiveUtils; +import eu.engys.util.progress.ProgressMonitor; + +public abstract class AbstractInitialisations implements Initialisations { + + private static Logger logger = LoggerFactory.getLogger(AbstractInitialisations.class); + + protected Map map = new HashMap<>(); + + protected final Model model; + + public AbstractInitialisations(Model model) { + this.model = model; + } + + public Dictionary getInitializationFor(String field) { + return map.get(field); + } + + protected void readFieldFromFile(Field field, File zeroDir, ProgressMonitor monitor) { + File file = new File(zeroDir, field.getName()); + if (file.exists()) { + field.read(file); + logger.info("READ: Field {}", field.getName()); + } else { + File fileGZ = new File(zeroDir, field.getName() + "." + ArchiveUtils.GZ); + if (fileGZ.exists()) { + ArchiveUtils.unGZ(fileGZ, zeroDir); + field.read(file); + logger.info("READ: Field {}", field.getName()); + } else { + monitor.warning("Missing field file " + field.getName(), 2); + logger.warn("READ: Missing field {}", field.getName()); + } + } + } + + // For test purpouse only! + public Map getMap() { + return map; + } + +} diff --git a/src/eu/engys/core/project/zero/fields/ArrayInternalField.java b/src/eu/engys/core/project/zero/fields/ArrayInternalField.java new file mode 100644 index 0000000..19fc83b --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/ArrayInternalField.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class ArrayInternalField implements InternalField { + + private String buffer; + private double[] value; + + public ArrayInternalField(double[] value) { + this.value = value; + } + + @Override + public int getSize() { + return 1; + } + + @Override + public double[][] getValue() { + return new double[][] { value }; + } + + @Override + public void write(FileWriter writer) throws IOException { + writer.write(buffer); + } + + @Override + public void buffer(File file) { + buffer = Field.INTERNAL_FIELD + " uniform (" + String.valueOf(value[0]) + " " + String.valueOf(value[1]) + " " + String.valueOf(value[2]) + ");"; + } +} diff --git a/src/eu/engys/core/project/zero/fields/Field.java b/src/eu/engys/core/project/zero/fields/Field.java new file mode 100644 index 0000000..c6fc81b --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/Field.java @@ -0,0 +1,281 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.util.Arrays; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.util.progress.ProgressMonitor; + +public class Field { + + public static final String FIELD_DEFINITION_KEY = "fieldDefinition"; + public static final String INITIALISATION_KEY = "initialisation"; + public static final String BOUNDARY_FIELD = "boundaryField"; + public static final String DIMENSIONS = "dimensions"; + public static final String INTERNAL_FIELD = "internalField"; + + public enum FieldType { + + SCALAR, VECTOR, POINT; + + public static FieldType getType(String string) { + switch (string) { + case "scalar": + return SCALAR; + case "vector": + return VECTOR; + case "point": + return POINT; + default: + return null; + } + } + + public boolean isScalar() { + return this == SCALAR; + } + + public boolean isVector() { + return this == VECTOR; + } + + public boolean isPoint() { + return this == POINT; + } + } + + private InternalField internalField; + private Dictionary boundaryField; + + + private FieldType fieldType; + private String[] initialisationMethods; + private Dictionary initialisation = new Dictionary(INITIALISATION_KEY); + private Dictionary definition = new Dictionary(FIELD_DEFINITION_KEY); + private String name; + private String dimensions; + private transient boolean visible; + + public Field(String name) { + this.name = name; + this.dimensions = null; + this.internalField = null; + this.boundaryField = new Dictionary(BOUNDARY_FIELD); + this.visible = true; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getInitialisationType() { + return initialisation.lookup(Dictionary.TYPE); + } + + public FieldType getFieldType() { + return fieldType; + } + + public void setFieldType(FieldType fieldType) { + this.fieldType = fieldType; + } + + public Dictionary getInitialisation() { + return initialisation; + } + + public void setInitialisation(Dictionary initialisation) { + this.initialisation = initialisation; + } + + public void setInitialisationMethods(String[] initMethods) { + this.initialisationMethods = initMethods; + } + + public String[] getInitialisationMethods() { + return initialisationMethods; + } + + public Dictionary getDefinition() { + return definition; + } + + public void setDefinition(Dictionary definition) { + this.definition = definition; + } + + public Dictionary getBoundaryField() { + return boundaryField; + } + + public String getDimensions() { + return dimensions; + } + + public void read(File file) { + new FieldReader(this).read(file); + } + + public void setDimensions(String dimensions) { + this.dimensions = dimensions; + } + + public void setInternalField(String internalField) { + if (internalField != null && !internalField.isEmpty()) { + this.internalField = new FieldReader(this).readValue(internalField); + } else { + this.internalField = null; + } + } + + public void setInternalField(InternalField internalField) { + this.internalField = internalField; + } + + public void setBoundaryField(Dictionary boundaryField) { + this.boundaryField = boundaryField; + } + + public InternalField getInternalField() { + return internalField; + } + + public void write(File zeroDir, ProgressMonitor monitor) { + new FieldWriter(this, monitor).write(zeroDir); + } + + public void bufferInternalField(File zeroDir, ProgressMonitor monitor) { + new FieldWriter(this, monitor).bufferInternalField(zeroDir); + } + + public void merge(Field field) { + if (field.boundaryField != null && !field.boundaryField.isEmpty() ) { + setBoundaryField(field.boundaryField); + } + if (field.definition != null) { + if (this.definition != null) { + this.definition.merge(field.definition); + } else { + setDefinition(new Dictionary(field.definition)); + } + } + if (field.dimensions != null) { + setDimensions(field.dimensions); + } + if (field.fieldType != null) { + setFieldType(field.fieldType); + } + if (field.initialisation != null) { +// if (this.initialisation != null) { +// this.initialisation.merge(field.initialisation); +// } else { + setInitialisation(new Dictionary(field.initialisation)); +// } + } + if (field.initialisationMethods != null) { + setInitialisationMethods(field.initialisationMethods); + } + if (field.internalField != null) { + setInternalField(field.internalField); + } + + setVisible(field.visible); + + } + + @Override + public String toString() { + return name + " " + fieldType + " " + Arrays.toString(initialisationMethods) + " " + initialisation + definition; + } + + public static void main(String[] args) { + /* U */ + Field U0 = new Field("U"); + Field U1 = new Field("U"); + Field U2 = new Field("U"); + Field U3 = new Field("U"); + U0.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor0/0/U")); + U1.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor1/0/U")); + U2.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor2/0/U")); + U3.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor3/0/U")); + + /* p */ + Field p0 = new Field("p"); + Field p1 = new Field("p"); + Field p2 = new Field("p"); + Field p3 = new Field("p"); + p0.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor0/0/p")); + p1.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor1/0/p")); + p2.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor2/0/p")); + p3.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor3/0/p")); + + /* epsilon */ + Field epsilon0 = new Field("epsilon"); + Field epsilon1 = new Field("epsilon"); + Field epsilon2 = new Field("epsilon"); + Field epsilon3 = new Field("epsilon"); + epsilon0.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor0/0/epsilon")); + epsilon1.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor1/0/epsilon")); + epsilon2.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor2/0/epsilon")); + epsilon3.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor3/0/epsilon")); + + /* nut */ + Field nut0 = new Field("nut"); + Field nut1 = new Field("nut"); + Field nut2 = new Field("nut"); + Field nut3 = new Field("nut"); + nut0.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor0/0/nut")); + nut1.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor1/0/nut")); + nut2.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor2/0/nut")); + nut3.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor3/0/nut")); + + /* k */ + Field k0 = new Field("k"); + Field k1 = new Field("k"); + Field k2 = new Field("k"); + Field k3 = new Field("k"); + k0.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor0/0/k")); + k1.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor1/0/k")); + k2.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor2/0/k")); + k3.read(new File("/home/stefano/ENGYS/examples/HELYX2/DanicaRANS/processor3/0/k")); + + } +} diff --git a/src/eu/engys/core/project/zero/fields/FieldFilter.java b/src/eu/engys/core/project/zero/fields/FieldFilter.java new file mode 100644 index 0000000..e289bfd --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/FieldFilter.java @@ -0,0 +1,32 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +public interface FieldFilter { + + boolean accept(Field field); + +} diff --git a/src/eu/engys/core/project/zero/fields/FieldReader.java b/src/eu/engys/core/project/zero/fields/FieldReader.java new file mode 100644 index 0000000..a6289ee --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/FieldReader.java @@ -0,0 +1,245 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import static eu.engys.core.project.zero.fields.Fields.ALPHA; +import static eu.engys.core.project.zero.fields.Fields.U; + +import java.io.File; +import java.io.FileInputStream; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryReader; +import eu.engys.core.dictionary.parser.DictionaryReader2; +import eu.engys.util.CompactStringBuilder; + +public class FieldReader { + + private static final String BOUNDARY_FIELD = "boundaryField"; + + private static final Logger logger = LoggerFactory.getLogger(FieldReader.class); + + private static final int SIZE = 8192; + + private static final Pattern END_PATTERN = Pattern.compile("([^#]*;\\s*}\\s*})\\s*.*"); + private static final String DOUBLE_NUMBER = "(\\s*\\-?\\d*\\.?\\d+([eE][-+]?[0-9]+)*\\s*)"; + private static final Pattern DOUBLE_NUMBER_PATTERN = Pattern.compile(DOUBLE_NUMBER); + private static final Pattern NONUNIFORM_VECTOR_PATTERN = Pattern.compile("internalField\\s+nonuniform\\s+List\\s+(\\d+)?\\s+\\(\\s+(\\([^#]*\\))\\s+\\)\\s*"); + private static final Pattern NONUNIFORM_SCALAR_PATTERN = Pattern.compile("internalField\\s+nonuniform\\s+List\\s+(\\d+)?\\s+\\(([^#]*)\\s+\\)\\s*"); + private static final Pattern UNIFORM_VECTOR_PATTERN = Pattern.compile("internalField\\s+uniform\\s+\\(([^\\)]*)\\)"); + private static final Pattern UNIFORM_SCALAR_PATTERN = Pattern.compile("internalField\\s+uniform\\s+" + DOUBLE_NUMBER); + + private Field field; + + public FieldReader(Field field) { + this.field = field; + } + + public void read(File file) { + field.setDimensions(readDimensions(file)); + field.setBoundaryField(readBoundaryField(file)); + field.setInternalField(readInternalField(file)); + // System.gc(); + // System.out.println("ReadField.read() "+MemoryStatus.getToolTipText(true)); + } + + private String readDimensions(File file) { + return extractString(file, "dimensions").toString().replace("dimensions", "").trim(); + } + + private InternalField readInternalField(File file) { + CharSequence internalField = extractString(file, "internalField"); + return readValue(internalField); + } + + InternalField readValue(CharSequence internalField) { + Matcher matrixMatcher = NONUNIFORM_VECTOR_PATTERN.matcher(internalField); + Matcher vectorMatcher = NONUNIFORM_SCALAR_PATTERN.matcher(internalField); + Matcher arrayMatcher = UNIFORM_VECTOR_PATTERN.matcher(internalField); + Matcher scalarMatcher = UNIFORM_SCALAR_PATTERN.matcher(internalField); + + if (matrixMatcher.matches()) { + logger.debug("Matrix: " + field.getName()); + String total = matrixMatcher.group(1); + return new MatrixInternalField(Integer.parseInt(total)); + } else if (vectorMatcher.matches()) { + logger.debug("Vector: " + field.getName()); + String total = vectorMatcher.group(1); + return new VectorInternalField(Integer.parseInt(total)); + } else if (arrayMatcher.matches()) { + logger.debug("Array: " + field.getName()); + double[] value = populateArray(arrayMatcher.group(1)); + return new ArrayInternalField(value); + } else if (scalarMatcher.matches()) { + logger.debug("Scalar: " + field.getName()); + double value = Double.parseDouble(scalarMatcher.group(1)); + return new ScalarInternalField(value); + } else { + logger.error("NO MATCH FOR {}, IT WILL BE READ AS A UNIFORM FIELD", field.getName()); + return readValue("internalField uniform " + (field.getName().startsWith(U) ? "(0 0 0)" : "0")); + } + } + + private double[] populateArray(String string) { + Matcher rowRegexMatcher = DOUBLE_NUMBER_PATTERN.matcher(string); + double[] value = new double[3]; + + int columnCounter = 0; + while (rowRegexMatcher.find()) { + value[columnCounter] = Double.valueOf(rowRegexMatcher.group().trim()); + if (columnCounter > 3) { + break; + } + columnCounter++; + } + + return value; + } + + private Dictionary readBoundaryField(File file) { + StringBuilder boundaryBuffer = new StringBuilder(); + + try (FileInputStream f = new FileInputStream(file)) { + + FileChannel ch = f.getChannel(); + byte[] barray = new byte[SIZE]; + ByteBuffer bb = ByteBuffer.wrap(barray); + boolean found = false; + + String previous = ""; + int read = 0; + while ((read = ch.read(bb)) != -1) { + String current = new String(barray, 0, read); + String boundaryString = ""; + + if (!found) { + if (current.contains(BOUNDARY_FIELD)) { + found = true; + boundaryString = current.substring(current.indexOf(BOUNDARY_FIELD)); + } else { + String concat = previous.concat(current); + if (concat.contains(BOUNDARY_FIELD)) { + found = true; + boundaryString = concat.substring(concat.indexOf(BOUNDARY_FIELD)); + } + } + } else { + boundaryString = current; + } + + if (found) { + Matcher endMatcher = END_PATTERN.matcher(boundaryString); + if (endMatcher.matches()) { + boundaryString = endMatcher.group(1); + boundaryBuffer.append(boundaryString); + break; + } else { + boundaryBuffer.append(boundaryString); + } + } + + bb.clear(); + previous = current; + } + } catch (Exception e) { + e.printStackTrace(); + } + String text = boundaryBuffer.toString(); + + Dictionary d = new Dictionary(""); + if (field.getName().startsWith(ALPHA)) { + new DictionaryReader2(d).read(text); + } else { + new DictionaryReader(d).read(text); + } + + if (d.found(BOUNDARY_FIELD)) { + return d.subDict(BOUNDARY_FIELD); + } else { + return new Dictionary(BOUNDARY_FIELD); + } + } + + public static CharSequence extractString(File file, String keyToExtract) { + CompactStringBuilder buffer = new CompactStringBuilder(); + + try (FileInputStream f = new FileInputStream(file)) { + FileChannel ch = f.getChannel(); + byte[] barray = new byte[SIZE]; + ByteBuffer bb = ByteBuffer.wrap(barray); + + boolean found = false; + + String previous = ""; + + while (ch.read(bb) != -1) { + String current = new String(barray); + String internalString = ""; + + if (!found) { + if (current.contains(keyToExtract)) { + found = true; + internalString = current.substring(current.indexOf(keyToExtract)); + } else { + String concat = previous.concat(current); + + if (concat.contains(keyToExtract)) { + found = true; + internalString = concat.substring(concat.indexOf(keyToExtract)); + } + } + } else { + internalString = current; + } + + if (found) { + if (internalString.contains(";")) { + internalString = internalString.substring(0, internalString.indexOf(";")); + buffer.append(internalString); + break; + } else { + buffer.append(internalString); + } + } + + bb.clear(); + + previous = current; + } + } catch (Exception e) { + e.printStackTrace(); + } + + return buffer.toCompactCharSequence(); + } +} diff --git a/src/eu/engys/core/project/zero/fields/FieldWriter.java b/src/eu/engys/core/project/zero/fields/FieldWriter.java new file mode 100644 index 0000000..ba5fa91 --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/FieldWriter.java @@ -0,0 +1,78 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.io.FileWriter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.util.progress.ProgressMonitor; + +public class FieldWriter { + + private static final Logger logger = LoggerFactory.getLogger(FieldWriter.class); + + private Field field; + + private ProgressMonitor monitor; + + public FieldWriter(Field field, ProgressMonitor monitor) { + this.field = field; + this.monitor = monitor; + } + + public void bufferInternalField(File zeroDir) { + String name = field.getName(); + InternalField internalField = field.getInternalField(); + File file = new File(zeroDir, name); + internalField.buffer(file); + } + + public void write(File zeroDir) { + String name = field.getName(); + String dimensions = field.getDimensions(); + Dictionary boundaryField = field.getBoundaryField(); + InternalField internalField = field.getInternalField(); + File file = new File(zeroDir, name); +// monitor.info(name, 2); + logger.info("WRITE : {}", file); + + try (FileWriter writer = new FileWriter(file)) { + writer.write(FoamFile.HEADER); + writer.write(FoamFile.getFieldFoamFile(name).toString()); + writer.write(Field.DIMENSIONS + " " + dimensions + ";\n"); + internalField.write(writer); + writer.write(boundaryField.toString()); + } catch (Exception e) { + monitor.error("Error writing " + file); + logger.error("Error writing " + file, e); + } + } +} diff --git a/src/eu/engys/core/project/zero/fields/Fields.java b/src/eu/engys/core/project/zero/fields/Fields.java new file mode 100644 index 0000000..0ce26f6 --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/Fields.java @@ -0,0 +1,232 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; + +import eu.engys.core.project.state.State; + +public class Fields extends LinkedHashMap { + + public static final String SMOKE = "smoke"; + public static final String DT_SMOKE = "Dtsmoke"; + public static final String CO2 = "CO2"; + public static final String DT_CO2 = "DtCO2"; + public static final String AOA = "AoA"; + public static final String DT_AOA = "DtAoA"; + public static final String W = "w"; + public static final String DT_W = "Dtw"; + public static final String T = "T"; + public static final String MU_SGS = "muSgs"; + public static final String ALPHA_1 = "alpha1"; + public static final String ALPHA_SGS = "alphaSgs"; + public static final String ALPHA_T = "alphat"; + public static final String ALPHA_S = "alphas"; + public static final String NU_TILDA = "nuTilda"; + public static final String EPSILON = "epsilon"; + public static final String OMEGA = "omega"; + public static final String K = "k"; + public static final String P_RGH = "p_rgh"; + public static final String P = "p"; + public static final String U = "U"; + public static final String IDEFAULT = "IDefault"; + public static final String NU_SGS = "nuSgs"; + public static final String NUT = "nut"; + public static final String MUT = "mut"; + public static final String RHO = "rho"; + public static final String ILAMBDA = "ILambda"; + public static final String FINAL = "Final"; + + public static final String ALPHA = "alpha"; + public static final String ETA = "eta"; + + private Fields[] parallelFields; + + public static final String EDITABLE_FIELDS[] = new String[] { U, P, P_RGH, K, OMEGA, EPSILON, NU_TILDA, T, W, AOA, CO2, SMOKE }; + private static final String PASSIVE_SCALARS[] = new String[] { W, AOA, CO2, SMOKE }; + + public List listFields(FieldFilter filter) { + List list = new LinkedList(); + for (Field field : orderedFields()) { + if (filter.accept(field)) { + list.add(field); + } + } + return list; + } + + public List orderedFieldsExcludingPassiveScalars() { + List list = new LinkedList(); + for (Field field : orderedFields()) { + if (!isPassiveScalar(field)) { + list.add(field); + } + } + return list; + } + + public List orderedFields() { + List list = new LinkedList(); + list.addAll(getMultiphaseUFields()); + for (String fieldName : EDITABLE_FIELDS) { + if (this.containsKey(fieldName)) { + Field field = this.get(fieldName); + if (field.isVisible()) { + list.add(field); + } + } + } + list.addAll(getAlphaFields()); + return list; + } + + public List orderedFieldsNames() { + List list = new LinkedList<>(); + for (Field field : orderedFields()) { + list.add(field.getName()); + } + return list; + } + + public List getMultiphaseUFields() { + List list = new LinkedList(); + for (Field field : this.values()) { + String name = field.getName(); + if (name.startsWith(U) && !name.equals(U)) { + list.add(field); + } + } + return list; + } + + public List getAlphaFields() { + List list = new LinkedList(); + for (Field field : this.values()) { + String name = field.getName(); + if (name.startsWith(ALPHA) && !name.equals(ALPHA_S) && !name.equals(ALPHA_SGS) && !name.equals(ALPHA_T)) { + list.add(field); + } + } + return list; + } + + private boolean isPassiveScalar(Field field) { + for (String s : PASSIVE_SCALARS) { + if (s.equals(field.getName())) { + return true; + } + } + return false; + } + + public List fieldNames() { + return new LinkedList<>(keySet()); + } + + public Fields[] getParallelFields() { + return parallelFields; + } + + public Fields getFieldsForProcessor(int processor) { + return parallelFields[processor]; + } + + public void setParallelFields(Fields[] parallelFields) { + this.parallelFields = parallelFields; + } + + public void newParallelFields(int processors) { + parallelFields = new Fields[processors]; + for (int i = 0; i < parallelFields.length; i++) { + parallelFields[i] = new Fields(); + } + } + + @Override + public void clear() { + super.clear(); + if (parallelFields != null) { + for (Fields pf : parallelFields) { + pf.clear(); + } + } + } + + public static String ALPHA(String phaseName) { + return ALPHA + phaseName; + } + + public static String PHASE(String fieldName) { + return fieldName.replace(ALPHA, ""); + } + + public static String PHASE_OS(String fieldName) { + return fieldName.replace(ALPHA + ".", ""); + } + + public void merge(Fields fields) { + // putAll(fields); + for (String key : fields.keySet()) { + if (containsKey(key)) { + get(key).merge(fields.get(key)); + } else { + put(key, fields.get(key)); + } + } + + if (fields.getParallelFields() != null) { + if (parallelFields == null) { + newParallelFields(fields.getParallelFields().length); + } + + Fields[] parallelFields2 = fields.getParallelFields(); + for (int i = 0; i < parallelFields.length; i++) { + if (parallelFields2.length > i) { + parallelFields[i].merge(parallelFields2[i]); + } + } + } + } + + public void fixPVisibility(State state) { + boolean stateCompressible = state.isCompressible(); + boolean stateBuoyant = state.isBuoyant(); + boolean prghPresent = containsKey(P_RGH); + boolean pPresent = containsKey(P); + + if (pPresent && prghPresent) { + if (stateCompressible && stateBuoyant) { + get(P).setVisible(false); + get(P_RGH).setVisible(true); + } else { + get(P).setVisible(true); + get(P_RGH).setVisible(false); + } + } + } +} diff --git a/src/eu/engys/core/project/zero/fields/FieldsDefaults.java b/src/eu/engys/core/project/zero/fields/FieldsDefaults.java new file mode 100644 index 0000000..477d1be --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/FieldsDefaults.java @@ -0,0 +1,247 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import static eu.engys.core.project.constant.TurbulenceProperties.FIELD_MAPS_KEY; +import static eu.engys.core.project.constant.TurbulenceProperties.LES; +import static eu.engys.core.project.constant.TurbulenceProperties.RAS; + +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.project.defaults.DefaultsProvider; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.fields.Field.FieldType; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.core.project.zero.patches.Patches; + +public class FieldsDefaults { + + private static final Logger logger = LoggerFactory.getLogger(FieldsDefaults.class); + private static Map oldInitialisations = new HashMap(); + + private DefaultsProvider defaults; + + private FieldsDefaults(DefaultsProvider defaults) { + this.defaults = defaults; + } + + public static void prepareFields(Fields fields) { + saveInitializations(fields); + fields.clear(); + } + + private static void saveInitializations(Fields fieldsMap) { + oldInitialisations.clear(); + + for (String key : fieldsMap.keySet()) { + oldInitialisations.put(key, fieldsMap.get(key).getInitialisation()); + } + } + + private static void applySavedInitialization(Field field) { + if (oldInitialisations.containsKey(field.getName())) { + Dictionary initialisation = oldInitialisations.get(field.getName()); + field.setInitialisation(new Dictionary(initialisation)); + } + } + + public static Fields loadFieldsFromDefaults(State state, DefaultsProvider defaults, Patches patches, String region) { + return new FieldsDefaults(defaults).loadDefaultFields(state, patches, region); + } + + public static Field loadFieldFromDefaults(String name, DefaultsProvider defaults, Patches patches) { + return new FieldsDefaults(defaults).loadDefaultField(name, name, patches); + } + + private Field loadDefaultField(String name, String value, Patches patches) { + return newFieldFromDefaults(name, value, patches); + } + + private Fields loadDefaultFields(State state, Patches patches, String region) { + Dictionary defaultFields = getDefaultFieldMaps(state, region); + + Fields fields = addNewFields(defaultFields, patches); + if (patches.getParallelPatches() != null) { + Fields[] parallelFields = new Fields[patches.getParallelPatches().length]; + for (int i = 0; i < parallelFields.length; i++) { + parallelFields[i] = addNewFields(defaultFields, patches); + } + fields.setParallelFields(parallelFields); + } + + return fields; + } + + private Dictionary getDefaultFieldMaps(State state, String region) { + Dictionary fieldMaps = new Dictionary(FIELD_MAPS_KEY); + fieldMaps.merge(getTurbulenceFieldMaps(state, defaults, region)); + fieldMaps.merge(getStateFieldMaps(state, defaults, region)); + return fieldMaps; + } + + private Dictionary getStateFieldMaps(State state, DefaultsProvider defaults, String region) { + return defaults.getDefaultsFieldMapsFor(state, region); + } + + private Dictionary getTurbulenceFieldMaps(State state, DefaultsProvider defaults, String region) { + if (state.getTurbulenceModel() != null && !state.getFlow().isNone() && !state.getMethod().isNone() && !state.getSolverType().isNone()) { + String modelName = state.getTurbulenceModel().getName(); + String compType = state.getSolverType().isCoupled() ? "coupledIncompressible" : state.isCompressible() ? "compressible" : "incompressible"; + String turbType = state.isLES() ? LES : RAS; + String modelCoeffs = modelName + "Coeffs"; + + Dictionary fieldMaps = new Dictionary(FIELD_MAPS_KEY); + + Dictionary tpp = defaults.getDefaultTurbulenceProperties(); + if (tpp != null && tpp.isDictionary(compType + turbType)) { + if (tpp.subDict(compType + turbType).isDictionary(modelCoeffs)) { + Dictionary defCoeff = tpp.subDict(compType + turbType).subDict(modelCoeffs); + if (region != null) { + if (defCoeff.found(FIELD_MAPS_KEY+"."+region)) { + fieldMaps.merge(defCoeff.subDict(FIELD_MAPS_KEY+"."+region)); + } + } else { + if (defCoeff.found(FIELD_MAPS_KEY)) { + fieldMaps.merge(defCoeff.subDict(FIELD_MAPS_KEY)); + } + } + } + } + return fieldMaps; + } + return new Dictionary(""); + } + + private Fields addNewFields(Dictionary defaultFieldsMap, Patches patches) { + Fields fields = new Fields(); + for (FieldElement element : defaultFieldsMap.getFields()) { + String name = element.getName(); + String value = element.getValue(); + + Field field = newFieldFromDefaults(name, value, patches); + + applySavedInitialization(field); + + fields.put(name, field); + } + return fields; + } + + private Field newFieldFromDefaults(String name, String value, Patches patches) { + Dictionary defaultsDictionary = getDefaultsDictionary(value); + + Field field = new Field(name); + if (defaultsDictionary.found("initialisation")) { + field.setInitialisation(new Dictionary(defaultsDictionary.subDict("initialisation"))); + } + if (defaultsDictionary.found("allowedFieldInitialisationMethods")) { + field.setInitialisationMethods(defaultsDictionary.lookupArray("allowedFieldInitialisationMethods")); + } + if (defaultsDictionary.found("fieldDefinition")) { + Dictionary definition = new Dictionary(defaultsDictionary.subDict("fieldDefinition")); + field.setDefinition(definition); + field.setFieldType(FieldType.getType(definition.lookup(Dictionary.TYPE))); + field.setDimensions(definition.lookup("dimensions")); + field.setInternalField("internalField " + definition.lookup("internalField")); + field.setBoundaryField(getBoundaryConditionsFromDefaults(field.getFieldType(), patches, definition)); + } + + return field; + } + + private Dictionary getDefaultsDictionary(String value) { + Dictionary defaultsDictionary = defaults.getDefaultFieldsData().subDict(value); + if (defaultsDictionary == null) { + logger.warn("Cannot find {} into defaults", value); + // JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Cannot find " + value + " into defaults", "Warning", JOptionPane.WARNING_MESSAGE); + return new Dictionary(""); + } + return defaultsDictionary; + } + + private Dictionary getBoundaryConditionsFromDefaults(FieldType fieldType, Patches patches, Dictionary definition) { + Dictionary regionDefaults = definition.subDict("boundaryConditions").subDict("regionDefaults"); + Dictionary boundaryField = new Dictionary("boundaryField"); + for (Patch patch : patches) { + boundaryField.add(getDefaultBoundaryCondition(fieldType, regionDefaults, patch)); + } + return boundaryField; + } + + private static Dictionary getDefaultBoundaryCondition(FieldType fieldType, Dictionary regionDefaults, Patch patch) { + String patchType = patch.getPhisicalType() == BoundaryType.OPENING ? BoundaryType.PATCH_KEY : patch.getPhisicalType().getKey(); + String patchName = patch.getName(); + + if (regionDefaults.found(patchType)) { + Dictionary defaultDictionary = regionDefaults.subDict(patchType); + Dictionary fieldPatch = new Dictionary(patchName); + fieldPatch.merge(defaultDictionary); + return fieldPatch; + } else if (patch.getPhisicalType().isCyclicAMI()) { + Dictionary fieldPatch = new Dictionary(patchName); + fieldPatch.add(Dictionary.TYPE, BoundaryType.CYCLIC_AMI_KEY); + fieldPatch.add(Dictionary.VALUE, fieldType == FieldType.SCALAR ? "uniform 0" : "uniform (0 0 0)"); + return fieldPatch; + } else { + Dictionary fieldPatch = new Dictionary(patchName); + fieldPatch.add(Dictionary.TYPE, patchType); + return fieldPatch; + } + } + + public static void setAsDefault(Field field, Patch patch) { + String patchName = patch.getName(); + String fieldName = field.getName(); + + try { + if(field.getDefinition() != null && !field.getDefinition().isEmpty()){ + Dictionary boundaryField = field.getBoundaryField(); + Dictionary regionDefaults = field.getDefinition().subDict("boundaryConditions").subDict("regionDefaults"); + + Dictionary defaultDictionary = getDefaultBoundaryCondition(field.getFieldType(), regionDefaults, patch); + if (boundaryField.found(patchName) && !fieldName.equals("U")) { + Dictionary fieldPatch = boundaryField.subDict(patchName); + fieldPatch.clear(); + fieldPatch.merge(defaultDictionary); + } else { + Dictionary fieldPatch = new Dictionary(patchName); + fieldPatch.merge(defaultDictionary); + boundaryField.add(fieldPatch); + } + } + } catch (Exception e) { + logger.error(patchName + " " + fieldName, e); + } + } + +} diff --git a/src/eu/engys/core/project/zero/fields/FieldsReader.java b/src/eu/engys/core/project/zero/fields/FieldsReader.java new file mode 100644 index 0000000..2b443b8 --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/FieldsReader.java @@ -0,0 +1,109 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.util.ArrayList; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.util.progress.ProgressMonitor; + +public class FieldsReader { + + private static final Logger logger = LoggerFactory.getLogger(FieldsReader.class); + + private Initialisations initialisations; + private ProgressMonitor monitor; + + public FieldsReader(Initialisations initialisations, ProgressMonitor monitor) { + this.monitor = monitor; + this.initialisations = initialisations; + } + + public Fields read(final Set fieldNames, File... zeroDirs) { + Fields fields = creteNewFields(zeroDirs); + + Fields[] parallelFields = fields.getParallelFields(); + + int total = zeroDirs.length * fieldNames.size(); + monitor.setCurrent("Reading fields", 0, total, 1); + + for (int i = 0; i < parallelFields.length; i++) { + final Fields pFields = parallelFields[i]; + final File zeroDir = zeroDirs[i]; + readFields(pFields, fieldNames, zeroDir); + } + copyFields(parallelFields[0], fields); + + return fields; + } + + private Fields creteNewFields(File... zeroDirs) { + Fields fields = new Fields(); + Fields[] parallelFields = new Fields[zeroDirs.length]; + for (int i = 0; i < parallelFields.length; i++) { + parallelFields[i] = new Fields(); + } + fields.setParallelFields(parallelFields); + + return fields; + } + + private void readFields(Fields fields, Set fieldNames, File zeroDir) { + logger.debug("----------Reading fields from {}", zeroDir); + + for (String fieldName : fieldNames) { + fields.put(fieldName, new Field(fieldName)); + } + + if (initialisations != null) { + for (int i = 0; i < fields.size(); i++) { + Field field = new ArrayList<>(fields.values()).get(i); + initialisations.readInitialisationFromFile(field); + initialisations.loadInitialisation(zeroDir, field, monitor); + monitor.setCurrent(null, monitor.getCurrent() + 1, 2); + } + } + } + + private void copyFields(Fields sources, Fields targets) { + for (Field source : sources.values()) { + Field target = new Field(source.getName()); + target.setDefinition(new Dictionary(source.getDefinition())); + target.setDimensions(source.getDimensions()); + target.setInitialisation(new Dictionary(source.getInitialisation())); + target.setInitialisationMethods(source.getInitialisationMethods()); + target.setFieldType(source.getFieldType()); + target.setInternalField(source.getInternalField()); + + targets.put(target.getName(), target); + } + } +} diff --git a/src/eu/engys/core/project/zero/fields/FieldsWriter.java b/src/eu/engys/core/project/zero/fields/FieldsWriter.java new file mode 100644 index 0000000..e8ac8c5 --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/FieldsWriter.java @@ -0,0 +1,117 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.util.ArrayList; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.zero.ZeroFolderUtil; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; + +public class FieldsWriter { + + private static Logger logger = LoggerFactory.getLogger(Fields.class); + + private ProgressMonitor monitor; + + public FieldsWriter(ProgressMonitor monitor) { + this.monitor = monitor; + } + + public void write(Fields fields, File... zeroDirs) { + if (zeroDirs.length == 1) { + _write(fields, zeroDirs[0]); + } else { + writeParallel(fields, zeroDirs); + } + } + + private void writeParallel(Fields fields, File... zeroDirs) { + Runnable[] runnables = new Runnable[zeroDirs.length]; + for (int i = 0; i < zeroDirs.length; i++) { + final Fields fieldsForProc = fields.getFieldsForProcessor(i); + + if (fieldsForProc.size() != fields.size()) { + logger.warn("Fields for processor {} are {}!", i, fieldsForProc.keySet()); + } + + final File zeroDir = zeroDirs[i]; + runnables[i] = new Runnable() { + @Override + public void run() { + _write(fieldsForProc, zeroDir); + monitor.setCurrent(null, monitor.getCurrent() + 1, 2); + } + }; + } + ExecUtil.execSerial(runnables); + // ExecUtil.execInParallelAndWait(runnables); + } + + private void _write(Fields fields, final File zeroDir) { + if (fields.isEmpty()) { + logger.info("WRITE: Fields -> none", 2); + } else { + bufferInternalFields(fields, zeroDir); + ZeroFolderUtil.clearFiles(zeroDir); + writeFields(zeroDir, fields); + } + } + + private void bufferInternalFields(Fields fields, final File zeroDir) { + Runnable[] runnablesForBuffer = new Runnable[fields.size()]; + for (int i = 0; i < fields.size(); i++) { + final Field field = new ArrayList<>(fields.values()).get(i); + runnablesForBuffer[i] = new Runnable() { + @Override + public void run() { + field.bufferInternalField(zeroDir, monitor); + } + }; + } + ExecUtil.execSerial(runnablesForBuffer); + // ExecUtil.execInParallelAndWait(runnablesForBuffer); + } + + private void writeFields(final File zeroDir, Fields fields) { + Runnable[] runnablesForWrite = new Runnable[fields.size()]; + for (int i = 0; i < fields.size(); i++) { + final Field field = new ArrayList<>(fields.values()).get(i); + runnablesForWrite[i] = new Runnable() { + @Override + public void run() { + field.write(zeroDir, monitor); + } + }; + } + ExecUtil.execSerial(runnablesForWrite); + // ExecUtil.execInParallelAndWait(runnablesForWrite); + } +} diff --git a/src/eu/engys/core/project/zero/fields/Initialisations.java b/src/eu/engys/core/project/zero/fields/Initialisations.java new file mode 100644 index 0000000..dcecf17 --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/Initialisations.java @@ -0,0 +1,49 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.fields; + +import java.io.File; + +import eu.engys.util.progress.ProgressMonitor; + +public interface Initialisations { + + public static final String DEFAULT_KEY = "default"; + public static final String FIXED_VALUE_KEY = "fixedValue"; + public static final String POTENTIAL_FLOW_KEY = "potentialFlow"; + public static final String PRANDTL_KEY = "Prandtl"; + public static final String TURBULENT_IL_KEY = "turbulentIL"; + public static final String BOUNDARY_VALUE_KEY = "boundaryValue"; + public static final String CELL_SET_KEY = "cellSet"; + public static final String INITIALISE_UBCS_KEY = "initialiseUBCs"; + public static final String PATCH_KEY = "patch"; + + public void readInitialisationFromFile(Field field); + + public void loadInitialisation(File zeroDir, Field field, ProgressMonitor monitor); + +} diff --git a/src/eu/engys/core/project/zero/fields/InternalField.java b/src/eu/engys/core/project/zero/fields/InternalField.java new file mode 100644 index 0000000..59cf2db --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/InternalField.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public interface InternalField { + + int getSize(); + + double[][] getValue(); + + void write(FileWriter writer) throws IOException; + + void buffer(File file); + +} diff --git a/src/eu/engys/core/project/zero/fields/MatrixInternalField.java b/src/eu/engys/core/project/zero/fields/MatrixInternalField.java new file mode 100644 index 0000000..9cbc7b2 --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/MatrixInternalField.java @@ -0,0 +1,68 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class MatrixInternalField implements InternalField { + + private int size; + private CharSequence buffer; + + public MatrixInternalField(int size) { + this.size = size; + } + + @Override + public int getSize() { + return size; + } + + @Override + public double[][] getValue() { + return null; + } + + @Override + public void write(FileWriter writer) throws IOException { + int len = buffer.length(); + int BUF_LENGTH = 1024; + for (int start = 0, end = Math.min(BUF_LENGTH, len); end <= len + BUF_LENGTH; start = end, end += BUF_LENGTH) { + writer.write(buffer.subSequence(start, Math.min(end, len)).toString()); + } + + writer.write(";\n"); + buffer = null; + } + + @Override + public void buffer(File file) { + buffer = FieldReader.extractString(file, Field.INTERNAL_FIELD); + } + +} diff --git a/src/eu/engys/core/project/zero/fields/ScalarInternalField.java b/src/eu/engys/core/project/zero/fields/ScalarInternalField.java new file mode 100644 index 0000000..dcdd542 --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/ScalarInternalField.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class ScalarInternalField implements InternalField { + + private String buffer; + private double value; + + public ScalarInternalField(double value) { + this.value = value; + } + + @Override + public int getSize() { + return 1; + } + + @Override + public double[][] getValue() { + return new double[][] {{value}}; + } + + @Override + public void write(FileWriter writer) throws IOException { + writer.write(buffer); + } + + @Override + public void buffer(File file) { + buffer = Field.INTERNAL_FIELD + " uniform "+String.valueOf(value)+";"; + } +} diff --git a/src/eu/engys/core/project/zero/fields/VectorInternalField.java b/src/eu/engys/core/project/zero/fields/VectorInternalField.java new file mode 100644 index 0000000..7754523 --- /dev/null +++ b/src/eu/engys/core/project/zero/fields/VectorInternalField.java @@ -0,0 +1,67 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.fields; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class VectorInternalField implements InternalField { + + private CharSequence buffer; + private int size; + + public VectorInternalField(int size) { + this.size = size; + } + + @Override + public int getSize() { + return size; + } + + @Override + public double[][] getValue() { + return null; + } + + @Override + public void write(FileWriter writer) throws IOException { + int len = buffer.length(); + int BUF_LENGTH = 1024; + for (int start = 0, end = Math.min(BUF_LENGTH, len); end <= len + BUF_LENGTH; start = end, end += BUF_LENGTH) { + writer.write(buffer.subSequence(start, Math.min(end, len)).toString()); + } + writer.write(";\n"); + buffer = null; + } + + @Override + public void buffer(File file) { + buffer = FieldReader.extractString(file, Field.INTERNAL_FIELD); + } + +} diff --git a/src/eu/engys/core/project/zero/patches/BoundaryConditions.java b/src/eu/engys/core/project/zero/patches/BoundaryConditions.java new file mode 100644 index 0000000..13a909b --- /dev/null +++ b/src/eu/engys/core/project/zero/patches/BoundaryConditions.java @@ -0,0 +1,357 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.patches; + +import static eu.engys.core.project.zero.fields.Fields.ALPHA; +import static eu.engys.core.project.zero.fields.Fields.ALPHA_SGS; +import static eu.engys.core.project.zero.fields.Fields.ALPHA_T; +import static eu.engys.core.project.zero.fields.Fields.AOA; +import static eu.engys.core.project.zero.fields.Fields.CO2; +import static eu.engys.core.project.zero.fields.Fields.DT_AOA; +import static eu.engys.core.project.zero.fields.Fields.DT_CO2; +import static eu.engys.core.project.zero.fields.Fields.DT_SMOKE; +import static eu.engys.core.project.zero.fields.Fields.DT_W; +import static eu.engys.core.project.zero.fields.Fields.EPSILON; +import static eu.engys.core.project.zero.fields.Fields.ETA; +import static eu.engys.core.project.zero.fields.Fields.IDEFAULT; +import static eu.engys.core.project.zero.fields.Fields.K; +import static eu.engys.core.project.zero.fields.Fields.MUT; +import static eu.engys.core.project.zero.fields.Fields.MU_SGS; +import static eu.engys.core.project.zero.fields.Fields.NUT; +import static eu.engys.core.project.zero.fields.Fields.NU_SGS; +import static eu.engys.core.project.zero.fields.Fields.NU_TILDA; +import static eu.engys.core.project.zero.fields.Fields.OMEGA; +import static eu.engys.core.project.zero.fields.Fields.P; +import static eu.engys.core.project.zero.fields.Fields.P_RGH; +import static eu.engys.core.project.zero.fields.Fields.SMOKE; +import static eu.engys.core.project.zero.fields.Fields.T; +import static eu.engys.core.project.zero.fields.Fields.U; +import static eu.engys.core.project.zero.fields.Fields.W; + +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.zero.fields.Fields; + +public class BoundaryConditions { + + private static final Logger logger = LoggerFactory.getLogger(BoundaryConditions.class); + + public static final String[] PLACE_HOLDER_KEYS = {"value", "refValue", "inletValue", "gradient"}; + + public static void replaceNonUniformVector(Dictionary d) { + for (String ph : PLACE_HOLDER_KEYS) { + if(isNonUniform(d, ph)){ + d.add(ph, "uniform (0 0 0)"); + logger.warn("Nonuniform field {} replaced with {}", ph, d.lookup(ph)); + } + } + } + public static void replaceNonUniformScalar(Dictionary d) { + for (String ph : PLACE_HOLDER_KEYS) { + if(isNonUniform(d, ph)){ + d.add(ph, "uniform 0"); + logger.warn("Nonuniform field {} replaced with {}", ph, d.lookup(ph)); + } + } + } + + public static boolean isNonUniform(Dictionary d) { + for (String ph : PLACE_HOLDER_KEYS) { + if(isNonUniform(d, ph)){ + return true; + } + } + return false; + } + + public static boolean isPlaceHolder(Dictionary d) { + for (String ph : PLACE_HOLDER_KEYS) { + if(isPlaceHolder(d, ph)){ + return true; + } + } + return false; + } + + private static boolean isPlaceHolder(Dictionary d, String key) { + return (d.isField(key) && d.lookup(key).contains("nonuniform 0()")) || (d.isList2(key) && d.getList2(key).isEmpty()); + } + + private static boolean isNonUniform(Dictionary d, String key) { + return (d.isField(key) && d.lookup(key).contains("nonuniform List")) || (d.isList2(key) && d.getList2(key).isNonuniform()); + } + + private Dictionary momentum; + private Dictionary turbulence; + private Dictionary thermal; + private Dictionary humidity; + private Dictionary radiation; + private Dictionary passiveScalars; + private Dictionary phase; + private Dictionary roughness; + + public BoundaryConditions() { + setMomentum(new Dictionary("momentum")); + setTurbulence(new Dictionary("turbulence")); + setThermal(new Dictionary("thermal")); + setHumidity(new Dictionary("humidity")); + setRadiation(new Dictionary("radiation")); + setPassiveScalars(new Dictionary("passiveScalars")); + setPhase(new Dictionary("phase")); + setRoughness(new Dictionary("roughness")); + } + + public BoundaryConditions(BoundaryConditions defaults) { + this(); + if (defaults != null) { + getMomentum().merge(defaults.getMomentum()); + getTurbulence().merge(defaults.getTurbulence()); + getThermal().merge(defaults.getThermal()); + getHumidity().merge(defaults.getHumidity()); + getRadiation().merge(defaults.getRadiation()); + getPassiveScalars().merge(defaults.getPassiveScalars()); + getPhase().merge(defaults.getPhase()); + getRoughness().merge(defaults.getRoughness()); + } + } + + public Dictionary toDictionary() { + Dictionary dict = new Dictionary("boundaryConditions"); + dict.merge(getMomentum()); + dict.merge(getTurbulence()); + dict.merge(getThermal()); + dict.merge(getHumidity()); + dict.merge(getRadiation()); + dict.merge(getPassiveScalars()); + dict.merge(getPhase()); + dict.merge(getRoughness()); + return dict; + } + + public void fromDictionary(Dictionary dictionary) { + for (Dictionary d : dictionary.getDictionaries()) { + add(d.getName(), d); + } + } + + // public void loadFromField(String name, Dictionary patchInField) { + // Dictionary dict = new Dictionary(name); + // dict.merge(patchInField); + // add(name, patchInField); + // } + + public void add(String name, Dictionary original) { + Dictionary dictionary = new Dictionary(original); + dictionary.setName(name.equals(Fields.P_RGH) ? Fields.P : name); + + if (isMomentum(name)) { + getMomentum().add(dictionary); + } else if (isTurbulence(name)) { + getTurbulence().add(dictionary); + } else if (isThermal(name)) { + getThermal().add(dictionary); + } else if (isHumidity(name)) { + getHumidity().add(dictionary); + } else if (isRadiation(name)) { + getRadiation().add(dictionary); + } else if (isPassiveScalar(name)) { + getPassiveScalars().add(dictionary); + } else if (isPhase(name)) { + getPhase().add(dictionary); + } else if (isRoughness(name)) { + getRoughness().add(dictionary); + } else { + + } + } + + private boolean isRoughness(String name) { + String[] list = new String[] { NUT, MUT, NU_SGS, MU_SGS }; + return Arrays.asList(list).contains(name); + } + + public static boolean isPassiveScalar(String name) { + String[] list = new String[] { AOA, DT_AOA, CO2, DT_CO2, SMOKE, DT_SMOKE }; + return Arrays.asList(list).contains(name); + } + + public static boolean isPhase(String name) { + return name.equals(ETA) || (name.startsWith(ALPHA) && !name.equals(ALPHA_SGS) && !name.equals(ALPHA_T)); + } + + public static boolean isRadiation(String name) { + return name.equals(IDEFAULT); + } + + public static boolean isHumidity(String name) { + return name.equals(W) || name.equals(DT_W); + } + + public static boolean isThermal(String name) { + return name.equals(T); + } + + public static boolean isTurbulence(String name) { + String[] list = new String[] { K, OMEGA, EPSILON, NU_TILDA, /*NUT, NU_SGS, MUT, MU_SGS, */ALPHA_SGS, ALPHA_T }; + return Arrays.asList(list).contains(name); + } + + public static boolean isMomentum(String name) { + return name.equals(P) || name.equals(P_RGH) || name.startsWith(U); + } + + public Dictionary getMomentum() { + return momentum; + } + + public Dictionary setMomentum(Dictionary momentum) { + this.momentum = momentum; + return momentum; + } + + public Dictionary getTurbulence() { + return turbulence; + } + + public Dictionary setTurbulence(Dictionary turbulence) { + this.turbulence = turbulence; + return turbulence; + } + + public Dictionary getThermal() { + return thermal; + } + + public Dictionary setThermal(Dictionary thermal) { + this.thermal = thermal; + return thermal; + } + + public Dictionary getHumidity() { + return humidity; + } + + public Dictionary setHumidity(Dictionary humidity) { + this.humidity = humidity; + return humidity; + } + + public Dictionary getRadiation() { + return radiation; + } + + public Dictionary setRadiation(Dictionary radiation) { + this.radiation = radiation; + return radiation; + } + + public Dictionary getPassiveScalars() { + return passiveScalars; + } + + public Dictionary setPassiveScalars(Dictionary passiveScalars) { + this.passiveScalars = passiveScalars; + return passiveScalars; + } + + public Dictionary getPhase() { + return phase; + } + + public Dictionary setPhase(Dictionary phase) { + this.phase = phase; + return phase; + } + + public Dictionary getRoughness() { + return roughness; + } + + public void setRoughness(Dictionary roughness) { + this.roughness = roughness; + } + + public static BoundaryConditions toMomentumRoughness(Dictionary dict) { + BoundaryConditions bc = new BoundaryConditions(); + bc.setMomentum(dict); + bc.setRoughness(dict); + return bc; + } + + public static BoundaryConditions toMomentumThermal(Dictionary dict) { + BoundaryConditions bc = new BoundaryConditions(); + bc.setMomentum(dict); + bc.setThermal(dict); + return bc; + } + + public static BoundaryConditions toTurbulence(Dictionary turbulence) { + BoundaryConditions bc = new BoundaryConditions(); + bc.setTurbulence(turbulence); + return bc; + } + + public static BoundaryConditions toThermal(Dictionary thermal) { + BoundaryConditions bc = new BoundaryConditions(); + bc.setThermal(thermal); + return bc; + } + + public static BoundaryConditions toRadiation(Dictionary radiation) { + BoundaryConditions bc = new BoundaryConditions(); + bc.setRadiation(radiation); + return bc; + } + + public static BoundaryConditions toPhase(Dictionary phase) { + BoundaryConditions bc = new BoundaryConditions(); + bc.setPhase(phase); + return bc; + } + + public static BoundaryConditions toPassiveScalars(Dictionary passiveScalars) { + BoundaryConditions bc = new BoundaryConditions(); + bc.setPassiveScalars(passiveScalars); + return bc; + } + + public static BoundaryConditions toHumidity(Dictionary humidity) { + BoundaryConditions bc = new BoundaryConditions(); + bc.setHumidity(humidity); + return bc; + } + + public static BoundaryConditions toMomentum(Dictionary momentum) { + BoundaryConditions bc = new BoundaryConditions(); + bc.setMomentum(momentum); + return bc; + } +} diff --git a/src/eu/engys/core/project/zero/patches/BoundaryConditionsDefaults.java b/src/eu/engys/core/project/zero/patches/BoundaryConditionsDefaults.java new file mode 100644 index 0000000..44975e5 --- /dev/null +++ b/src/eu/engys/core/project/zero/patches/BoundaryConditionsDefaults.java @@ -0,0 +1,211 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.patches; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.fields.FieldsDefaults; + +public class BoundaryConditionsDefaults { + + private static final Logger logger = LoggerFactory.getLogger(BoundaryConditionsDefaults.class); + + private static Map defaultBoundaryConditions = new HashMap(); + + public static void updateBoundaryConditionsDefaultsByFields(Model model) { + defaultBoundaryConditions.clear(); + + Fields fields = model.getFields(); + Map typesMap = BoundaryType.getRegisteredBoundaryTypes(); + + for (String type : typesMap.keySet()) { + BoundaryConditions bc = extractDefaultBoundaryConditionsForType(fields.values(), type); + defaultBoundaryConditions.put(type, bc); + } + } + + private static BoundaryConditions extractDefaultBoundaryConditionsForType(Collection fields, String patchType) { + BoundaryConditions bc = new BoundaryConditions(); + for (Field field : fields) { + if (field.getDefinition() != null && field.getDefinition().subDict("boundaryConditions") != null) { + Dictionary regionDefaults = field.getDefinition().subDict("boundaryConditions").subDict("regionDefaults"); + String internalType = BoundaryType.isOpening(patchType) ? BoundaryType.PATCH_KEY : patchType; + if (regionDefaults.found(internalType)) { + Dictionary regionDefaultsForType = regionDefaults.subDict(internalType); + bc.add(field.getName(), regionDefaultsForType); + } else { + Dictionary fieldPatch = new Dictionary(field.getName()); + fieldPatch.add(Dictionary.TYPE, patchType); + bc.add(field.getName(), fieldPatch); + } + } else { + logger.error("No definition for field " + field.getName() + ": " + field.getDefinition()); + } + } + return bc; + } + + public static BoundaryConditions get(String key) { + return defaultBoundaryConditions.get(key); + } + + public static Dictionary getPressureFor(BoundaryType type, Dictionary def) { + BoundaryConditions boundaryConditions = BoundaryConditionsDefaults.get(type.getKey()); + if (boundaryConditions != null) { + Dictionary momentum = boundaryConditions.getMomentum(); + if (momentum != null) { + if (momentum.isDictionary(Fields.P)) { + return new Dictionary(momentum.subDict(Fields.P)); + } + } + } + return new Dictionary(def); + } + + + public static Dictionary getRoughness() { + BoundaryConditions boundaryConditions = BoundaryConditionsDefaults.get(BoundaryType.WALL_KEY); + if (boundaryConditions != null) { + Dictionary roughness = boundaryConditions.getRoughness(); + if (roughness != null) { + return new Dictionary(roughness); + } + } + return null; + } + + public static void loadBoundaryConditionsFromFields(Patches patches, Fields fields) { + patches.clearBoundaryConditions(); + + fieldsToBoundaryConditions(patches, fields); + + new MergeBoundaryConditions(patches, fields).execute(); + } + + public static void fieldsToBoundaryConditions(Patches patches, Fields fields) { + Fields[] parallelFields = fields.getParallelFields(); + Patches[] parallelPatches = patches.getParallelPatches(); + + if (parallelFields != null && parallelPatches != null) { + for (int i = 0; i < parallelFields.length; i++) { + Fields map = parallelFields[i]; + Patches patchesOfProcessor = parallelPatches[i]; + for (Field field : map.values()) { + fieldToBoundaryConditions(field, patchesOfProcessor); + } + } + } + } + + public static void fieldToBoundaryConditions(Field field, Patches patches) { + Map patchesMap = patches.toMap(); + + Dictionary boundaryField = field.getBoundaryField(); + + for (Dictionary patchInField : boundaryField.getDictionaries()) { + String patchName = patchInField.getName(); + Patch patch = patchesMap.get(patchName); + + if (patch != null) { + patch.getBoundaryConditions().add(field.getName(), patchInField); + } + } + } + + public static void saveBoundaryConditionsToFields(Patches patches, Fields fields) { + new SplitBoundaryConditions(patches, fields).execute(); + + boundaryConditionsToFields(patches, fields); + } + + public static void boundaryConditionsToFields(Patches patches, Fields fieldsMap) { + + /* questa roba serve veramente ? */ + for (Field field : fieldsMap.values()) { + boundaryConditionsToField(patches, field); + } + + Fields[] parallelFields = fieldsMap.getParallelFields(); + if (parallelFields != null) { + for (int i = 0; i < parallelFields.length; i++) { + Fields processorFields = parallelFields[i]; + for (Field field : processorFields.values()) { + boundaryConditionsToField(patches.getPatchesOfProcessor(i), field); + } + } + } + } + + public static void boundaryConditionsToField(Patches patches, Field field) { + Dictionary boundaryField = field.getBoundaryField(); + String fieldName = field.getName(); + for (Patch patch : patches) { + String patchName = patch.getName(); + if (patch.getBoundaryConditions() != null) { + Dictionary boundaryConditions = patch.getBoundaryConditions().toDictionary(); + if (boundaryConditions.found(fieldName)) { + Dictionary bcDictionary = boundaryConditions.subDict(fieldName); + if (boundaryField.found(patchName)) { + Dictionary fieldPatch = boundaryField.subDict(patchName); + fieldPatch.clear(); + fieldPatch.merge(bcDictionary); + } else { + Dictionary fieldPatch = new Dictionary(patchName); + boundaryField.add(fieldPatch); + fieldPatch.merge(bcDictionary); + } + + } else if (fieldName.equals(Fields.P_RGH) && boundaryConditions.found(Fields.P)) { + Dictionary bcDictionary = boundaryConditions.subDict(Fields.P); + if (boundaryField.found(patchName)) { + Dictionary fieldPatch = boundaryField.subDict(patchName); + fieldPatch.clear(); + fieldPatch.merge(bcDictionary); + } else { + Dictionary fieldPatch = new Dictionary(patchName); + boundaryField.add(fieldPatch); + fieldPatch.merge(bcDictionary); + } + + } else { + FieldsDefaults.setAsDefault(field, patch); + } + } else { + FieldsDefaults.setAsDefault(field, patch); + } + } + } +} diff --git a/src/eu/engys/core/project/zero/patches/BoundaryType.java b/src/eu/engys/core/project/zero/patches/BoundaryType.java new file mode 100644 index 0000000..f60f4f1 --- /dev/null +++ b/src/eu/engys/core/project/zero/patches/BoundaryType.java @@ -0,0 +1,225 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.patches; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.swing.Icon; +import javax.swing.ImageIcon; + +public class BoundaryType { + + public static final String MAPPED_PATCH_KEY = "mappedPatch"; + public static final String MAPPED_WALL_KEY = "mappedWall"; + public static final String CYCLIC_KEY = "cyclic"; + public static final String CYCLIC_AMI_KEY = "cyclicAMI"; + public static final String EMPTY_KEY = "empty"; + public static final String INLET_KEY = "inlet"; + public static final String OPENING_KEY = "opening"; + public static final String OUTLET_KEY = "outlet"; + public static final String PATCH_KEY = "patch"; + public static final String PROCESSOR_KEY = "processor"; + public static final String PROCESSOR_CYCLIC_KEY = "processorCyclic"; + public static final String SYMMETRY_KEY = "symmetry"; + public static final String SYMMETRY_PLANE_KEY = "symmetryPlane"; + public static final String WALL_KEY = "wall"; + public static final String WEDGE_KEY = "wedge"; + public static final String FREE_SURFACE_KEY = "freeSurface"; + + public static final String CYCLIC_LABEL = "Cyclic"; + public static final String CYCLIC_AMI_LABEL = "Cyclic AMI"; + public static final String EMPTY_LABEL = "Empty"; + public static final String INLET_LABEL = "Inlet"; + public static final String OPENING_LABEL = "Opening"; + public static final String OUTLET_LABEL = "Outlet"; + public static final String PATCH_LABEL = "Patch"; + public static final String PROCESSOR_LABEL = "Processor"; + public static final String PROCESSOR_CYCLIC_LABEL = "Processor Cyclic"; + public static final String SYMMETRY_LABEL = "Symmetry"; + public static final String SYMMETRY_PLANE_LABEL = "Symmetry Plane"; + public static final String WALL_LABEL = "Wall"; + public static final String WEDGE_LABEL = "Wedge"; + public static final String FREE_SURFACE_LABEL = "Free Surface"; + + public static final BoundaryType INLET = new BoundaryType(INLET_KEY, INLET_LABEL, true); + public static final BoundaryType OUTLET = new BoundaryType(OUTLET_KEY, OUTLET_LABEL, true); + public static final BoundaryType OPENING = new BoundaryType(OPENING_KEY, OPENING_LABEL, true); + public static final BoundaryType WALL = new BoundaryType(WALL_KEY, WALL_LABEL, true); + public static final BoundaryType PATCH = new BoundaryType(PATCH_KEY, PATCH_LABEL, true); + public static final BoundaryType SYMMETRY = new BoundaryType(SYMMETRY_KEY, SYMMETRY_LABEL, false); + public static final BoundaryType SYMMETRY_PLANE = new BoundaryType(SYMMETRY_PLANE_KEY, SYMMETRY_PLANE_LABEL, false); + public static final BoundaryType CYCLIC = new BoundaryType(CYCLIC_KEY, CYCLIC_LABEL, true); + public static final BoundaryType CYCLIC_AMI = new BoundaryType(CYCLIC_AMI_KEY, CYCLIC_AMI_LABEL, true); + public static final BoundaryType EMPTY = new BoundaryType(EMPTY_KEY, EMPTY_LABEL, false); + public static final BoundaryType WEDGE = new BoundaryType(WEDGE_KEY, WEDGE_LABEL, false); + public static final BoundaryType PROCESSOR = new BoundaryType(PROCESSOR_KEY, PROCESSOR_LABEL, false); + public static final BoundaryType PROCESSOR_CYCLIC = new BoundaryType(PROCESSOR_CYCLIC_KEY, PROCESSOR_CYCLIC_LABEL, false); + public static final BoundaryType FREE_SURFACE = new BoundaryType(FREE_SURFACE_KEY, FREE_SURFACE_LABEL, true); + + private static Map registeredTypes = new LinkedHashMap<>(); + private static Map registeredTypesIcon = new LinkedHashMap<>(); + + public static void registerBoundaryType(BoundaryType type) { + registeredTypes.put(type.getKey(), type); + registeredTypesIcon.put(type.getKey(), getIcon("eu/engys/resources/images/" + type.getKey() + "16.png")); + } + + public static void unregisterBoundaryType(BoundaryType type) { + registeredTypes.remove(type.getKey()); + registeredTypesIcon.remove(type.getKey()); + } + + private static Icon getIcon(String string) { + try { + return new ImageIcon(BoundaryType.class.getClassLoader().getResource(string)); + } catch (Exception e) { + return null; + } + } + + public static Map getRegisteredBoundaryTypes() { + return Collections.unmodifiableMap(registeredTypes); + } + + public static boolean isPatch(String key) { + return key.equals(PATCH_KEY); + } + + public static boolean isWall(String key) { + return key.equals(WALL_KEY); + } + + public static boolean isMappedWall(String key) { + return key.equals(MAPPED_WALL_KEY); + } + + public static boolean isMappedPatch(String key) { + return key.equals(MAPPED_PATCH_KEY); + } + + public static boolean isOpening(String key) { + return key.equals(OPENING_KEY); + } + + public static boolean isPatchPhysicalType(String key) { + return key.equals(INLET_KEY) || key.equals(OUTLET_KEY) || key.equals(OPENING_KEY); + } + + public static boolean isWallPhysicalType(String key) { + return key.equals(FREE_SURFACE_KEY); + } + + public static boolean isCoupledSymmetryPlaneType(String patchType) { + return patchType.equals(SYMMETRY_PLANE_KEY); + } + + public static boolean isProcessor(String key) { + return key.equals(PROCESSOR_KEY); + } + + public static boolean isProcessorCyclic(String key) { + return key.equals(PROCESSOR_CYCLIC_KEY); + } + + public static boolean isCyclicAMI(String key) { + return key.equals(CYCLIC_AMI_KEY); + } + + public static boolean isInlet(Patch patch) { + return patch.getPhisicalType().getKey().equals(INLET_KEY); + } + + public static boolean isKnown(String key) { + return registeredTypes.containsKey(key); + } + + public static BoundaryType getDefaultType() { + return WALL; + } + + public static String getDefaultKey() { + return WALL_KEY; + } + + public static BoundaryType getType(String key) { + return registeredTypes.get(key); + } + + private String label; + private String key; + private boolean hasBoundaryConditions; + + private BoundaryType(String key, String label, boolean hasBoundaryConditions) { + this.key = key; + this.label = label; + this.hasBoundaryConditions = hasBoundaryConditions; + } + + public String getLabel() { + return label; + } + + public String getKey() { + return key; + } + + public boolean hasBoundaryConditions() { + return hasBoundaryConditions; + } + + public Icon getIcon() { + return registeredTypesIcon.get(key); + } + + @Override + public String toString() { + return getKey(); + } + + @Override + public boolean equals(Object obj) { + return toString().equals(obj.toString()); + } + + public boolean isProcessor() { + return this == PROCESSOR; + } + + public boolean isProcessorCyclic() { + return this == PROCESSOR_CYCLIC; + } + + public boolean isCyclicAMI() { + return this == CYCLIC_AMI; + } + + public boolean isPatch() { + return this == PATCH; + } +}; diff --git a/src/eu/engys/core/project/zero/patches/MergeBoundaryConditions.java b/src/eu/engys/core/project/zero/patches/MergeBoundaryConditions.java new file mode 100644 index 0000000..69580a8 --- /dev/null +++ b/src/eu/engys/core/project/zero/patches/MergeBoundaryConditions.java @@ -0,0 +1,317 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.patches; + +import static eu.engys.core.project.zero.fields.Fields.ALPHA_SGS; +import static eu.engys.core.project.zero.fields.Fields.ALPHA_T; +import static eu.engys.core.project.zero.fields.Fields.AOA; +import static eu.engys.core.project.zero.fields.Fields.CO2; +import static eu.engys.core.project.zero.fields.Fields.DT_AOA; +import static eu.engys.core.project.zero.fields.Fields.DT_CO2; +import static eu.engys.core.project.zero.fields.Fields.DT_SMOKE; +import static eu.engys.core.project.zero.fields.Fields.DT_W; +import static eu.engys.core.project.zero.fields.Fields.EPSILON; +import static eu.engys.core.project.zero.fields.Fields.ETA; +import static eu.engys.core.project.zero.fields.Fields.IDEFAULT; +import static eu.engys.core.project.zero.fields.Fields.K; +import static eu.engys.core.project.zero.fields.Fields.MUT; +import static eu.engys.core.project.zero.fields.Fields.MU_SGS; +import static eu.engys.core.project.zero.fields.Fields.NUT; +import static eu.engys.core.project.zero.fields.Fields.NU_SGS; +import static eu.engys.core.project.zero.fields.Fields.NU_TILDA; +import static eu.engys.core.project.zero.fields.Fields.OMEGA; +import static eu.engys.core.project.zero.fields.Fields.P; +import static eu.engys.core.project.zero.fields.Fields.SMOKE; +import static eu.engys.core.project.zero.fields.Fields.T; +import static eu.engys.core.project.zero.fields.Fields.U; +import static eu.engys.core.project.zero.fields.Fields.W; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; + +public class MergeBoundaryConditions { + + private static final Logger logger = LoggerFactory.getLogger(MergeBoundaryConditions.class); + + private Patches patches; + private Fields fields; + + public MergeBoundaryConditions(Patches patches, Fields fields) { + this.patches = patches; + this.fields = fields; + } + + public void execute() { + for (Patch patch : patches) { + String name = patch.getName(); + logger.info("Merging boundary condition for patch {}", name); + // System.out.println("*** patch "+name+" ***"); + Patches[] parallelPatches = patches.getParallelPatches(); + if (parallelPatches != null) { + boolean emptyForAllProcessors = true; + for (int i = 0; i < parallelPatches.length; i++) { + Map patchesMap = parallelPatches[i].toMap(); + // System.out.println("\tprocessor "+i); + if (patchesMap.containsKey(name)) { + Patch parallelPatch = patchesMap.get(name); + if (parallelPatch.getBoundaryConditions() != null) { + // System.out.println("MergeBoundaryConditions.execute() merge "+name); + merge(parallelPatch.getBoundaryConditions(), patch.getBoundaryConditions()); + } + emptyForAllProcessors = emptyForAllProcessors && parallelPatch.isEmpty(); +// System.out.println("*** AFTER MERGE ***"+parallelPatch.getBoundaryConditions().toDictionary()); +// System.out.println("*** AFTER MERGE ***"+patch.getBoundaryConditions().toDictionary()); + } + } + patch.setEmpty(patch.isEmpty() || emptyForAllProcessors); + } + } + } + + private void merge(BoundaryConditions source, BoundaryConditions target) { + if (!source.getMomentum().isEmpty()) { + mergeField(source.getMomentum(), target.getMomentum(), U); + for (Field U : fields.getMultiphaseUFields()) { + mergeField(source.getMomentum(), target.getMomentum(), U.getName()); + } + mergeField(source.getMomentum(), target.getMomentum(), P); + } + if (!source.getTurbulence().isEmpty()) { + mergeField(source.getTurbulence(), target.getTurbulence(), K); + mergeField(source.getTurbulence(), target.getTurbulence(), OMEGA); + mergeField(source.getTurbulence(), target.getTurbulence(), EPSILON); + mergeField(source.getTurbulence(), target.getTurbulence(), NU_TILDA); + mergeField(source.getTurbulence(), target.getTurbulence(), NUT); + mergeField(source.getTurbulence(), target.getTurbulence(), NU_SGS); + mergeField(source.getTurbulence(), target.getTurbulence(), MUT); + mergeField(source.getTurbulence(), target.getTurbulence(), MU_SGS); + mergeField(source.getTurbulence(), target.getTurbulence(), ALPHA_T); + mergeField(source.getTurbulence(), target.getTurbulence(), ALPHA_SGS); + } + if (!source.getRoughness().isEmpty()) { + mergeField(source.getRoughness(), target.getRoughness(), NUT); + mergeField(source.getRoughness(), target.getRoughness(), NU_SGS); + mergeField(source.getRoughness(), target.getRoughness(), MUT); + mergeField(source.getRoughness(), target.getRoughness(), MU_SGS); + } + if (!source.getThermal().isEmpty()) { + mergeField(source.getThermal(), target.getThermal(), T); + } + if (!source.getHumidity().isEmpty()) { + mergeField(source.getHumidity(), target.getHumidity(), W); + mergeField(source.getHumidity(), target.getHumidity(), DT_W); + } + if (!source.getRadiation().isEmpty()) { + mergeField(source.getRadiation(), target.getRadiation(), IDEFAULT); + } + if (!source.getPassiveScalars().isEmpty()) { + mergeField(source.getPassiveScalars(), target.getPassiveScalars(), AOA); + mergeField(source.getPassiveScalars(), target.getPassiveScalars(), DT_AOA); + mergeField(source.getPassiveScalars(), target.getPassiveScalars(), CO2); + mergeField(source.getPassiveScalars(), target.getPassiveScalars(), DT_CO2); + mergeField(source.getPassiveScalars(), target.getPassiveScalars(), SMOKE); + mergeField(source.getPassiveScalars(), target.getPassiveScalars(), DT_SMOKE); + } + if (!source.getPhase().isEmpty()) { + mergeField(source.getPhase(), target.getPhase(), ETA); + for (Field af : fields.getAlphaFields()) { + mergeField(source.getPhase(), target.getPhase(), af.getName()); + } + } + } + + private void mergeField(Dictionary source, Dictionary target, String field) { + if (source.isDictionary(field) /* && target.isDictionary(field) */) { + Dictionary fieldSource = source.subDict(field); + // Dictionary fieldTarget = target.subDict(field); + + if (BoundaryConditions.isPlaceHolder(fieldSource)) { + // System.out.println("\t\t"+field+" PH"); + /* DO NOTHING */ + } else { + // System.out.println("\t\t"+field+" UN"); + target.add(new Dictionary(fieldSource)); + } + } else if (source.isDictionary(field)) { + // System.err.println("ERROR: missing TARGET "+field+" dictionary"); + } else { + // System.err.println("ERROR: missing SOURCE "+field+" dictionary"); + // System.out.println(""+source+target); + } + } + + public void mergeExcludingNonUniform(BoundaryConditions source, BoundaryConditions target) { + if (!source.getMomentum().isEmpty()) { + mergeExcludingNonUniform(source.getMomentum(), target.getMomentum(), U); + for (Field U : fields.getMultiphaseUFields()) { + mergeExcludingNonUniform(source.getMomentum(), target.getMomentum(), U.getName()); + } + mergeExcludingNonUniform(source.getMomentum(), target.getMomentum(), P); + } + if (!source.getTurbulence().isEmpty()) { + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), K); + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), OMEGA); + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), EPSILON); + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), NU_TILDA); + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), NUT); + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), NU_SGS); + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), MUT); + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), MU_SGS); + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), ALPHA_T); + mergeExcludingNonUniform(source.getTurbulence(), target.getTurbulence(), ALPHA_SGS); + } + if (!source.getRoughness().isEmpty()) { + mergeExcludingNonUniform(source.getRoughness(), target.getRoughness(), NUT); + mergeExcludingNonUniform(source.getRoughness(), target.getRoughness(), NU_SGS); + mergeExcludingNonUniform(source.getRoughness(), target.getRoughness(), MUT); + mergeExcludingNonUniform(source.getRoughness(), target.getRoughness(), MU_SGS); + } + if (!source.getThermal().isEmpty()) { + mergeExcludingNonUniform(source.getThermal(), target.getThermal(), T); + } + if (!source.getHumidity().isEmpty()) { + mergeExcludingNonUniform(source.getHumidity(), target.getHumidity(), W); + mergeExcludingNonUniform(source.getHumidity(), target.getHumidity(), DT_W); + } + if (!source.getRadiation().isEmpty()) { + mergeExcludingNonUniform(source.getRadiation(), target.getRadiation(), IDEFAULT); + } + if (!source.getPassiveScalars().isEmpty()) { + mergeExcludingNonUniform(source.getPassiveScalars(), target.getPassiveScalars(), AOA); + mergeExcludingNonUniform(source.getPassiveScalars(), target.getPassiveScalars(), DT_AOA); + mergeExcludingNonUniform(source.getPassiveScalars(), target.getPassiveScalars(), CO2); + mergeExcludingNonUniform(source.getPassiveScalars(), target.getPassiveScalars(), DT_CO2); + mergeExcludingNonUniform(source.getPassiveScalars(), target.getPassiveScalars(), SMOKE); + mergeExcludingNonUniform(source.getPassiveScalars(), target.getPassiveScalars(), DT_SMOKE); + } + if (!source.getPhase().isEmpty()) { + mergeExcludingNonUniform(source.getPhase(), target.getPhase(), ETA); + for (Field af : fields.getAlphaFields()) { + mergeExcludingNonUniform(source.getPhase(), target.getPhase(), af.getName()); + } + } + } + + private void mergeExcludingNonUniform(Dictionary source, Dictionary target, String field) { + if (source.isDictionary(field) && target.isDictionary(field)) { + Dictionary fieldSource = source.subDict(field); + Dictionary fieldTarget = target.subDict(field); + if (haveSameType(fieldSource, fieldTarget)) { + if (BoundaryConditions.isNonUniform(fieldTarget)) { + fieldTarget.merge(fieldSource); + } else { + /* DO NOTHING */ + } + } else { + /* DO NOTHING */ + } + } else if (source.isDictionary(field) && !target.isDictionary(field)) { + // System.err.println("ERROR: missing target "+field+" dictionary"); + } else if (!source.isDictionary(field) && target.isDictionary(field)) { + // System.err.println("ERROR: missing source "+field+" dictionary"); + } else { + // System.err.println("ERROR: missing both "+field+" dictionary"); + } + } + + private boolean haveSameType(Dictionary d1, Dictionary d2) { + return d1.isField(Dictionary.TYPE) && d2.isField(Dictionary.TYPE) && d1.lookup(Dictionary.TYPE).equals(d2.lookup(Dictionary.TYPE)); + } + + + public void excludeNonUniform(BoundaryConditions target) { + if (!target.getMomentum().isEmpty()) { + excludeNonUniform(target.getMomentum(), U); + for (Field U : fields.getMultiphaseUFields()) { + excludeNonUniform(target.getMomentum(), U.getName()); + } + excludeNonUniform(target.getMomentum(), P); + } + if (!target.getTurbulence().isEmpty()) { + excludeNonUniform(target.getTurbulence(), K); + excludeNonUniform(target.getTurbulence(), OMEGA); + excludeNonUniform(target.getTurbulence(), EPSILON); + excludeNonUniform(target.getTurbulence(), NU_TILDA); + excludeNonUniform(target.getTurbulence(), NUT); + excludeNonUniform(target.getTurbulence(), NU_SGS); + excludeNonUniform(target.getTurbulence(), MUT); + excludeNonUniform(target.getTurbulence(), MU_SGS); + excludeNonUniform(target.getTurbulence(), ALPHA_T); + excludeNonUniform(target.getTurbulence(), ALPHA_SGS); + } + if (!target.getRoughness().isEmpty()) { + excludeNonUniform(target.getRoughness(), NUT); + excludeNonUniform(target.getRoughness(), NU_SGS); + excludeNonUniform(target.getRoughness(), MUT); + excludeNonUniform(target.getRoughness(), MU_SGS); + } + if (!target.getThermal().isEmpty()) { + excludeNonUniform(target.getThermal(), T); + } + if (!target.getHumidity().isEmpty()) { + excludeNonUniform(target.getHumidity(), W); + excludeNonUniform(target.getHumidity(), DT_W); + } + if (!target.getRadiation().isEmpty()) { + excludeNonUniform(target.getRadiation(), IDEFAULT); + } + if (!target.getPassiveScalars().isEmpty()) { + excludeNonUniform(target.getPassiveScalars(), AOA); + excludeNonUniform(target.getPassiveScalars(), DT_AOA); + excludeNonUniform(target.getPassiveScalars(), CO2); + excludeNonUniform(target.getPassiveScalars(), DT_CO2); + excludeNonUniform(target.getPassiveScalars(), SMOKE); + excludeNonUniform(target.getPassiveScalars(), DT_SMOKE); + } + if (!target.getPhase().isEmpty()) { + excludeNonUniform(target.getPhase(), ETA); + for (Field af : fields.getAlphaFields()) { + excludeNonUniform(target.getPhase(), af.getName()); + } + } + } + + private void excludeNonUniform(Dictionary target, String field) { + if (target.isDictionary(field) && target.isDictionary(field)) { + Dictionary fieldTarget = target.subDict(field); + if (BoundaryConditions.isNonUniform(fieldTarget)) { + if (field.equals(Fields.U)) { + BoundaryConditions.replaceNonUniformVector(fieldTarget); + } else { + BoundaryConditions.replaceNonUniformScalar(fieldTarget); + } + } + } + } + +} diff --git a/src/eu/engys/core/project/zero/patches/Patch.java b/src/eu/engys/core/project/zero/patches/Patch.java new file mode 100644 index 0000000..4061310 --- /dev/null +++ b/src/eu/engys/core/project/zero/patches/Patch.java @@ -0,0 +1,154 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.patches; + +import vtk.vtkPolyData; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.util.ui.checkboxtree.LoadableItem; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class Patch implements VisibleItem, LoadableItem { + + public static final int NONE = -1; + private final String originalName; + private String name; + private BoundaryType phisicalType; + private String type; + private boolean visible; + private boolean loaded; + private Dictionary dictionary; + private BoundaryConditions boundaryConditions; + private boolean empty; + private vtkPolyData dataSet; + + public Patch(String originalName) { + this.originalName = originalName; + } + + public Patch(Patch patch) { + this.originalName = patch.originalName; + this.name = patch.name; + this.phisicalType = patch.phisicalType; + this.type = patch.type; + this.visible = patch.visible; + this.loaded = patch.loaded; + this.boundaryConditions = new BoundaryConditions(patch.boundaryConditions); + this.dictionary = new Dictionary(patch.getDictionary()); + } + + public String getOriginalName() { + return originalName; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public BoundaryType getPhisicalType() { + return phisicalType; + } + public void setPhisicalType(BoundaryType type) { + this.phisicalType = type; + } + + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + + @Override + public boolean isVisible() { + return visible; + } + + @Override + public void setVisible(boolean selected) { + this.visible = selected; + } + + @Override + public boolean isLoaded() { + return loaded; + } + + @Override + public void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + public void setBoundaryConditions(BoundaryConditions boundaryConditions) { + this.boundaryConditions = boundaryConditions; + } + + public BoundaryConditions getBoundaryConditions() { + return boundaryConditions; + } + + @Override + public String toString() { + return name + " [ type: " + phisicalType.getLabel() + ", visible: " + visible + ", loaded: " + loaded + "]"; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Patch) { + return getName().equals(((Patch) obj).getName()); + } else { + return super.equals(obj); + } + } + + public void setEmpty(boolean b) { + this.empty = b; + } + + public boolean isEmpty() { + return empty; + } + + public void setDictionary(Dictionary patch) { + this.dictionary = patch; + } + + public Dictionary getDictionary() { + return dictionary; + } + + public vtkPolyData getDataSet() { + return dataSet; + } + + public void setDataSet(vtkPolyData dataSet) { + this.dataSet = dataSet; + } + +} diff --git a/src/eu/engys/core/project/zero/patches/Patches.java b/src/eu/engys/core/project/zero/patches/Patches.java new file mode 100644 index 0000000..f41a571 --- /dev/null +++ b/src/eu/engys/core/project/zero/patches/Patches.java @@ -0,0 +1,163 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.patches; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import eu.engys.util.PrefUtil; + +public class Patches extends ArrayList { + + private Patches[] parallelPatches; + + public Patches() { + super(); + } + + public Map toMap() { + Map patchesMap = new HashMap(); + for (Patch patch : this) { + patchesMap.put(patch.getName(), patch); + } + return Collections.unmodifiableMap(patchesMap); + } + + public void print() { + for (Patch patch : this) { + System.err.println(" >>>>>>>>>> " + patch.getName()+", hash: "+patch.hashCode()); + System.err.println(patch.getBoundaryConditions().toDictionary()); + } + } + + public Patches filterProcBoundary() { + Patches nonProcPatches = new Patches(); + for (Patch p : this) { + if (!p.getPhisicalType().isProcessor() && !p.getPhisicalType().isProcessorCyclic()) { + nonProcPatches.add(p); + } + } + return nonProcPatches; + } + + public Patches patchesToDisplay() { + Patches patches = new Patches(); + for (Patch patch : this) { + Boolean hideEmptyPatches = PrefUtil.getBoolean(PrefUtil.HIDE_EMPTY_PATCHES); + if ( (patch.isEmpty() && hideEmptyPatches) || patch.getPhisicalType().isProcessor() || patch.getPhisicalType().isProcessorCyclic()) { + continue; + } + patches.add(patch); + } + return patches; + } + + public void printBoundaryConditions(int procIndex, int patchIndex) { + if (procIndex < 0) { + for (int i = 0; i < parallelPatches.length; i++) { + Patch patch = parallelPatches[i].get(patchIndex); + System.out.println("PATCHES PRINT BOUNDARY CONDITIONS processor " + i + ", patch: " + patch.getName() + " " + patch.getBoundaryConditions().toDictionary()); + } + } else { + Patch patch = parallelPatches[procIndex].get(patchIndex); + System.out.println("PATCHES PRINT BOUNDARY CONDITIONS processor " + procIndex + ", patch: " + patch.getName() + " " + patch.getBoundaryConditions().toDictionary()); + } + } + + public void setParallelPatches(Patches[] parallelPatches) { + this.parallelPatches = parallelPatches; + } + + public Patches[] getParallelPatches() { + return parallelPatches; + } + + public Patches getPatchesOfProcessor(int processor) { + return parallelPatches[processor]; + } + + public void clearBoundaryConditions() { + for (Patch patch : this) { + patch.setBoundaryConditions(new BoundaryConditions()); + } + if (parallelPatches != null) { + for (Patches patches : parallelPatches) { + patches.clearBoundaryConditions(); + } + } + } + + public boolean addPatches(Collection c) { + if (parallelPatches != null) { + for (Patches patches : parallelPatches) { + for (Patch patch : c) { + patches.add(new Patch(patch)); + } + } + } + return super.addAll(c); + } + + public void newParallelPatches(int processors) { + parallelPatches = new Patches[processors]; + for (int i = 0; i < parallelPatches.length; i++) { + parallelPatches[i] = new Patches(); + } + } + + public List patchesNames() { + List names = new ArrayList<>(); + for (Patch patch : this) { + names.add(patch.getName()); + } + return names; + } + + public List patchesNames(BoundaryType type) { + List names = new ArrayList<>(); + for (Patch patch : this) { + if (patch.getPhisicalType().equals(type)) { + names.add(patch.getName()); + } + } + return names; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + for (Patch patch : this) { + sb.append(patch.getName() + " - "); + } + return sb.toString(); + } + +} diff --git a/src/eu/engys/core/project/zero/patches/PatchesReader.java b/src/eu/engys/core/project/zero/patches/PatchesReader.java new file mode 100644 index 0000000..63ac7a8 --- /dev/null +++ b/src/eu/engys/core/project/zero/patches/PatchesReader.java @@ -0,0 +1,183 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.patches; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.util.IOUtils; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; + +public class PatchesReader { + + private static final Logger logger = LoggerFactory.getLogger(Patches.class); + private ProgressMonitor monitor; + + public PatchesReader(ProgressMonitor monitor) { + this.monitor = monitor; + } + + public Patches read(File... boundaryFiles) { + Patches patches = new Patches(); + + final Patches[] parallelPatches = new Patches[boundaryFiles.length]; + + Runnable[] runnables = new Runnable[boundaryFiles.length]; + for (int i = 0; i < boundaryFiles.length; i++) { + final File boundary = boundaryFiles[i]; + final int index = i; + runnables[i] = new Runnable() { + @Override + public void run() { + Patches readPatches = readBoundary(boundary); + parallelPatches[index] = readPatches; + } + }; + } + ExecUtil.execParallelAndWait(runnables); + + for (Patches readPatches : parallelPatches) { + merge(patches, readPatches); + } + patches.setParallelPatches(parallelPatches); + + return patches; + } + + private void merge(Patches patches, Patches readPatches) { + for (Patch patch : readPatches) { + if (!patches.contains(patch)) { + patches.add(new Patch(patch)); + } + } + } + + Patches readBoundary(File boundary) { + logger.info("READ: Patches {}", boundary.getAbsolutePath()); + Patches patches = new Patches(); + if (boundary.exists()) { + try { + String boundaryString = IOUtils.readStringFromFile(boundary); + boundaryString = boundaryString.replaceAll("/\\*(?:.|[\\n\\r])*?\\*/", ""); + + Pattern pattern = Pattern.compile("(\\d*)\\s*\\(([^#]*)\\)"); + Matcher matcher = pattern.matcher(boundaryString); + if (matcher.find()) { + if (matcher.groupCount() == 2) { + String nPatch = matcher.group(1); + String patchesString = matcher.group(2); + Dictionary dict = DictionaryUtils.readDictionary(patchesString); + List notKnownPatches = new ArrayList(); + for (Dictionary patch : dict.getDictionaries()) { + Patch bm = dictToPatch(notKnownPatches, patch); + patches.add(bm); + } + monitor.setCurrent(null, monitor.getCurrent() + 1, 2); + + if (!nPatch.isEmpty() && Integer.parseInt(nPatch) != patches.size()) { + monitor.error("Number of read patches (" + patches.size() + ") is invalid (expected " + nPatch + ").", 2); + } else if (!notKnownPatches.isEmpty()) { + StringBuilder sb = new StringBuilder(); + sb.append("Unknown patches type: \n"); + for (String string : notKnownPatches) { + sb.append("\t " + string + "\n"); + } + monitor.warning(sb.toString(), 2); + } + } + } + } catch (Exception e) { + monitor.warning("Cannot read the file: " + e.getMessage(), 2); + logger.warn("Cannot read the file", e); + } + } else { + monitor.warning("Boundary file does not exist", 2); + logger.warn("Boundary file does not exist"); + } + return patches; + } + + public static Patch dictToPatch(List notKnownPatches, Dictionary patch) { + String patchName = patch.getName(); + String patchType = patch.lookup("type"); + String physicalType = patch.lookup("physicalType"); + String nFaces = patch.lookup("nFaces"); + + Patch bm = new Patch(patchName); + bm.setDictionary(patch); + bm.setName(patchName); + bm.setVisible(true); + bm.setEmpty(nFaces != null && Integer.valueOf(nFaces) == 0); + bm.setType(patchType); + + if (BoundaryType.isPatch(patchType)) { + if (BoundaryType.isKnown(physicalType)) { + bm.setPhisicalType(BoundaryType.getType(physicalType)); + } else if (BoundaryType.isKnown(BoundaryType.OPENING_KEY)) { + bm.setPhisicalType(BoundaryType.OPENING); + } else { + bm.setPhisicalType(BoundaryType.PATCH); + } + } else if (BoundaryType.isWall(patchType)) { + if (BoundaryType.isKnown(physicalType)) { + bm.setPhisicalType(BoundaryType.getType(physicalType)); + } else { + bm.setPhisicalType(BoundaryType.WALL); + } + } else if (BoundaryType.isMappedPatch(patchType)) { + if (BoundaryType.isKnown(physicalType)) { + bm.setPhisicalType(BoundaryType.getType(physicalType)); + } else { + bm.setPhisicalType(BoundaryType.WALL); + } + } else if (BoundaryType.isMappedWall(patchType)) { + if (BoundaryType.isKnown(physicalType)) { + bm.setPhisicalType(BoundaryType.getType(physicalType)); + } else { + bm.setPhisicalType(BoundaryType.WALL); + } + } else if (BoundaryType.isKnown(patchType)) { + bm.setPhisicalType(BoundaryType.getType(patchType)); + } else if (BoundaryType.isProcessor(patchType)) { + bm.setPhisicalType(BoundaryType.PROCESSOR); + } else if (BoundaryType.isProcessorCyclic(patchType)) { + bm.setPhisicalType(BoundaryType.PROCESSOR_CYCLIC); + } else { + notKnownPatches.add(patchName + ": " + patchType); + bm.setPhisicalType(BoundaryType.getDefaultType()); + } + return bm; + } +} diff --git a/src/eu/engys/core/project/zero/patches/PatchesWriter.java b/src/eu/engys/core/project/zero/patches/PatchesWriter.java new file mode 100644 index 0000000..1437e22 --- /dev/null +++ b/src/eu/engys/core/project/zero/patches/PatchesWriter.java @@ -0,0 +1,189 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.project.zero.patches; + +import static eu.engys.core.dictionary.Dictionary.TYPE; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.dictionary.DictionaryWriter; +import eu.engys.core.dictionary.FoamFile; +import eu.engys.core.project.Model; +import eu.engys.util.IOUtils; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; + +public class PatchesWriter { + + public static final String OFFSETS_KEY = "offsets"; + public static final String TYPE_KEY = "type"; + public static final String PHYSICAL_TYPE_KEY = "physicalType"; + public static final String START_FACE_KEY = "startFace"; + public static final String N_FACES_KEY = "nFaces"; + + private static final Logger logger = LoggerFactory.getLogger(Patches.class); + + private ProgressMonitor monitor; + + private Model model; + + public PatchesWriter(Model model, ProgressMonitor monitor) { + this.model = model; + this.monitor = monitor; + } + + public void write(final Patches patches, File... boundaryFiles) { + Runnable[] runnables = new Runnable[boundaryFiles.length]; + for (int i = 0; i < boundaryFiles.length; i++) { + final File boundary = boundaryFiles[i]; + runnables[i] = new Runnable() { + @Override + public void run() { + writeBoundary(patches, boundary); + } + }; + } +// ExecUtil.execInParallelAndWait(runnables); + ExecUtil.execSerial(runnables); + } + + private void writeBoundary(Patches patches, File boundaryFile) { + monitor.setCurrent(null, monitor.getCurrent() + 1, 2); + logger.info("WRITE: Boundary {}", boundaryFile.getAbsolutePath()); + + Map originalNames = new HashMap(); + Map phisicalTypes = new HashMap(); + Map types = new HashMap(); + Map dictionaries = new HashMap(); + + for (Patch patch : patches) { + phisicalTypes.put(patch.getName(), patch.getPhisicalType().getKey()); + types.put(patch.getName(), patch.getType()); + originalNames.put(patch.getOriginalName(), patch.getName()); + dictionaries.put(patch.getName(), new Dictionary(patch.getDictionary())); + } + + try { + String boundaryString = IOUtils.readStringFromFile(boundaryFile); + + StringBuffer sb = new StringBuffer(boundaryString.length()); + + boundaryString = boundaryString.replaceAll("/\\*(?:.|[\\n\\r])*?\\*/", ""); + + Pattern pattern = Pattern.compile("(\\d+)\\s*\\(([^#]*)\\)"); + Matcher matcher = pattern.matcher(boundaryString); + + if (matcher.find()) { + if (matcher.groupCount() == 2) { + String nPatch = matcher.group(1); + + FoamFile foamFile = FoamFile.getDictionaryFoamFile("polyBoundaryMesh", "\"0/polyMesh\"", "boundary"); + new DictionaryWriter(foamFile).writeDictionary(sb, ""); + + sb.append(nPatch + "(\n"); + String patchesString = matcher.group(2); + + Dictionary patchesStringAsDictionary = DictionaryUtils.readDictionary(patchesString); + for (Dictionary originalPatchDict : patchesStringAsDictionary.getDictionaries()) { + String originalName = originalPatchDict.getName(); + String newName = originalNames.get(originalName); + + Dictionary patchDict = new Dictionary(newName); + patchDict.add(N_FACES_KEY, originalPatchDict.lookup(N_FACES_KEY)); + patchDict.add(START_FACE_KEY, originalPatchDict.lookup(START_FACE_KEY)); + + if (phisicalTypes.containsKey(newName)) { + String phisicalType = phisicalTypes.get(newName); + String type = types.get(newName); + + if (BoundaryType.isPatchPhysicalType(phisicalType)) { + patchDict.add(TYPE_KEY, "patch"); + patchDict.add(PHYSICAL_TYPE_KEY, phisicalType); + } else if (BoundaryType.isCoupledSymmetryPlaneType(phisicalType) && model.getState().getSolverType().isCoupled()) { + patchDict.add(TYPE_KEY, "patch"); + patchDict.add(PHYSICAL_TYPE_KEY, phisicalType); + } else if (BoundaryType.isWallPhysicalType(phisicalType)) { + patchDict.add(TYPE_KEY, type); + patchDict.add(PHYSICAL_TYPE_KEY, phisicalType); + + if (type.equals("mappedPatch") || type.equals("mappedWall")) { + patchDict.add(OFFSETS_KEY, originalPatchDict.lookup(OFFSETS_KEY)); + Dictionary dictionary = dictionaries.get(newName); + if (dictionary.found(N_FACES_KEY)) + dictionary.remove(N_FACES_KEY); + if (dictionary.found(START_FACE_KEY)) + dictionary.remove(START_FACE_KEY); + if (dictionary.found(OFFSETS_KEY)) + dictionary.remove(OFFSETS_KEY); + + patchDict.merge(dictionary); + } + } else { + patchDict.add(TYPE, phisicalType); + } + + if (phisicalType.equals("cyclic") || phisicalType.equals("cyclicAMI") || phisicalType.equals("processor")) { + Dictionary dictionary = dictionaries.get(newName); + if (dictionary.found(N_FACES_KEY)) + dictionary.remove(N_FACES_KEY); + if (dictionary.found(START_FACE_KEY)) + dictionary.remove(START_FACE_KEY); + + patchDict.merge(dictionary); + } + } else { + patchDict.add(TYPE_KEY, originalPatchDict.lookup(TYPE_KEY)); + } + + new DictionaryWriter(patchDict).writeDictionary(sb, " "); + } + + sb.append(")"); + } + } + + FileWriter outStream = new FileWriter(boundaryFile); + outStream.write(sb.toString()); + outStream.close(); + + } catch (IOException e) { + monitor.warning("Cannot read or write boundary file"); + logger.warn("Cannot read or write boundary file", e); + } + + } +} diff --git a/src/eu/engys/core/project/zero/patches/SplitBoundaryConditions.java b/src/eu/engys/core/project/zero/patches/SplitBoundaryConditions.java new file mode 100644 index 0000000..29d2f1d --- /dev/null +++ b/src/eu/engys/core/project/zero/patches/SplitBoundaryConditions.java @@ -0,0 +1,192 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.core.project.zero.patches; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; + +public class SplitBoundaryConditions { + + public static boolean VERBOSE = false; + + private static final Logger logger = LoggerFactory.getLogger(SplitBoundaryConditions.class); + + private Patches patches; + private Fields fields; + + public SplitBoundaryConditions(Patches patches, Fields fields) { + this.patches = patches; + this.fields = fields; + } + + public void execute() { + for (Patch patch : patches) { + String patchName = patch.getName(); + logger.info("Splitting boundary condition for patch {}", patchName); + // System.out.println("*** patch " + patchName + " *** " + + // patch.getBoundaryConditions().toDictionary()); + Patches[] parallelPatches = patches.getParallelPatches(); + if (parallelPatches != null) { + for (int i = 0; i < parallelPatches.length; i++) { + info("\t processor " + i); + Map patchesMap = parallelPatches[i].toMap(); + if (patchesMap.containsKey(patchName)) { + Patch parallelPatch = patchesMap.get(patchName); + parallelPatch.setPhisicalType(patch.getPhisicalType()); + if (patch.getBoundaryConditions() != null && parallelPatch.getBoundaryConditions() != null) { + // System.out.println("SplitBoundaryConditions.execute() split BEFORE "+patchName+parallelPatch.getBoundaryConditions().toDictionary()); + splitTo(patch.getBoundaryConditions(), parallelPatch.getBoundaryConditions()); + //System.out.println("SplitBoundaryConditions.execute() split AFTER "+patchName+parallelPatch.getBoundaryConditions().toDictionary()); + } else if (patch.getBoundaryConditions() == null) { + // System.out.println("SplitBoundaryConditions.execute() GUI patch "+patch.getName()+" has null BC"); + parallelPatch.setBoundaryConditions(null); + } else if (parallelPatch.getBoundaryConditions() == null) { + // System.out.println("SplitBoundaryConditions.execute() parallel patch "+patch.getName()+" has null BC"); + /* do nothing ? */ + } + } + } + } + } + } + + public void splitTo(BoundaryConditions source, BoundaryConditions target) { + if (target.getMomentum() != null) { + splitField(source.getMomentum(), target.getMomentum(), Fields.U); + for (Field U : fields.getMultiphaseUFields()) { + splitField(source.getMomentum(), target.getMomentum(), U.getName()); + } + splitField(source.getMomentum(), target.getMomentum(), Fields.P); + } + if (target.getTurbulence() != null) { + splitField(source.getTurbulence(), target.getTurbulence(), Fields.K); + splitField(source.getTurbulence(), target.getTurbulence(), Fields.OMEGA); + splitField(source.getTurbulence(), target.getTurbulence(), Fields.EPSILON); + splitField(source.getTurbulence(), target.getTurbulence(), Fields.NU_TILDA); + splitField(source.getTurbulence(), target.getTurbulence(), Fields.NUT); + splitField(source.getTurbulence(), target.getTurbulence(), Fields.NU_SGS); + splitField(source.getTurbulence(), target.getTurbulence(), Fields.MUT); + splitField(source.getTurbulence(), target.getTurbulence(), Fields.MU_SGS); + splitField(source.getTurbulence(), target.getTurbulence(), Fields.ALPHA_T); + splitField(source.getTurbulence(), target.getTurbulence(), Fields.ALPHA_SGS); + } + if (target.getRoughness() != null) { + splitField(source.getRoughness(), target.getRoughness(), Fields.NUT); + splitField(source.getRoughness(), target.getRoughness(), Fields.NU_SGS); + splitField(source.getRoughness(), target.getRoughness(), Fields.MUT); + splitField(source.getRoughness(), target.getRoughness(), Fields.MU_SGS); + } + if (target.getThermal() != null) { + splitField(source.getThermal(), target.getThermal(), Fields.T); + } + if (target.getHumidity() != null) { + splitField(source.getHumidity(), target.getHumidity(), Fields.W); + splitField(source.getHumidity(), target.getHumidity(), Fields.DT_W); + } + if (target.getRadiation() != null) { + splitField(source.getRadiation(), target.getRadiation(), Fields.IDEFAULT); + } + if (target.getPassiveScalars() != null) { + splitField(source.getPassiveScalars(), target.getPassiveScalars(), Fields.AOA); + splitField(source.getPassiveScalars(), target.getPassiveScalars(), Fields.DT_AOA); + splitField(source.getPassiveScalars(), target.getPassiveScalars(), Fields.CO2); + splitField(source.getPassiveScalars(), target.getPassiveScalars(), Fields.DT_CO2); + splitField(source.getPassiveScalars(), target.getPassiveScalars(), Fields.SMOKE); + splitField(source.getPassiveScalars(), target.getPassiveScalars(), Fields.DT_SMOKE); + } + if (target.getPhase() != null) { + splitField(source.getPhase(), target.getPhase(), Fields.ETA); + for (Field af : fields.getAlphaFields()) { + splitField(source.getPhase(), target.getPhase(), af.getName()); + } + } + } + + private void splitField(Dictionary source, Dictionary target, String field) { + if (source.isDictionary(field) && target.isDictionary(field)) { + Dictionary fieldSource = source.subDict(field); + Dictionary fieldTarget = target.subDict(field); + if (haveSameType(fieldSource, fieldTarget)) { + if (BoundaryConditions.isPlaceHolder(fieldTarget)) { + if (BoundaryConditions.isPlaceHolder(fieldSource)) { + /* DO NOTHING */ + info("\t\t "+field+" (PH + PH) DO NOTHING"); + } else { + /* DO NOTHING */ + info("\t\t "+field+" (UN + PH) SAVE EXCLUDING UNIFORM"+target); + fieldTarget.merge(fieldSource, BoundaryConditions.PLACE_HOLDER_KEYS); + } + } else { + if (BoundaryConditions.isPlaceHolder(fieldSource)) { + /* BOH? */ + info("\t\t "+field+" (PH + UN) BOH?"+fieldSource+fieldTarget); + } else { + /* SAVE */ + if (BoundaryConditions.isNonUniform(fieldSource)) { + /* DO NOTHING */ + info("\t\t "+field+" (NUN + UN) DO NOTHING"); + fieldTarget.merge(fieldSource, BoundaryConditions.PLACE_HOLDER_KEYS); + } else { + info("\t\t "+field+" (UN + UN) SAVE"); + // System.out.println("SplitBoundaryConditions.splitField() SOURCE BEFORE "+fieldSource); + // System.out.println("SplitBoundaryConditions.splitField() TARGET BEFORE "+fieldTarget); + fieldTarget.clear(); + fieldTarget.merge(fieldSource); + // System.out.println("SplitBoundaryConditions.splitField() SOURCE AFTER "+fieldSource); + // System.out.println("SplitBoundaryConditions.splitField() TARGET AFTER "+fieldTarget); + } + } + } + } else { + // System.err.println("ERROR: different type for "+field+" dictionary"); + fieldTarget.clear(); + fieldTarget.merge(fieldSource); + } + } else if (source.isDictionary(field) && !target.isDictionary(field)) { + // System.err.println("ERROR: missing target "+field+" dictionary"); + } else if (!source.isDictionary(field) && target.isDictionary(field)) { + // System.err.println("ERROR: missing source "+field+" dictionary"); + } else { + // System.err.println("ERROR: missing both "+field+" dictionary"); + } + } + + private static void info(String msg) { + if (VERBOSE) System.err.println(msg); + } + + private boolean haveSameType(Dictionary d1, Dictionary d2) { + return d1.isField("type") && d2.isField("type") && d1.lookup("type").equals(d2.lookup("type")); + } + +} diff --git a/src/eu/engys/core/report/Exporter.java b/src/eu/engys/core/report/Exporter.java new file mode 100644 index 0000000..b3b5f37 --- /dev/null +++ b/src/eu/engys/core/report/Exporter.java @@ -0,0 +1,143 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.report; + +import java.io.File; +import java.util.List; + +import org.apache.poi.ss.usermodel.Workbook; + +import au.com.bytecode.opencsv.CSVWriter; +import eu.engys.core.project.system.monitoringfunctionobjects.Parser; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.core.report.excel.CSVExporter; +import eu.engys.core.report.excel.ExcelExporter; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.progress.SilentMonitor; + +public abstract class Exporter { + + protected static final String POPULATING_SHEET = "Populating sheet "; + protected static final String PARSING_LOG_FILE = "Parsing log file: "; + protected static final String DOTS = "..."; + + protected List parsers; + protected ProgressMonitor monitor; + + public Exporter(List parsers, ProgressMonitor monitor) { + this.parsers = parsers; + this.monitor = monitor; + } + + protected TimeBlocks getTimeBlocks() throws Exception { + monitor.setIndeterminate(false); + monitor.setTotal(parsers.size()); + + TimeBlocks blocks = new TimeBlocks(); + for (int i = 0; i < parsers.size(); i++) { + Parser parser = parsers.get(i); + monitor.info(PARSING_LOG_FILE + parser.getFile(), 1); + parser.init(); + blocks.addAll(parser.updateParsing()); + parser.end(); + monitor.setCurrent(null, monitor.getCurrent() + 1); + } + return blocks; + } + + /* + * Excel + */ + + public void exportToExcel(File reportFile, ProgressMonitor monitor) throws Exception { + ExcelExporter exporter = new ExcelExporter(parsers, monitor) { + @Override + protected void populate(Workbook workbook) throws Exception { + populateExcelFile(workbook); + } + }; + exporter.create(reportFile); + exporter.show(reportFile); + } + + protected abstract void populateExcelFile(Workbook workbook) throws Exception; + + /* + * CSV + */ + + public void exportToCSV(File reportFile, ProgressMonitor monitor) throws Exception { + CSVExporter exporter = new CSVExporter(parsers, monitor) { + + @Override + protected void populate(CSVWriter writer) throws Exception { + populateCSVFile(writer); + } + }; + + exporter.create(reportFile); + exporter.show(reportFile); + } + + protected void populateCSVFile(CSVWriter writer) throws Exception { + + } + + protected void addRow(CSVWriter writer, String string) { + writer.writeNext(new String[] { string }); + } + + protected void addEmptyRow(CSVWriter writer) { + writer.writeNext(new String[] { "" }); + } + + /* + * For test purposes only + */ + public void exportToExcel_TEST(File reportFile) throws Exception { + ExcelExporter exporter = new ExcelExporter(parsers, new SilentMonitor()) { + + @Override + protected void populate(Workbook workbook) throws Exception { + populateExcelFile(workbook); + } + }; + + exporter.create(reportFile); + } + + public void exportToCSV_TEST(File reportFile) throws Exception { + CSVExporter exporter = new CSVExporter(parsers, new SilentMonitor()) { + + @Override + protected void populate(CSVWriter writer) throws Exception { + populateCSVFile(writer); + } + }; + + exporter.create(reportFile); + } +} diff --git a/src/eu/engys/core/report/excel/CSVExporter.java b/src/eu/engys/core/report/excel/CSVExporter.java new file mode 100644 index 0000000..ad771a0 --- /dev/null +++ b/src/eu/engys/core/report/excel/CSVExporter.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.report.excel; + +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.List; + +import au.com.bytecode.opencsv.CSVWriter; +import eu.engys.core.executor.FileManagerSupport; +import eu.engys.core.project.system.monitoringfunctionobjects.Parser; +import eu.engys.util.progress.ProgressMonitor; + +public abstract class CSVExporter { + + protected List parsers; + protected ProgressMonitor monitor; + + public CSVExporter(List parsers, ProgressMonitor monitor) { + this.parsers = parsers; + this.monitor = monitor; + } + + public CSVExporter(Parser parser) { + List parsers = new ArrayList<>(); + parsers.add(parser); + this.parsers = parsers; + } + + public void create(File reportFile) throws Exception { + CSVWriter writer = new CSVWriter(new FileWriter(reportFile), ','); + populate(writer); + end(writer); + } + + protected abstract void populate(CSVWriter writer) throws Exception; + + private void end(CSVWriter writer) throws Exception { + writer.close(); + } + + public void show(File reportFile) { + FileManagerSupport.open(reportFile); + } + +} diff --git a/src/eu/engys/core/report/excel/ExcelExporter.java b/src/eu/engys/core/report/excel/ExcelExporter.java new file mode 100644 index 0000000..f924b85 --- /dev/null +++ b/src/eu/engys/core/report/excel/ExcelExporter.java @@ -0,0 +1,83 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.report.excel; + +import static eu.engys.util.ui.FileChooserUtils.EXCEL_EXTENSION_NEW; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FilenameUtils; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import eu.engys.core.executor.FileManagerSupport; +import eu.engys.core.project.system.monitoringfunctionobjects.Parser; +import eu.engys.util.progress.ProgressMonitor; + +public abstract class ExcelExporter { + + protected List parsers; + protected ProgressMonitor monitor; + + public ExcelExporter(List parsers, ProgressMonitor monitor) { + this.parsers = parsers; + this.monitor = monitor; + } + + public ExcelExporter(Parser parser) { + List parsers = new ArrayList<>(); + parsers.add(parser); + this.parsers = parsers; + } + + public void create(File reportFile) throws Exception { + Workbook workbook = null; + if (FilenameUtils.getExtension(reportFile.getAbsolutePath()).equals(EXCEL_EXTENSION_NEW)) { + workbook = new XSSFWorkbook(); + } else { + workbook = new HSSFWorkbook(); + } + populate(workbook); + end(workbook, reportFile); + } + + protected abstract void populate(Workbook workbook) throws Exception; + + private void end(Workbook workbook, File reportFile) throws Exception { + FileOutputStream fileOut = new FileOutputStream(reportFile); + workbook.write(fileOut); + fileOut.close(); + } + + public void show(File reportFile) { + FileManagerSupport.open(reportFile); + } + +} diff --git a/src/eu/engys/core/report/excel/ExcelUtils.java b/src/eu/engys/core/report/excel/ExcelUtils.java new file mode 100644 index 0000000..b2483af --- /dev/null +++ b/src/eu/engys/core/report/excel/ExcelUtils.java @@ -0,0 +1,84 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.report.excel; + +import javax.vecmath.Point3d; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.util.CellRangeAddress; + +public class ExcelUtils { + + public static void addHeaderCell(Workbook workbook, Row row, int col, String value) { + Cell cell = row.createCell(col); + cell.setCellValue(value); + + Font font = workbook.createFont(); + font.setBoldweight(Font.BOLDWEIGHT_BOLD); + + CellStyle cellStyle = workbook.createCellStyle(); + cellStyle.setFont(font); + cellStyle.setAlignment(CellStyle.ALIGN_CENTER); + cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + cell.setCellStyle(cellStyle); + } + + public static void addEmptyCell(Workbook workbook, Row row, int col) { + row.createCell(col).setCellValue(""); + } + + public static void addDoubleCell(Sheet sheet, int row, int col, double value) { + sheet.getRow(row + 1).createCell(col + 1).setCellValue(value); + } + + public static void addPointCells(Sheet sheet, int row, int col, Point3d point) { + sheet.getRow(row + 1).createCell(col + 1).setCellValue(point.getX()); + sheet.getRow(row + 1).createCell(col + 2).setCellValue(point.getY()); + sheet.getRow(row + 1).createCell(col + 3).setCellValue(point.getZ()); + } + + public static void mergeColumnsOnRow(Sheet sheet, int firstRow, int firstColumn, int lastColumn) { + sheet.addMergedRegion(new CellRangeAddress(firstRow, firstRow, firstColumn, lastColumn)); + } + + public static void autoSizeColumns(Sheet sheet) { + // header row + for (int i = 0; i < sheet.getRow(0).getLastCellNum(); i++) { + sheet.autoSizeColumn(i, true); + } + + // table row + for (int i = 0; i < sheet.getRow(1).getLastCellNum(); i++) { + sheet.autoSizeColumn(i, true); + } + } + +} diff --git a/src/eu/engys/core/report/pdf/PDFImage.java b/src/eu/engys/core/report/pdf/PDFImage.java new file mode 100644 index 0000000..76718ae --- /dev/null +++ b/src/eu/engys/core/report/pdf/PDFImage.java @@ -0,0 +1,46 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.report.pdf; + +public class PDFImage { + + private String title; + private String name; + + public PDFImage(String name, String title) { + this.name = name; + this.title = title; + } + + public String getTitle() { + return title; + } + + public String getName() { + return name; + } + +} diff --git a/src/eu/engys/core/report/pdf/PDFPage.java b/src/eu/engys/core/report/pdf/PDFPage.java new file mode 100644 index 0000000..379888f --- /dev/null +++ b/src/eu/engys/core/report/pdf/PDFPage.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.report.pdf; + +import com.lowagie.text.Element; + +public interface PDFPage { + + public abstract String getTitle(); + + public abstract Element getElement(); + +} diff --git a/src/eu/engys/core/report/pdf/PDFPageEvent.java b/src/eu/engys/core/report/pdf/PDFPageEvent.java new file mode 100644 index 0000000..6ecb85e --- /dev/null +++ b/src/eu/engys/core/report/pdf/PDFPageEvent.java @@ -0,0 +1,79 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.report.pdf; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +import com.lowagie.text.BadElementException; +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Image; +import com.lowagie.text.pdf.PdfContentByte; +import com.lowagie.text.pdf.PdfPageEventHelper; +import com.lowagie.text.pdf.PdfWriter; + +public class PDFPageEvent extends PdfPageEventHelper { + + private static final int FRONT_PAGE_INDEX = 1; + private URL frontPagewatermarkImage; + private URL watermarkImage; + + public PDFPageEvent(URL frontPagewatermarkImage, URL watermarkImage) { + this.frontPagewatermarkImage = frontPagewatermarkImage; + this.watermarkImage = watermarkImage; + } + + @Override + public void onEndPage(PdfWriter writer, Document document) { + try { + _addWatermark(writer, document); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void _addWatermark(PdfWriter writer, Document document) throws BadElementException, MalformedURLException, IOException, DocumentException { + PdfContentByte canvas = writer.getDirectContentUnder(); + Image image = null; + if (document.getPageNumber() == FRONT_PAGE_INDEX) { + image = Image.getInstance(frontPagewatermarkImage); + } else { + image = Image.getInstance(watermarkImage); + } + image.setAlignment(Image.MIDDLE); + float x = (document.getPageSize().getWidth() - image.getWidth()) / 2; + float y = (document.getPageSize().getHeight() - image.getHeight()) / 2; + if (document.getPageNumber() == FRONT_PAGE_INDEX) { + image.setAbsolutePosition(x, y - 30); + } else { + image.setAbsolutePosition(x, y); + } + canvas.addImage(image); + + } +} diff --git a/src/eu/engys/core/report/pdf/PDFReport.java b/src/eu/engys/core/report/pdf/PDFReport.java new file mode 100644 index 0000000..c1112d8 --- /dev/null +++ b/src/eu/engys/core/report/pdf/PDFReport.java @@ -0,0 +1,107 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.report.pdf; + +import java.io.File; +import java.io.FileOutputStream; +import java.net.URL; +import java.util.LinkedList; +import java.util.List; + +import com.lowagie.text.Document; +import com.lowagie.text.Element; +import com.lowagie.text.HeaderFooter; +import com.lowagie.text.Phrase; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.PdfWriter; + +import eu.engys.core.project.Model; + +public abstract class PDFReport { + + protected Model model; + + private Document document; + private PdfWriter writer; + private File reportFile; + + private List pages = new LinkedList<>(); + + public PDFReport(Model model, File reportFile) { + this.model = model; + this.reportFile = reportFile; + } + + public void create() throws Exception { + document = new Document(); + writer = PdfWriter.getInstance(document, new FileOutputStream(reportFile)); + writer.setPageEvent(new PDFPageEvent(getFrontPageWaterMarkImage(), getWaterMarkImage())); + document.open(); + addFooter(); + populate(); + end(); + } + + private void addFooter() { + HeaderFooter headerFooter = new HeaderFooter(new Phrase(getFooter()), false); + headerFooter.setAlignment(Element.ALIGN_CENTER); + headerFooter.setBorder(Rectangle.TOP); + document.setFooter(headerFooter); + } + + protected abstract void populate() throws Exception; + + public abstract URL getWaterMarkImage(); + + public abstract URL getFrontPageWaterMarkImage(); + + public abstract String getFooter(); + + protected void addPage(PDFPage page) { + pages.add(page); + } + + private void end() throws Exception { + for (PDFPage page : pages) { + document.add(page.getElement()); + } + document.close(); + writer.close(); + } + + public Model getModel() { + return model; + } + + public PdfWriter getWriter() { + return writer; + } + + public Document getDocument() { + return document; + } + +} diff --git a/src/eu/engys/core/report/pdf/PDFUtils.java b/src/eu/engys/core/report/pdf/PDFUtils.java new file mode 100644 index 0000000..8de6769 --- /dev/null +++ b/src/eu/engys/core/report/pdf/PDFUtils.java @@ -0,0 +1,213 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.core.report.pdf; + +import java.awt.Color; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.lowagie.text.BadElementException; +import com.lowagie.text.Document; +import com.lowagie.text.Element; +import com.lowagie.text.Font; +import com.lowagie.text.Image; +import com.lowagie.text.Paragraph; +import com.lowagie.text.Phrase; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.PdfPCell; +import com.lowagie.text.pdf.PdfPTable; + +import eu.engys.core.project.Model; + +public class PDFUtils { + + private static final Logger logger = LoggerFactory.getLogger(PDFUtils.class); + + private static final int DEFAULT_FONT = Font.HELVETICA; + public static final String POSTPRO = "POSTPRO"; + + public static final int MEDIUM_FONT = 18; + public static final int BIG_FONT = 25; + + public static final int SMALL_LINE_SPACING = 10; + public static final int MEDIUM_LINE_SPACING = 20; + public static final int LARGE_LINE_SPACING = 50; + public static final int HUGE_LINE_SPACING = 100; + + public static final String NO_VALUE = "-"; + + public static Paragraph createParagraph() { + return createParagraph(MEDIUM_LINE_SPACING); + } + + public static Paragraph createParagraph(int lineSpacing) { + return createParagraph(lineSpacing, Element.ALIGN_CENTER); + } + + public static Paragraph createParagraph(int lineSpacing, int align) { + Paragraph paragraph = new Paragraph(); + paragraph.setLeading(lineSpacing); + paragraph.setAlignment(align); + paragraph.setSpacingBefore(10); + return paragraph; + } + + public static Phrase createLine(String text) { + return createLine(text, MEDIUM_FONT, false, Color.BLACK); + } + + public static Phrase createLine(String text, int fontSize) { + return createLine(text, fontSize, false, Color.BLACK); + } + + public static Phrase createLine(String text, int fontSize, boolean bold) { + return createLine(text, fontSize, bold, Color.BLACK); + } + + public static Phrase createLine(String text, int fontSize, boolean bold, Color color) { + Font font = new Font(DEFAULT_FONT, fontSize, bold ? Font.BOLD : Font.NORMAL, color); + Phrase phrase = new Phrase(text + "\n", font); + return phrase; + } + + public static PdfPTable createTableKeyValue(String[][] data) { + PdfPTable table = new PdfPTable(data[0].length); + for (String[] row : data) { + String key = row[0]; + String value = row[1]; + + Paragraph keyParagraph = new Paragraph(key); + keyParagraph.getFont().setStyle(Font.BOLD); + + PdfPCell keyCell = new PdfPCell(keyParagraph); + keyCell.setPadding(5); + keyCell.setHorizontalAlignment(PdfPCell.LEFT); + keyCell.setBorderWidth(1); + keyCell.setBorderColor(Color.GRAY); + table.addCell(keyCell); + + PdfPCell valueCell = new PdfPCell(new Paragraph(value)); + valueCell.setPadding(5); + valueCell.setHorizontalAlignment(PdfPCell.LEFT); + valueCell.setBorderWidth(1); + valueCell.setBorderColor(Color.GRAY); + table.addCell(valueCell); + + } + return table; + } + + public static PdfPTable createTable(String[][] data) { + PdfPTable table = new PdfPTable(data[0].length); + for (String[] row : data) { + for (String value : row) { + PdfPCell cell = new PdfPCell(new Paragraph(value)); + cell.setPadding(5); + cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); + cell.setBorderWidth(1); + cell.setBorderColor(Color.GRAY); + if (table.getRows().size() % 2 == 0) { + cell.setBackgroundColor(new Color(245, 245, 245)); + } else { + cell.setBackgroundColor(new Color(230, 250, 250)); + } + table.addCell(cell); + } + } + return table; + } + + public static Image createImage(Document document, URL url) throws BadElementException, MalformedURLException, IOException { + Image image = Image.getInstance(url); + image.setAlignment(Image.MIDDLE); + float ratio = image.getWidth() / (document.getPageSize().getWidth() - 100); + image.scaleAbsolute((image.getWidth() / ratio), (image.getHeight() / ratio)); + return image; + } + + public static PdfPTable createImagePage(Model model, PDFImage[] images) { + File postProFolder = new File(model.getProject().getBaseDir(), POSTPRO); + if (postProFolder.exists()) { + PdfPTable table = new PdfPTable(1); + table.getDefaultCell().setBorder(Rectangle.BOX); + + for (PDFImage image : images) { + File file = new File(postProFolder, image.getName()); + addImageToTable(table, file); + addTitleToTable(table, image.getTitle()); + addEmptyCellToTable(table); + } + table.setWidthPercentage(70); + table.setKeepTogether(true); + + return table; + } else { + return new PdfPTable(1); + } + } + + private static void addEmptyCellToTable(PdfPTable table) { + PdfPCell emptyCell = new PdfPCell(new Phrase("")); + emptyCell.setBorder(Rectangle.NO_BORDER); + table.addCell(emptyCell); + } + + private static void addTitleToTable(PdfPTable table, String title) { + if (title.isEmpty()) { + return; + } + PdfPCell textCell = new PdfPCell(new Phrase(title)); + textCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); + table.addCell(textCell); + } + + private static void addImageToTable(PdfPTable table, File imageFile) { + try { + if (imageFile.exists()) { + Image image = Image.getInstance(imageFile.toURI().toURL()); + image.setAlignment(Image.MIDDLE); + table.addCell(image); + } else { + PdfPCell missingImageText = new PdfPCell(new Phrase("Missing Image")); + missingImageText.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); + table.addCell(missingImageText); + } + } catch (BadElementException | IOException e) { + logger.error(e.getMessage()); + } + } + + public static Paragraph createImagesBlock(Model model, PDFImage... images) { + Paragraph p = createParagraph(); + p.add(createImagePage(model, images)); + return p; + } +} diff --git a/src/eu/engys/gui/AboutWindow.java b/src/eu/engys/gui/AboutWindow.java new file mode 100644 index 0000000..79ce270 --- /dev/null +++ b/src/eu/engys/gui/AboutWindow.java @@ -0,0 +1,166 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.net.MalformedURLException; +import java.net.URL; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JWindow; + +import eu.engys.util.ApplicationInfo; +import eu.engys.util.Util; +import eu.engys.util.ui.UiUtil; + +public class AboutWindow { + + private JWindow window; + private final Icon vendorIcon; + private final Icon applicationIcon; + + public AboutWindow(Icon vendorIcon, Icon applicationIcon) { + this.vendorIcon = vendorIcon; + this.applicationIcon = applicationIcon; + createWindow(); + } + + private void createWindow() { + window = new JWindow(UiUtil.getActiveWindow()); + window.getContentPane().setLayout(new BorderLayout()); + JPanel mainPanel = createMainPanel(); + window.getContentPane().add(mainPanel, BorderLayout.CENTER); + window.setSize(mainPanel.getPreferredSize().width, mainPanel.getPreferredSize().height); + window.setLocationRelativeTo(null); + window.setVisible(true); + } + + private JPanel createMainPanel() { + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.setBackground(Color.WHITE); + mainPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + mainPanel.add(createNorthPanel(), BorderLayout.NORTH); + mainPanel.add(createCenterPanel(), BorderLayout.CENTER); + mainPanel.add(createCloseButtonPanel(), BorderLayout.SOUTH); + return mainPanel; + } + + private JPanel createNorthPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.setBackground(Color.WHITE); + panel.add(getImage(vendorIcon), BorderLayout.WEST); + panel.add(getImage(applicationIcon), BorderLayout.CENTER); + panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + return panel; + } + + private JLabel getImage(Icon imageIcon) { + JLabel label = new JLabel(imageIcon); + label.setOpaque(true); + label.setBackground(Color.WHITE); + return label; + } + + private JPanel createCloseButtonPanel() { + JPanel panel = new JPanel(new FlowLayout()); + panel.setBackground(Color.WHITE); + panel.add(new JButton(new AbstractAction("Close") { + @Override + public void actionPerformed(ActionEvent e) { + window.dispose(); + } + })); + return panel; + } + + private JPanel createCenterPanel() { + JLabel vers = center("" + ApplicationInfo.getVersion() + "", 20f, Color.BLACK); + JLabel copy = center("" + ApplicationInfo.getCopyright() + "", 10f, Color.BLACK); + + JPanel infoPanel = new JPanel(new GridBagLayout()); + infoPanel.setBackground(Color.WHITE); + infoPanel.add(vers, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(30, 10, 0, 10), 0, 0)); + infoPanel.add(copy, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 10, 30, 10), 0, 0)); + + final JButton sitebutton = createOpenSiteButton(); + JPanel siteButtonPanel = new JPanel(new GridBagLayout()); + siteButtonPanel.setBackground(Color.WHITE); + siteButtonPanel.add(sitebutton, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 10, 20, 10), 0, 0)); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(infoPanel, BorderLayout.NORTH); + // mainPanel.add(new JPanel(), BorderLayout.CENTER); + mainPanel.add(siteButtonPanel, BorderLayout.CENTER); + return mainPanel; + } + + private JButton createOpenSiteButton() { + final JButton button = new JButton(new AbstractAction(ApplicationInfo.getSite()) { + + @Override + public void actionPerformed(ActionEvent e) { + try { + Util.openWebpage(new URL(ApplicationInfo.getSite())); + } catch (MalformedURLException e1) { + e1.printStackTrace(); + } + } + }); + button.setForeground(Color.BLUE); + return button; + } + + private JLabel center(String text, float size, Color color) { + JLabel label = new JLabel(text) { + @Override + public void paintComponent(Graphics g) { + Graphics2D graphics2d = (Graphics2D) g; + graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + super.paintComponent(g); + } + }; + label.setAlignmentX(JLabel.CENTER_ALIGNMENT); + label.setHorizontalAlignment(JLabel.CENTER); + label.setFont(label.getFont().deriveFont(size)); + label.setForeground(color); + return label; + } +} diff --git a/src/eu/engys/gui/AbstractGUIPanel.java b/src/eu/engys/gui/AbstractGUIPanel.java new file mode 100644 index 0000000..6c7f402 --- /dev/null +++ b/src/eu/engys/gui/AbstractGUIPanel.java @@ -0,0 +1,235 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui; + +import java.awt.BorderLayout; +import java.awt.Font; + +import javax.inject.Inject; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSeparator; +import javax.swing.JToolBar; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.Model; +import eu.engys.gui.view3D.CanvasPanel; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; + +public abstract class AbstractGUIPanel extends JPanel implements GUIPanel, ModelObserver { + + private static final Logger logger = LoggerFactory.getLogger(GUIPanel.class); + + @Inject + protected ProgressMonitor monitor; + + private final String title; + protected final Model model; + + private JLabel titleLabel; + protected JToolBar titleToolbar; + + protected CanvasPanel view3D; + + public AbstractGUIPanel(String title, Model model) { + super(new BorderLayout()); + this.title = title; + this.model = model; + + setName(title); + logger.info("-> {}", title); + } + + @Override + public void install(CanvasPanel view3D) { + this.view3D = view3D; + } + + @Override + public void layoutPanel() { + JComponent titleComponent = createTitle(title); + JComponent mainComponent = layoutComponents(); + + titleComponent.setBorder(BorderFactory.createEmptyBorder(0, 0, 4, 8)); + mainComponent.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8)); + + add(titleComponent, BorderLayout.NORTH); + add(mainComponent, BorderLayout.CENTER); + } + + protected JComponent layoutComponents() { + return new JLabel("Component"); + } + + private JComponent createTitle(String text) { + titleLabel = new JLabel(text); + Font font = titleLabel.getFont(); + titleLabel.setFont(font.deriveFont(font.getSize2D() + 2).deriveFont(Font.BOLD)); + + titleToolbar = UiUtil.getToolbar("view.gui.toolbar"); + titleToolbar.add(titleLabel); + titleToolbar.add(Box.createHorizontalGlue()); + + PanelBuilder pb = new PanelBuilder(); + pb.addComponent(titleToolbar); + pb.addComponent(new JSeparator()); + + return pb.removeMargins().getPanel(); + } + + protected void setTitle(String title) { + if (titleLabel != null) { + titleLabel.setText(title); + } + } + + @Override + public String getName() { + return title; + } + + @Override + public String getKey() { + return title; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public String getVersion() { + return getClass().getPackage().getImplementationVersion(); + } + + @Override + public JComponent getPanel() { + JScrollPane scrollPane = new JScrollPane(this); + scrollPane.getVerticalScrollBar().setUnitIncrement(20); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + return scrollPane; + } + + @Override + public void load() { + } + + @Override + public void resetToDefaults() { + } + + @Override + public void save() { + requestFocusInWindow(); + } + + @Override + public void clear() { + } + + @Override + public boolean canStart() { + return true; + } + + @Override + public void start() { + } + + @Override + public boolean canStop() { + return true; + } + + @Override + public void stop() { + save(); + } + + public Model getModel() { + return model; + } + + @Override + public void fieldManipulationFunctionObjectsChanged() { + } + + @Override + public void monitoringFunctionObjectsChanged() { + } + + @Override + public void stateChanged() { + } + + @Override + public void runtimeFieldsChanged() { + } + + @Override + public void fieldsChanged() { + } + + @Override + public void solverChanged() { + } + + @Override + public void materialsChanged() { + } + + @Override + public void projectChanged() { + } + + @Override + public int getIndex() { + return -1; + } + + public ProgressMonitor getMonitor() { + return monitor; + } + + public void setMonitor(ProgressMonitor monitor) { + this.monitor = monitor; + } + + @Override + public String toString() { + return title; + } + +} diff --git a/src/eu/engys/gui/Actions.java b/src/eu/engys/gui/Actions.java new file mode 100644 index 0000000..d9c0259 --- /dev/null +++ b/src/eu/engys/gui/Actions.java @@ -0,0 +1,37 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui; + +import javax.swing.JToolBar; + +public interface Actions { + + public JToolBar toolbar(); + + public void update(); + +} diff --git a/src/eu/engys/gui/CreateCaseDialog.java b/src/eu/engys/gui/CreateCaseDialog.java new file mode 100644 index 0000000..e3b0926 --- /dev/null +++ b/src/eu/engys/gui/CreateCaseDialog.java @@ -0,0 +1,366 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui; + +import static eu.engys.util.ui.ComponentsFactory.checkField; +import static eu.engys.util.ui.ComponentsFactory.intArrayField; +import static eu.engys.util.ui.ComponentsFactory.intField; +import static eu.engys.util.ui.ComponentsFactory.labelArrayField; +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.util.Arrays; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import eu.engys.core.project.CaseParameters; +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.FileFieldPanel; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.IntegerField; +import eu.engys.util.ui.textfields.StringField; +import eu.engys.util.ui.textfields.verifiers.AbstractVerifier; +import eu.engys.util.ui.textfields.verifiers.AbstractVerifier.ValidationStatusListener; + +public class CreateCaseDialog extends JPanel { + + public static final String CREATE_CASE_LABEL = "Create Case"; + public static final String HIERARCHY_LABEL = "Hierarchy"; + public static final String PROCESSORS_LABEL = "Processors"; + public static final String PARALLEL_LABEL = "Parallel"; + public static final String PARENT_FOLDER_LABEL = "Parent Folder"; + public static final String CASE_NAME_LABEL = "Case Name"; + + enum Status { + OK, ERROR, CANCEL + } + + private static final int X = 0; + private static final int Y = 1; + private static final int Z = 2; + + private OkDialogAction okAction = new OkDialogAction(); + private CancelDialogAction cancelAction = new CancelDialogAction(); + + private JDialog dialog; + private FileFieldPanel fileField; + private StringField nameField; + private IntegerField nProcessorsField; + private JCheckBox isParallel; + + private File baseDir; + private IntegerField[] nHierarchyField; + private Status status = Status.ERROR; + + public CreateCaseDialog() { + super(new BorderLayout()); + layoutComponents(); + createDialog(); + setDefaultValues(); + } + + private void layoutComponents() { + fileField = ComponentsFactory.fileField(SelectionMode.DIRS_ONLY, "Select a folder where to save the case", false); + nameField = stringField(); + isParallel = checkField(); + nProcessorsField = intField(); + nHierarchyField = intArrayField(3); + + ((AbstractVerifier) nameField.getInputVerifier()).setValidationStatusListener(new ValidationStatusListener() { + + @Override + public void validatePassed() { + okAction.setEnabled(true); + } + + @Override + public void validateFailed() { + okAction.setEnabled(false); + } + }); + + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(CASE_NAME_LABEL, nameField); + builder.addComponent(PARENT_FOLDER_LABEL, fileField); + builder.addComponent(PARALLEL_LABEL, isParallel); + builder.addComponent(PROCESSORS_LABEL, nProcessorsField); + builder.addComponent(labelArrayField("x", "y", "z")); + builder.addComponent(HIERARCHY_LABEL, nHierarchyField[X], nHierarchyField[Y], nHierarchyField[Z]); + nProcessorsField.setEnabled(false); + for (IntegerField f : nHierarchyField) + f.setEnabled(false); + + isParallel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + nProcessorsField.setEnabled(isParallel.isSelected()); + nProcessorsField.setIntValue(isParallel.isSelected() ? 2 : 1); + for (IntegerField f : nHierarchyField) + f.setEnabled(isParallel.isSelected()); + } + }); + nProcessorsField.addPropertyChangeListener(new IntFieldHandler(nProcessorsField, nHierarchyField)); + nProcessorsField.setIntValue(1); + + add(builder.getPanel()); + } + + private void createDialog() { + JButton okButton = new JButton(okAction); + okButton.setName("button.ok"); + + JButton cancelButton = new JButton(cancelAction); + cancelButton.setName("button.cancel"); + + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonsPanel.add(okButton); + buttonsPanel.add(cancelButton); + + dialog = new JDialog(UiUtil.getActiveWindow(), CREATE_CASE_LABEL); + dialog.setName("create.case.dialog"); + dialog.setModal(true); + dialog.setSize(350, 250); + dialog.setLocationRelativeTo(null); + dialog.getContentPane().setLayout(new BorderLayout()); + dialog.getContentPane().add(this, BorderLayout.CENTER); + dialog.getContentPane().add(buttonsPanel, BorderLayout.SOUTH); + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.getRootPane().setDefaultButton(okButton); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + if (cancelAction.isEnabled()) { + cancelAction(); + } + } + }); + } + + private void setDefaultValues() { + File lastDir = PrefUtil.getWorkDir(PrefUtil.WORK_DIR); + fileField.setFile(lastDir); + + nameField.setText("newCase"); + + isParallel.setSelected(false); + isParallel.doClick(); + } + + public void showDialog() { + dialog.setVisible(true); + } + + private void closeDialog() { + dialog.setVisible(false); + dialog.dispose(); + } + + public CaseParameters getParameters() { + CaseParameters params = new CaseParameters(); + params.setBaseDir(baseDir); + params.setParallel(isParallel.isSelected()); + params.setnProcessors(nProcessorsField.getIntValue()); + params.setnHierarchy(new int[] { nHierarchyField[0].getIntValue(), nHierarchyField[1].getIntValue(), nHierarchyField[2].getIntValue() }); + return params; + } + + private void checkStatus() { + String warning = "Create Case Warning"; + String error = "Create Case Error"; + String parentPath = fileField.getFilePath(); + if (parentPath.isEmpty()) { + JOptionPane.showMessageDialog(dialog, "Empty parent folder", error, JOptionPane.ERROR_MESSAGE); + status = Status.CANCEL; + } else { + File parent = new File(parentPath); + if (parent.exists()) { + if (Util.canWrite(parent)) { + baseDir = new File(parent, nameField.getText()); + if (baseDir.exists()) { + if (baseDir.isFile()) { + JOptionPane.showMessageDialog(dialog, "File already exists", error, JOptionPane.ERROR_MESSAGE); + status = Status.CANCEL; + } else if (baseDir.isDirectory() && baseDir.list().length != 0) { + int retVal = JOptionPane.showConfirmDialog(dialog, "Folder already exists. Continue anyway?", warning, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (retVal == JOptionPane.NO_OPTION) { + status = Status.CANCEL; + } else { + status = Status.OK; + } + } else { + status = Status.OK; + } + } else { + status = Status.OK; + } + } else { + JOptionPane.showMessageDialog(dialog, "Write permission", error, JOptionPane.ERROR_MESSAGE); + status = Status.CANCEL; + } + } else { + String msg = String.format("Folder %s does not exist.\n Do you want to create it?", parent); + int retVal = JOptionPane.showConfirmDialog(dialog, msg, warning, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + if (retVal == JOptionPane.NO_OPTION) { + status = Status.CANCEL; + } else { + if (parent.canWrite()) { + status = Status.OK; + } else { + JOptionPane.showMessageDialog(dialog, "Write permission", error, JOptionPane.ERROR_MESSAGE); + status = Status.CANCEL; + } + } + } + } + } + + private void okAction() { + checkStatus(); + if (isOK()) { + if (isParallel.isSelected() && !productEqualsToNumberOfSubdomain()) { + JOptionPane.showMessageDialog(dialog, "Product of Hierarchical Coefficients should be equal to the Number of Processors", "Decomposition error", JOptionPane.ERROR_MESSAGE); + return; + } + } + closeDialog(); + } + + private boolean productEqualsToNumberOfSubdomain() { + int nOfSubdomains = nProcessorsField.getIntValue(); + int x = nHierarchyField[X].getIntValue(); + int y = nHierarchyField[Y].getIntValue(); + int z = nHierarchyField[Z].getIntValue(); + + return nOfSubdomains == x * y * z; + } + + private void cancelAction() { + status = Status.CANCEL; + closeDialog(); + } + + public boolean isOK() { + return status == Status.OK; + } + + public boolean isError() { + return status == Status.ERROR; + } + + public boolean isCancel() { + return status == Status.CANCEL; + } + + private final class OkDialogAction extends AbstractAction implements Runnable { + + public OkDialogAction() { + super("OK"); + } + + @Override + public void actionPerformed(ActionEvent e) { + SwingUtilities.invokeLater(OkDialogAction.this); + } + + @Override + public void run() { + okAction(); + } + } + + private final class CancelDialogAction extends AbstractAction implements Runnable { + + public CancelDialogAction() { + super("Cancel"); + } + + @Override + public void actionPerformed(ActionEvent e) { + SwingUtilities.invokeLater(CancelDialogAction.this); + } + + @Override + public void run() { + cancelAction(); + } + } + + class IntFieldHandler implements PropertyChangeListener { + private IntegerField[] nHierarchyField; + private IntegerField nProcessorsField; + + public IntFieldHandler(IntegerField nProcessorsField, IntegerField[] nHierarchyField) { + this.nProcessorsField = nProcessorsField; + this.nHierarchyField = nHierarchyField; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + int np = nProcessorsField.getIntValue(); + + int[] factors = Util.getFactorsFor(np); + nHierarchyField[X].setIntValue(factors[0]); + nHierarchyField[Y].setIntValue(factors[1]); + nHierarchyField[Z].setIntValue(factors[2]); + } + } + } + + public static void main(String[] args) { + System.out.println("12 -> " + Arrays.toString(Util.getFactorsFor(12))); + System.out.println("128 -> " + Arrays.toString(Util.getFactorsFor(128))); + System.out.println("120 -> " + Arrays.toString(Util.getFactorsFor(120))); + System.out.println("512 -> " + Arrays.toString(Util.getFactorsFor(512))); + System.out.println("2 -> " + Arrays.toString(Util.getFactorsFor(2))); + System.out.println("47 -> " + Arrays.toString(Util.getFactorsFor(47))); + System.out.println("13 -> " + Arrays.toString(Util.getFactorsFor(13))); + System.out.println("1 -> " + Arrays.toString(Util.getFactorsFor(1))); + // System.out.println("0 -> "+Arrays.toString(getFactorsFor(0))); + } + + public JDialog getDialog() { + return dialog; + } +} diff --git a/src/eu/engys/gui/DefaultGUIPanel.java b/src/eu/engys/gui/DefaultGUIPanel.java new file mode 100644 index 0000000..178649d --- /dev/null +++ b/src/eu/engys/gui/DefaultGUIPanel.java @@ -0,0 +1,47 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui; + +import eu.engys.core.project.Model; +import eu.engys.gui.tree.DefaultTreeNodeManager; +import eu.engys.gui.tree.TreeNodeManager; + +public class DefaultGUIPanel extends AbstractGUIPanel { + + private DefaultTreeNodeManager treeNodeManager; + + public DefaultGUIPanel(String title, Model model) { + super(title, model); + this.treeNodeManager = new DefaultTreeNodeManager(model, this); + model.addObserver(treeNodeManager); + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } +} diff --git a/src/eu/engys/gui/GUIError.java b/src/eu/engys/gui/GUIError.java new file mode 100644 index 0000000..4b7d9cf --- /dev/null +++ b/src/eu/engys/gui/GUIError.java @@ -0,0 +1,35 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui; + +public class GUIError extends RuntimeException { + + public GUIError(String msg) { + super(msg); + } + +} diff --git a/src/eu/engys/gui/GUIPanel.java b/src/eu/engys/gui/GUIPanel.java new file mode 100644 index 0000000..4a68a7e --- /dev/null +++ b/src/eu/engys/gui/GUIPanel.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui; + +import javax.swing.JComponent; + +import eu.engys.core.modules.ModulePanel; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.gui.view3D.CanvasPanel; + +public interface GUIPanel extends ModulePanel { + + public void load(); + + public void save(); + + public void resetToDefaults(); + + public JComponent getPanel(); + + public TreeNodeManager getTreeNodeManager(); + + public void clear(); + + public String getName(); + + public String getVersion(); + + public boolean canStart(); + + public void start(); + + public boolean canStop(); + + public void stop(); + + public void layoutPanel(); + + public void install(CanvasPanel view3D); +} diff --git a/src/eu/engys/gui/GlassPane.java b/src/eu/engys/gui/GlassPane.java new file mode 100644 index 0000000..7841ba6 --- /dev/null +++ b/src/eu/engys/gui/GlassPane.java @@ -0,0 +1,78 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +import javax.swing.JPanel; + +public class GlassPane extends JPanel implements MouseListener, MouseMotionListener, MouseWheelListener { + + public GlassPane() { + super(null); + addMouseListener(this); + addMouseMotionListener(this); + addMouseWheelListener(this); + setOpaque(false); + } + + @Override + public void mouseDragged(MouseEvent e) { + } + + @Override + public void mouseMoved(MouseEvent e) { + } + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + } + + @Override + public void mouseReleased(MouseEvent e) { + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + } + +} diff --git a/src/eu/engys/gui/ListBuilderFactory.java b/src/eu/engys/gui/ListBuilderFactory.java new file mode 100644 index 0000000..77c2b5f --- /dev/null +++ b/src/eu/engys/gui/ListBuilderFactory.java @@ -0,0 +1,152 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui; + +import java.util.ArrayList; +import java.util.List; + +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.project.Model; +import eu.engys.core.project.runtimefields.RuntimeField; +import eu.engys.core.project.zero.facezones.FaceZone; +import eu.engys.core.project.zero.facezones.FaceZones; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.util.ui.ListBuilder; + +public class ListBuilderFactory { + + public static ListBuilder getPatchesListBuilder(final Model model) { + ListBuilder listBuilder = new ListBuilder() { + + @Override + public String getTitle() { + return "Select Patches"; + } + + @Override + public String[] getSourceElements() { + Patches patches = model.getPatches(); + List elements = new ArrayList<>(); + if (patches != null) { + for (Patch patch : patches.patchesToDisplay()) { + elements.add(patch.getName()); + } + } + return elements.toArray(new String[0]); + } + + @Override + public int getSelectionMode() { + return ListBuilder.MULTIPLE_SELECTION; + } + }; + return listBuilder; + } + + public static ListBuilder getFaceZonesListBuilder(final Model model) { + ListBuilder listBuilder = new ListBuilder() { + + @Override + public String getTitle() { + return "Select Face Zone"; + } + + @Override + public String[] getSourceElements() { + FaceZones faceZones = model.getFaceZones(); + List elements = new ArrayList<>(); + if (faceZones != null) { + for (FaceZone zone : faceZones) { + elements.add(zone.getName()); + } + } + return elements.toArray(new String[0]); + } + + @Override + public int getSelectionMode() { + return ListBuilder.MULTIPLE_SELECTION; + } + }; + return listBuilder; + } + + public static ListBuilder getFieldsListBuilder(final Model model) { + ListBuilder fieldsListBuilder = new ListBuilder() { + + @Override + public String getTitle() { + return "Select Fields"; + } + + @Override + public String[] getSourceElements() { + List fields = model.getFields().orderedFields(); + List runTimeFields = model.getRuntimeFields().fields(); + + List elements = new ArrayList<>(); + if (fields != null) { + for (Field f : fields) { + elements.add(f.getName()); + } + for (RuntimeField rtf : runTimeFields) { + elements.add(rtf.getName()); + } + } + return elements.toArray(new String[0]); + } + + @Override + public int getSelectionMode() { + return ListBuilder.MULTIPLE_SELECTION; + } + }; + return fieldsListBuilder; + } + + public static ListBuilder getAdvancedMeshPatchesListBuilder(final Model model, final String title) { + ListBuilder listBuilder = new ListBuilder() { + + @Override + public String getTitle() { + return title; + } + + @Override + public String[] getSourceElements() { + return new GeometryToMesh(model).listPatches(); + } + + @Override + public int getSelectionMode() { + return ListBuilder.MULTIPLE_SELECTION; + } + }; + return listBuilder; + } +} diff --git a/src/eu/engys/gui/MenuBar.java b/src/eu/engys/gui/MenuBar.java new file mode 100644 index 0000000..976a010 --- /dev/null +++ b/src/eu/engys/gui/MenuBar.java @@ -0,0 +1,167 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui; + +import java.awt.event.ActionEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.comparator.NameFileComparator; +import org.apache.commons.io.filefilter.FileFilterUtils; +import org.apache.commons.io.filefilter.IOFileFilter; + +import eu.engys.core.executor.FileManagerSupport; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.gui.RecentItems.RecentItemsObserver; +import eu.engys.gui.view.View; +import eu.engys.launcher.StartUpMonitor; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.ResourcesUtil; + +public class MenuBar extends JMenuBar implements RecentItemsObserver { + + public static final Icon OPEN_ICON = ResourcesUtil.getIcon("application.open.icon"); + public static final Icon FILE_ICON = ResourcesUtil.getIcon("file"); + + private JMenu fileMenu; + private JMenu editMenu; + // private JMenu dictionariesMenu; + private JMenu helpMenu; + // private JMenu viewMenu; + private JMenu recentCasesMenu; + + private View view; + + public MenuBar(View view) { + super(); + this.view = view; + StartUpMonitor.info("Loading Menu Bar"); + fileMenu = new JMenu("File"); + fileMenu.add(ActionManager.getInstance().get("application.create")); + fileMenu.add(ActionManager.getInstance().get("application.open")); + + recentCasesMenu = new JMenu("Open Recent"); + recentCasesMenu.setIcon(OPEN_ICON); + fileMenu.add(recentCasesMenu); + + fileMenu.add(ActionManager.getInstance().get("application.save")); + fileMenu.add(ActionManager.getInstance().get("application.saveAs")); + fileMenu.addSeparator(); + fileMenu.add(ActionManager.getInstance().get("application.exit")); + + editMenu = new JMenu("Edit"); + editMenu.setName("Application Edit"); + + // dictionariesMenu = new JMenu("Dictionaries"); + + helpMenu = new JMenu("Help"); + + add(fileMenu); + add(editMenu); + // add(dictionariesMenu); + add(helpMenu); + + RecentItems.getInstance().addObserver(this); + } + + public JMenu getFileMenu() { + return fileMenu; + } + + public JMenu getEditMenu() { + return editMenu; + } + + public JMenu getHelpMenu() { + return helpMenu; + } + + @Override + public void onRecentItemChange(RecentItems src) { + recentCasesMenu.removeAll(); + List items = RecentItems.getInstance().getItems(); + if (items.isEmpty()) { + JMenuItem menuItem = new JMenuItem(RecentItems.NO_ITEMS); + menuItem.setEnabled(false); + recentCasesMenu.add(menuItem); + } else { + Icon CASE_ICON = ResourcesUtil.getIcon(ApplicationInfo.getVendor().toLowerCase() + ".case"); + for (final String item : items) { + recentCasesMenu.add(new AbstractAction(item, CASE_ICON) { + @Override + public void actionPerformed(ActionEvent e) { + if (view.getController().allowActionsOnRunning(false)) { + view.getController().openCase(new File(item)); + } + } + }); + } + recentCasesMenu.addSeparator(); + recentCasesMenu.add(new AbstractAction("Clear") { + @Override + public void actionPerformed(ActionEvent e) { + RecentItems.getInstance().clear(); + } + }); + } + } + + public void updateDictionariesList(final Model model) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + // dictionariesMenu.removeAll(); + if (model.hasProject()) { + File baseDir = model.getProject().getBaseDir(); + IOFileFilter fileFilter = FileFilterUtils.or(FileFilterUtils.suffixFileFilter("Dict"), FileFilterUtils.suffixFileFilter("Properties"), FileFilterUtils.prefixFileFilter("fv")); + List files = new ArrayList(FileUtils.listFiles(baseDir, fileFilter, FileFilterUtils.directoryFileFilter())); + Collections.sort(files, NameFileComparator.NAME_INSENSITIVE_COMPARATOR); + for (final File file : files) { + JMenuItem menuItem = new JMenuItem(new AbstractAction(file.getName(), FILE_ICON) { + @Override + public void actionPerformed(ActionEvent e) { + FileManagerSupport.open(file); + } + }); + menuItem.setToolTipText(file.getAbsolutePath()); + // dictionariesMenu.add(menuItem); + } + } + } + }); + } +} diff --git a/src/eu/engys/gui/ModelObserver.java b/src/eu/engys/gui/ModelObserver.java new file mode 100644 index 0000000..284b788 --- /dev/null +++ b/src/eu/engys/gui/ModelObserver.java @@ -0,0 +1,47 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui; + +public interface ModelObserver { + + void fieldManipulationFunctionObjectsChanged(); + + void monitoringFunctionObjectsChanged(); + + void stateChanged(); + + void fieldsChanged(); + + void runtimeFieldsChanged(); + + void solverChanged(); + + void materialsChanged(); + + void projectChanged(); + + String getTitle(); +} diff --git a/src/eu/engys/gui/PreferencesDialog.java b/src/eu/engys/gui/PreferencesDialog.java new file mode 100644 index 0000000..6127ddd --- /dev/null +++ b/src/eu/engys/gui/PreferencesDialog.java @@ -0,0 +1,595 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui; + +import static eu.engys.util.ui.ComponentsFactory.checkField; +import static eu.engys.util.ui.ComponentsFactory.intField; +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog.ModalityType; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import net.java.dev.designgridlayout.Componentizer; + +import org.apache.commons.io.FileUtils; + +import eu.engys.core.OpenFOAMEnvironment; +import eu.engys.core.executor.FileManagerSupport; +import eu.engys.core.project.defaults.DictDataFolder; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.FileFieldPanel; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; +import eu.engys.util.ui.textfields.StringField; + +public class PreferencesDialog { + + private static final String DEFAULT_DICTIONARIES_LABEL = "Default Dictionaries"; + public static final String ERROR_LABEL_TEXT = "* the file no longer exist"; + private static final String PREFIX_FOR_TOOLTIP = "Full Installation Path, "; + private static final String OPENFOAM_TOOLTIP_LINUX = "e.g. /%s/OpenFOAM-x.x_engysEdition-x.x"; + private static final String OPENFOAM_TOOLTIP_WINDOWS = "e.g. \\%s\\OpenFOAM-x.x_engysEdition-x.x"; + private static final String OPENFOAM_TOOLTIP_LINUX_OS = "e.g. /%s/OpenFOAM-x.x.x"; + private static final String OPENFOAM_TOOLTIP_WINDOWS_OS = "e.g. \\%s\\OpenFOAM-x.x.x"; + private static final String PARAVIEW_TOOLTIP_LINUX = "e.g. /ParaView x.x.x/bin/paraview"; + private static final String PARAVIEW_TOOLTIP_WINDOWS = "e.g. \\ParaView x.x.x\\bin\\paraview.exe"; + private static final String FIELDVIEW_TOOLTIP_LINUX = "e.g. /fv/bin/fv"; + private static final String FIELDVIEW_TOOLTIP_WINDOWS = "e.g. \\Intelligent Light\\FVWINxx\\bin\\fv.bat"; + private static final String ENSIGHT_TOOLTIP_LINUX = "e.g. /CEI/bin/ensight100"; + private static final String ENSIGHT_TOOLTIP_WINDOWS = "e.g. \\CEI\\bin\\ensight100.bat"; + + private static final String TERMINAL_TOOLTIP = "Override system terminal, e.g. 'xterm'"; + private static final String FILE_MANAGER_TOOLTIP = "Override system file manager, e.g. 'nautilus'"; + private static final String DEFAULT_HOSTFILE_TOOLTIP = "Turn on/off the default hostfile (needs restart)"; + // private static final String FILE_OPENER_TOOLTIP = + // "Override system file opener, e.g. 'gnome-open'"; + + /* + * Labels + */ + + private static final String PATHS_LABEL = "Paths"; + public static final String CORE_FOLDER_LABEL = "Core Folder"; + public static final String PARA_VIEW_EXECUTABLE_LABEL = "ParaView Executable"; + public static final String FIELD_VIEW_EXECUTABLE_LABEL = "FieldView Executable"; + public static final String EN_SIGHT_EXECUTABLE_LABEL = "EnSight Executable"; + + private static final String SERVER_LABEL = "Server"; + // public static final String OUTPUT_LOG_WAIT_TIME_LABEL = "Output Log Wait Time"; + public static final String KILL_WAIT_TIME_LABEL = "Kill Wait Time"; + public static final String OUTPUT_LOG_REFRESH_INTERVAL_LABEL = "Output Log Refresh Interval"; + public static final String RUN_WAIT_TIME_LABEL = "Run Wait time"; + // public static final String STOP_WAIT_TIME_LABEL = "Stop Wait Time"; + public static final String CONNECTION_TRIES_INTERVAL_MSEC_LABEL = "Connection Tries Interval [msec]"; + public static final String CONNECTION_TRIES_LABEL = "Connection Tries"; + + private static final String _3D_RENDERING_LABEL = "3D Rendering"; + public static final String ENABLE_LOD_THRESHOLD_KB_LABEL = "Enable LOD Threshold [KB]"; + public static final String LOCK_INTERACTIVE_RENDER_FOR_MSEC_LABEL = "Lock Interactive Render For [msec]"; + public static final String DISBLE_TRANSPARENCY_THRESHOLD_KB_LABEL = "Disable Transparency Threshold [KB]"; + + private static final String MISC_LABEL = "Misc"; + public static final String MAX_LOG_LINES_LABEL = "Max Log Lines"; + // public static final String MAX_CHART_LINES_LABEL = "Max Chart Lines"; + public static final String HIDE_EMPTY_PATCHES_LABEL = "Hide Empty Patches"; + public static final String CUSTOM_FILE_MANAGER_LABEL = "Custom File Manager"; + public static final String CUSTOM_TERMINAL_COMMAND_LABEL = "Custom Terminal Command"; + public static final String DEFAULT_HOSTFILE_NONE_LABEL = "Default Hostfile Off (needs restart)"; + + private JDialog dialog; + private FileFieldPanel fieldViewPanel; + private FileFieldPanel ensightPanel; + private FileFieldPanel paraViewPanel; + private FileFieldPanel openFoamPanel; + + private IntegerField connectionTries; + private IntegerField connectionRefresh; + private IntegerField waitForStopTime; + private IntegerField waitForRunTime; + private IntegerField scriptRefresh; + private IntegerField waiForKillTime; + private IntegerField logWaitTime; + + private IntegerField interactiveMemory; + private IntegerField interactiveTime; + private IntegerField transparencyMemory; + + private StringField defaultTerminal; + private StringField defaultFileManager; + private StringField defaultFileOpener; + private JCheckBox defaultHostFile; + + private JCheckBox hideEmptyPatches; + + private IntegerField maxChartRows; + private IntegerField maxLogRows; + + private final boolean isOS; + private final boolean paraview; + private final boolean fieldview; + private final boolean ensight; + private final boolean hasSolverPreferences; + + private JLabel errorLabel; + private JButton okButton; + private JButton openDefaults; + private DictDataFolder dictDataFolder; + + public PreferencesDialog(boolean isOS, boolean paraview, boolean fieldview, boolean ensight, boolean hasSolverPreferences, DictDataFolder dictDataFolder) { + this.isOS = isOS; + this.paraview = paraview;// HELYX-OS or Windows OS + this.fieldview = fieldview;// HELYX-SAS and HELYX + this.ensight = ensight;// HELYX + this.hasSolverPreferences = hasSolverPreferences; + this.dictDataFolder = dictDataFolder; + + initDialog(); + load(); + } + + private void initDialog() { + JScrollPane scrollPane = new JScrollPane(createCenterPanel()); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + scrollPane.getVerticalScrollBar().setUnitIncrement(20); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(scrollPane, BorderLayout.CENTER); + mainPanel.add(createButtonsPanel(), BorderLayout.SOUTH); + + dialog = new JDialog(UiUtil.getActiveWindow(), "Preferences", ModalityType.APPLICATION_MODAL); + dialog.getContentPane().setLayout(new BorderLayout()); + dialog.getContentPane().add(mainPanel); + dialog.setSize(800, 600); + dialog.setLocationRelativeTo(null); + dialog.setName("PreferencesDialog"); + dialog.getRootPane().setDefaultButton(okButton); + } + + private JPanel createButtonsPanel() { + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + okButton = new JButton(new AbstractAction("OK") { + @Override + public void actionPerformed(ActionEvent e) { + save(); + dialog.setVisible(false); + } + }); + okButton.setName("OK"); + JButton cancelButton = new JButton(new AbstractAction("Cancel") { + @Override + public void actionPerformed(ActionEvent e) { + dialog.setVisible(false); + } + }); + cancelButton.setName("Cancel"); + + buttonsPanel.add(okButton); + buttonsPanel.add(cancelButton); + return buttonsPanel; + } + + /* + * Load + */ + + public void load() { + loadPathProperties(); + loadBatchProperties(); + loadVTKProperties(); + loadMiscProperties(); + + } + + private void loadPathProperties() { + openFoamPanel.setFile(PrefUtil.getOpenFoamEntry()); + if (paraview) { + paraViewPanel.setFile(PrefUtil.getParaViewEntry()); + } + if (fieldview) { + fieldViewPanel.setFile(PrefUtil.getFieldViewEntry()); + } + if (ensight) { + ensightPanel.setFile(PrefUtil.getEnsightEntry()); + } + + updateErrorLabel(); + } + + private void updateErrorLabel() { + boolean coreOk = openFoamPanel.hasExistingFile(); + if (!coreOk || !isParaViewOk() || !isFieldViewOk() || !isEnsightOk()) { + errorLabel.setText(ERROR_LABEL_TEXT); + } else { + errorLabel.setText(""); + } + } + + private void loadBatchProperties() { + connectionTries.setIntValue(PrefUtil.getInt(PrefUtil.SERVER_CONNECTION_MAX_TRIES)); + connectionRefresh.setIntValue(PrefUtil.getInt(PrefUtil.SERVER_CONNECTION_REFRESH_TIME)); + waitForRunTime.setIntValue(PrefUtil.getInt(PrefUtil.SERVER_WAIT_FOR_RUN_REFRESH_TIME)); + scriptRefresh.setIntValue(PrefUtil.getInt(PrefUtil.SCRIPT_RUN_REFRESH_TIME)); + waiForKillTime.setIntValue(PrefUtil.getInt(PrefUtil.SCRIPT_WAIT_FOR_KILL_REFRESH_TIME)); + } + + private void loadVTKProperties() { + interactiveMemory.setIntValue(PrefUtil.getInt(PrefUtil._3D_LOCK_INTRACTIVE_MEMORY)); + interactiveTime.setIntValue(PrefUtil.getInt(PrefUtil._3D_LOCK_INTRACTIVE_TIME)); + transparencyMemory.setIntValue(PrefUtil.getInt(PrefUtil._3D_TRANSPARENCY_MEMORY)); + } + + private void loadMiscProperties() { + if (Util.isUnix()) { + defaultTerminal.setStringValue(PrefUtil.getString(PrefUtil.HELYX_DEFAULT_TERMINAL)); + defaultFileManager.setStringValue(PrefUtil.getString(PrefUtil.HELYX_DEFAULT_FILE_MANAGER)); + defaultHostFile.setSelected(PrefUtil.getBoolean(PrefUtil.DEFAULT_HOSTFILE_NONE)); + } + hideEmptyPatches.setSelected(PrefUtil.getBoolean(PrefUtil.HIDE_EMPTY_PATCHES)); + maxLogRows.setIntValue(PrefUtil.getInt(PrefUtil.BATCH_MONITOR_DIALOG_MAX_ROW)); + } + + /* + * Save + */ + + // public for test purposes only + public void save() { + savePathProperties(); + saveBatchProperties(); + saveVTKProperties(); + saveMiscProperties(); + } + + private void savePathProperties() { + PrefUtil.setOpenFoamEntry(openFoamPanel.getFile()); + if (paraview) { + PrefUtil.setParaViewEntry(paraViewPanel.getFile()); + } + if (fieldview) { + PrefUtil.setFieldViewEntry(fieldViewPanel.getFile()); + } + if (ensight) { + PrefUtil.setEnsightEntry(ensightPanel.getFile()); + } + } + + private void saveBatchProperties() { + PrefUtil.putInt(PrefUtil.SERVER_CONNECTION_MAX_TRIES, connectionTries.getIntValue()); + PrefUtil.putInt(PrefUtil.SERVER_CONNECTION_REFRESH_TIME, connectionRefresh.getIntValue()); + PrefUtil.putInt(PrefUtil.SERVER_WAIT_FOR_RUN_REFRESH_TIME, waitForRunTime.getIntValue()); + + PrefUtil.putInt(PrefUtil.SCRIPT_RUN_REFRESH_TIME, scriptRefresh.getIntValue()); + PrefUtil.putInt(PrefUtil.SCRIPT_WAIT_FOR_KILL_REFRESH_TIME, waiForKillTime.getIntValue()); + } + + private void saveVTKProperties() { + PrefUtil.putInt(PrefUtil._3D_LOCK_INTRACTIVE_MEMORY, interactiveMemory.getIntValue()); + PrefUtil.putInt(PrefUtil._3D_LOCK_INTRACTIVE_TIME, interactiveTime.getIntValue()); + PrefUtil.putInt(PrefUtil._3D_TRANSPARENCY_MEMORY, transparencyMemory.getIntValue()); + } + + private void saveMiscProperties() { + if (Util.isUnix()) { + PrefUtil.putString(PrefUtil.HELYX_DEFAULT_TERMINAL, defaultTerminal.getStringValue()); + PrefUtil.putString(PrefUtil.HELYX_DEFAULT_FILE_MANAGER, defaultFileManager.getStringValue()); + PrefUtil.putBoolean(PrefUtil.DEFAULT_HOSTFILE_NONE, defaultHostFile.isSelected()); + } + PrefUtil.putBoolean(PrefUtil.HIDE_EMPTY_PATCHES, hideEmptyPatches.isSelected()); + PrefUtil.putInt(PrefUtil.BATCH_MONITOR_DIALOG_MAX_ROW, maxLogRows.getIntValue()); + } + + /* + * Layout + */ + + private Component createCenterPanel() { + JPanel pathsPanel = createPathsPanel(); + JPanel batchPanel = createBatchPanel(); + JPanel vtkPanel = createVTKPanel(); + JPanel miscPanel = createMiscPanel(); + + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(pathsPanel); + if (hasSolverPreferences) { + builder.addComponent(batchPanel); + } + builder.addComponent(vtkPanel); + builder.addComponent(miscPanel); + + JPanel container = new JPanel(new BorderLayout()); + container.setOpaque(false); + container.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + container.add(builder.getPanel(), BorderLayout.CENTER); + container.add(errorLabel = new JLabel(""), BorderLayout.SOUTH); + errorLabel.setForeground(Color.RED.darker()); + errorLabel.setName("error.label"); + return container; + } + + private JPanel createPathsPanel() { + String ofPrompt = ""; + if (Util.isWindows()) { + if (isOS) { + ofPrompt = String.format(OPENFOAM_TOOLTIP_WINDOWS_OS, ApplicationInfo.getVendor()); + } else { + ofPrompt = String.format(OPENFOAM_TOOLTIP_WINDOWS, ApplicationInfo.getVendor()); + } + } else { + if (isOS) { + ofPrompt = String.format(OPENFOAM_TOOLTIP_LINUX_OS, ApplicationInfo.getVendor()); + } else { + ofPrompt = String.format(OPENFOAM_TOOLTIP_LINUX, ApplicationInfo.getVendor()); + } + } + + String ofTooltip = PREFIX_FOR_TOOLTIP + ofPrompt; + + PanelBuilder pathBuilder = new PanelBuilder(); + addResettableComponent(pathBuilder, CORE_FOLDER_LABEL, openFoamPanel = ComponentsFactory.fileField(SelectionMode.DIRS_ONLY, ofTooltip, ofPrompt, true), PrefUtil.OPENFOAM_KEY); + openFoamPanel.addPropertyChangeListener(new UpdateErrorLabelListener()); + + if (paraview) { + String pvPrompt = Util.isWindows() ? PARAVIEW_TOOLTIP_WINDOWS : PARAVIEW_TOOLTIP_LINUX; + String pvTooltip = PREFIX_FOR_TOOLTIP + pvPrompt; + + paraViewPanel = ComponentsFactory.fileField(SelectionMode.FILES_ONLY, pvTooltip, pvPrompt, true); + paraViewPanel.addPropertyChangeListener(new UpdateErrorLabelListener()); + addResettableComponent(pathBuilder, PARA_VIEW_EXECUTABLE_LABEL, paraViewPanel, PrefUtil.PARAVIEW_KEY); + } + + if (fieldview) { + String fvPrompt = Util.isWindows() ? FIELDVIEW_TOOLTIP_WINDOWS : FIELDVIEW_TOOLTIP_LINUX; + String fvTooltip = PREFIX_FOR_TOOLTIP + fvPrompt; + + fieldViewPanel = ComponentsFactory.fileField(SelectionMode.FILES_ONLY, fvTooltip, fvPrompt, true); + fieldViewPanel.addPropertyChangeListener(new UpdateErrorLabelListener()); + addResettableComponent(pathBuilder, FIELD_VIEW_EXECUTABLE_LABEL, fieldViewPanel, PrefUtil.FIELDVIEW_KEY); + } + if (ensight) { + String fvPrompt = Util.isWindows() ? ENSIGHT_TOOLTIP_WINDOWS : ENSIGHT_TOOLTIP_LINUX; + String fvTooltip = PREFIX_FOR_TOOLTIP + fvPrompt; + + ensightPanel = ComponentsFactory.fileField(SelectionMode.FILES_ONLY, fvTooltip, fvPrompt, true); + ensightPanel.addPropertyChangeListener(new UpdateErrorLabelListener()); + addResettableComponent(pathBuilder, EN_SIGHT_EXECUTABLE_LABEL, ensightPanel, PrefUtil.ENSIGHT_KEY); + } + JPanel panel = pathBuilder.getPanel(); + panel.setBorder(BorderFactory.createTitledBorder(PATHS_LABEL)); + return panel; + } + + private JPanel createBatchPanel() { + PanelBuilder batchBuilder = new PanelBuilder(); + addResettableComponent(batchBuilder, CONNECTION_TRIES_LABEL, connectionTries = intField(), PrefUtil.SERVER_CONNECTION_MAX_TRIES); + addResettableComponent(batchBuilder, CONNECTION_TRIES_INTERVAL_MSEC_LABEL, connectionRefresh = intField(), PrefUtil.SERVER_CONNECTION_REFRESH_TIME); + addResettableComponent(batchBuilder, RUN_WAIT_TIME_LABEL, waitForRunTime = intField(), PrefUtil.SERVER_WAIT_FOR_RUN_REFRESH_TIME); + addResettableComponent(batchBuilder, OUTPUT_LOG_REFRESH_INTERVAL_LABEL, scriptRefresh = intField(), PrefUtil.SCRIPT_RUN_REFRESH_TIME); + addResettableComponent(batchBuilder, KILL_WAIT_TIME_LABEL, waiForKillTime = intField(), PrefUtil.SCRIPT_WAIT_FOR_KILL_REFRESH_TIME); + batchBuilder.getPanel().setBorder(BorderFactory.createTitledBorder(SERVER_LABEL)); + return batchBuilder.getPanel(); + } + + private JPanel createVTKPanel() { + PanelBuilder vtkBuilder = new PanelBuilder(); + addResettableComponent(vtkBuilder, LOCK_INTERACTIVE_RENDER_FOR_MSEC_LABEL, interactiveTime = intField(), PrefUtil._3D_LOCK_INTRACTIVE_TIME); + addResettableComponent(vtkBuilder, ENABLE_LOD_THRESHOLD_KB_LABEL, interactiveMemory = intField(), PrefUtil._3D_LOCK_INTRACTIVE_MEMORY); + addResettableComponent(vtkBuilder, DISBLE_TRANSPARENCY_THRESHOLD_KB_LABEL, transparencyMemory = intField(), PrefUtil._3D_TRANSPARENCY_MEMORY); + vtkBuilder.getPanel().setBorder(BorderFactory.createTitledBorder(_3D_RENDERING_LABEL)); + return vtkBuilder.getPanel(); + } + + private JPanel createMiscPanel() { + PanelBuilder miscBuilder = new PanelBuilder(); + if (Util.isUnix()) { + addResettableComponent(miscBuilder, CUSTOM_TERMINAL_COMMAND_LABEL, defaultTerminal = stringField(), PrefUtil.HELYX_DEFAULT_TERMINAL); + defaultTerminal.setPrompt(TERMINAL_TOOLTIP); + + addResettableComponent(miscBuilder, CUSTOM_FILE_MANAGER_LABEL, defaultFileManager = stringField(), PrefUtil.HELYX_DEFAULT_FILE_MANAGER); + defaultFileManager.setPrompt(FILE_MANAGER_TOOLTIP); + + addResettableComponent(miscBuilder, DEFAULT_HOSTFILE_NONE_LABEL, defaultHostFile = checkField(), PrefUtil.DEFAULT_HOSTFILE_NONE); + defaultHostFile.setToolTipText(DEFAULT_HOSTFILE_TOOLTIP); + } + addResettableComponent(miscBuilder, HIDE_EMPTY_PATCHES_LABEL, hideEmptyPatches = checkField(), PrefUtil.HIDE_EMPTY_PATCHES); + addResettableComponent(miscBuilder, MAX_LOG_LINES_LABEL, maxLogRows = intField(), PrefUtil.BATCH_MONITOR_DIALOG_MAX_ROW); + + openDefaults = new JButton(new AbstractAction("Show Files") { + @Override + public void actionPerformed(ActionEvent e) { + if (dictDataFolder.toFile() != null && dictDataFolder.toFile().exists()) { + FileManagerSupport.open(dictDataFolder.toFile()); + } + } + }); + JButton resetButton = new JButton(new ViewAction("Reset", "Reset Files To Default") { + @Override + public void actionPerformed(ActionEvent e) { + try { + FileUtils.forceDeleteOnExit(new File(ApplicationInfo.getHome(), "dictData")); + } catch (IOException e1) { + } finally { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Restart " + ApplicationInfo.getName() + " to complete this action."); + } + } + }); + miscBuilder.addComponent(DEFAULT_DICTIONARIES_LABEL, Componentizer.create().minAndMore(openDefaults).minToPref(resetButton).component()); + + miscBuilder.getPanel().setBorder(BorderFactory.createTitledBorder(MISC_LABEL)); + return miscBuilder.getPanel(); + } + + private void addResettableComponent(PanelBuilder builder, String label, JComponent compToAdd, String prefKey) { + JButton resetButton = createResetButton(compToAdd, prefKey); + resetButton.setName(label + ".reset"); + compToAdd.setName(label); + builder.addComponent(label, Componentizer.create().minAndMore(compToAdd).minToPref(resetButton).component()); + } + + private JButton createResetButton(final JComponent compToAdd, final String key) { + return new JButton(new ViewAction("Reset", "Reset Preference To Default") { + + @Override + public void actionPerformed(ActionEvent e) { + Object value = PrefUtil.getDefaultValue(key); + if (compToAdd instanceof IntegerField) { + resetIntegerField(compToAdd, value); + } else if (compToAdd instanceof StringField) { + resetStringField(compToAdd, value); + } else if (compToAdd instanceof JCheckBox) { + resetBooleanField(compToAdd, value); + } else if (compToAdd instanceof DoubleField) { + resetDoubleField(compToAdd, value); + } else if (compToAdd instanceof FileFieldPanel) { + if(key.equals(PrefUtil.OPENFOAM_KEY)){ + resetOpenFoamFileField(compToAdd); + } else { + resetFileField(compToAdd); + } + } + } + + private void resetFileField(final JComponent compToAdd) { + ((FileFieldPanel) compToAdd).setFile(null); + } + + private void resetOpenFoamFileField(final JComponent compToAdd) { + File[] openFoamDir = OpenFOAMEnvironment.getOpenFoamDir(); + if (Util.isVarArgsNotNullAndOfSize(1, openFoamDir)) { + ((FileFieldPanel) compToAdd).setFile(openFoamDir[0]); + } else { + ((FileFieldPanel) compToAdd).setFile(null); + } + } + + private void resetDoubleField(final JComponent compToAdd, Object value) { + if (value == null) { + ((DoubleField) compToAdd).setDoubleValue(0); + } else { + double doubleValue = Double.parseDouble(String.valueOf(value)); + ((DoubleField) compToAdd).setDoubleValue(doubleValue); + } + } + + private void resetBooleanField(final JComponent compToAdd, Object value) { + if (value == null) { + ((JCheckBox) compToAdd).setSelected(false); + } else { + boolean booleanValue = Boolean.valueOf(String.valueOf(value)); + ((JCheckBox) compToAdd).setSelected(booleanValue); + } + } + + private void resetStringField(final JComponent compToAdd, Object value) { + if (value == null) { + ((StringField) compToAdd).setStringValue(""); + } else { + String stringValue = String.valueOf(value); + ((StringField) compToAdd).setStringValue(stringValue); + } + } + + private void resetIntegerField(final JComponent compToAdd, Object value) { + if (value == null) { + ((IntegerField) compToAdd).setIntValue(0); + } else { + int intValue = Integer.parseInt(String.valueOf(value)); + ((IntegerField) compToAdd).setIntValue(intValue); + } + } + }); + } + + /* + * Utils + */ + + private boolean isParaViewOk() { + if (paraview) { + return paraViewPanel.hasExistingFile(); + } + return true; + } + + private boolean isEnsightOk() { + if (ensight) { + return ensightPanel.hasExistingFile(); + } + return true; + } + + private boolean isFieldViewOk() { + if (fieldview) { + return fieldViewPanel.hasExistingFile(); + } + return true; + } + + public void show() { + dialog.setVisible(true); + } + + private class UpdateErrorLabelListener implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + updateErrorLabel(); + } + } + + } + + // For test purpose only + public JDialog getDialog() { + return dialog; + } +} diff --git a/src/eu/engys/gui/RecentItems.java b/src/eu/engys/gui/RecentItems.java new file mode 100644 index 0000000..7ff76ce --- /dev/null +++ b/src/eu/engys/gui/RecentItems.java @@ -0,0 +1,129 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ +package eu.engys.gui; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; + +import eu.engys.util.PrefUtil; + +public class RecentItems { + + public interface RecentItemsObserver { + void onRecentItemChange(RecentItems src); + } + + public final static String RECENT_ITEM_STRING = "recent.item."; + + static final int MAX_ITEMS = 5; + + public static final String NO_ITEMS = "No recent files"; + + private List items = new ArrayList<>(); + private List m_observers = new ArrayList(); + + private static RecentItems instance; + + public static RecentItems getInstance() { + if (instance == null) { + instance = new RecentItems(); + } + return instance; + } + + public RecentItems() { + loadFromPreferences(); + } + + public void push(File item) { + items.remove(item.getAbsolutePath()); + items.add(0, item.getAbsolutePath()); + + if (items.size() > MAX_ITEMS) { + items.remove(items.size() - 1); + } + + update(); + storeToPreferences(); + } + + public void remove(Object item) { + items.remove(item); + update(); + storeToPreferences(); + } + + public List getItems() { + return items; + } + + public int size() { + return items.size(); + } + + public void addObserver(RecentItemsObserver observer) { + m_observers.add(observer); + update(); + } + + public void removeObserver(RecentItemsObserver observer) { + m_observers.remove(observer); + } + + private void update() { + for (RecentItemsObserver observer : m_observers) { + observer.onRecentItemChange(this); + } + } + + void loadFromPreferences() { + // load recent files from properties + String recentItems = PrefUtil.getString(PrefUtil.RECENT_PROJECTS, ""); + for (String item : recentItems.split(File.pathSeparator)) { + File file = new File(item); + if (file.exists()) { + items.add(item); + } + } + } + + void storeToPreferences() { + List list = new ArrayList<>(); + for (int i = 0; i < MAX_ITEMS; i++) { + if (i < items.size()) { + list.add(items.get(i)); + } + } + PrefUtil.putString(PrefUtil.RECENT_PROJECTS, StringUtils.join(list, File.pathSeparator)); + } + + public void clear() { + items.clear(); + storeToPreferences(); + } +} diff --git a/src/eu/engys/gui/StandardScriptFactory.java b/src/eu/engys/gui/StandardScriptFactory.java new file mode 100644 index 0000000..75d3409 --- /dev/null +++ b/src/eu/engys/gui/StandardScriptFactory.java @@ -0,0 +1,104 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui; + +import static eu.engys.core.OpenFOAMEnvironment.loadEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.printHeader; +import static eu.engys.core.OpenFOAMEnvironment.printVariables; +import static eu.engys.util.OpenFOAMCommands.CHECK_MESH_PARALLEL; +import static eu.engys.util.OpenFOAMCommands.CHECK_MESH_SERIAL; +import static eu.engys.util.OpenFOAMCommands.SET_FIELDS_PARALLEL; +import static eu.engys.util.OpenFOAMCommands.SET_FIELDS_SERIAL; + +import java.util.List; + +import javax.inject.Inject; + +import eu.engys.core.controller.DefaultScriptFactory; +import eu.engys.core.controller.ScriptBuilder; +import eu.engys.core.project.Model; + +public class StandardScriptFactory extends DefaultScriptFactory { + + @Inject + public StandardScriptFactory(Model model) { + super(model); + } + + protected boolean performBlockMesh() { + return true; + } + + @Override + protected List getSerialCheckMeshScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, CHECK_MESH); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(CHECK_MESH_SERIAL()); + sb.newLine(); + return sb.getLines(); + } + + @Override + protected List getParallelCheckMeshScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, CHECK_MESH); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(CHECK_MESH_PARALLEL()); + sb.newLine(); + return sb.getLines(); + } + + @Override + protected List getSerialInitialiseScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, INITIALISE_FIELDS.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(SET_FIELDS_SERIAL()); + sb.newLine(); + return sb.getLines(); + } + + @Override + protected List getParallelInitialiseScript() { + ScriptBuilder sb = new ScriptBuilder(); + printHeader(sb, INITIALISE_FIELDS.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + sb.newLine(); + sb.append(SET_FIELDS_PARALLEL()); + sb.newLine(); + return sb.getLines(); + } + +} diff --git a/src/eu/engys/gui/StartPanel.java b/src/eu/engys/gui/StartPanel.java new file mode 100644 index 0000000..c8064fd --- /dev/null +++ b/src/eu/engys/gui/StartPanel.java @@ -0,0 +1,214 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import eu.engys.application.Application; +import eu.engys.core.presentation.ActionManager; +import eu.engys.gui.view.View; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; + +public class StartPanel extends JPanel { + + private static final String DEMO_START = "Go under Help > License Manager to provide a valid license."; + + private List actions; + private Application application; + private View view; + + public StartPanel(Application application, View view) { + super(new BorderLayout()); + this.application = application; + this.view = view; + this.actions = createActions(); + layoutComponents(); + setBorder(BorderFactory.createEmptyBorder(10, 25, 10, 25)); + } + + private List createActions() { + List actions = new ArrayList(); + + actions.add(ActionManager.getInstance().get("application.create")); + actions.add(ActionManager.getInstance().get("application.open")); + actions.add(ActionManager.getInstance().get("application.exit")); + + return actions; + } + + private void layoutComponents() { + JPanel topPanel = new JPanel(new BorderLayout()); + JPanel bottomPanel = new JPanel(new BorderLayout()); + + topPanel.add(createBannerPanel(), BorderLayout.NORTH); + topPanel.add(application.createAdPanel(), BorderLayout.CENTER); + + bottomPanel.add(createProjectActionsPanel(), BorderLayout.CENTER); + bottomPanel.add(application.createVersionPanel(), BorderLayout.SOUTH); + + add(topPanel, BorderLayout.NORTH); + add(bottomPanel, BorderLayout.CENTER); + } + + private JComponent createBannerPanel() { + JLabel banner = new JLabel(application.getBannerIcon()); + return banner; + } + + protected JPanel createProjectActionsPanel() { + final ImageIcon BG_IMAGE = (ImageIcon) application.getBgIcon(); + JPanel containerPanel = new JPanel(new BorderLayout()) { + @Override + protected void paintComponent(Graphics g) { + setOpaque(false); + g.drawImage(BG_IMAGE.getImage(), (getWidth() - BG_IMAGE.getImage().getWidth(null)) - 10, getHeight() - BG_IMAGE.getImage().getHeight(null), null); + super.paintComponent(g); + } + }; + + int width = actions.size() >= 4 ? 700 : BG_IMAGE.getImage().getWidth(null); + int height = 260 * (((actions.size() - 1) / 3) + 1); + containerPanel.setPreferredSize(new Dimension(width, height)); + + JPanel buttonsPanel = createButtonsPanel(); + + JPanel recentPanel = createRecentPanel(); + + JPanel titlePanel = new JPanel(new GridBagLayout()); + titlePanel.setBorder(BorderFactory.createTitledBorder("Select an action")); + titlePanel.setOpaque(false); + titlePanel.add(buttonsPanel, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + titlePanel.add(recentPanel, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.VERTICAL, new Insets(10, 10, 10, 10), 0, 0)); + + containerPanel.add(titlePanel, BorderLayout.CENTER); + containerPanel.add(getDemoLabel(), BorderLayout.SOUTH); + return containerPanel; + } + + private JPanel createRecentPanel() { + JPanel panel = new JPanel(new BorderLayout()); + panel.setOpaque(false); + List items = RecentItems.getInstance().getItems(); + if (items.isEmpty()) { + JLabel label = new JLabel(RecentItems.NO_ITEMS); + panel.add(label); + } else { + List buttons = new ArrayList<>(); + Icon CASE_ICON = ResourcesUtil.getIcon(ApplicationInfo.getVendor().toLowerCase() + ".case"); + for (final String item : items) { + JButton button = new JButton((new AbstractAction(truncateItem(item), CASE_ICON) { + @Override + public void actionPerformed(ActionEvent e) { + if (view.getController().allowActionsOnRunning(false)) { + view.getController().openCase(new File(item)); + } + } + })); + buttons.add(button); + } + panel.add(UiUtil.getCommandColumnToolbar(buttons)); + } + + return panel; + } + + private String truncateItem(String projectName) { + int MAX_LEN = 30; + String path = projectName; + if (path.length() <= MAX_LEN) { + return path; + } else { + return "..." + path.substring(path.length() - MAX_LEN, path.length()); + } + } + + private JLabel getDemoLabel() { + String licenseErrorMessage = System.getProperty("license.error.message", null); + if (licenseErrorMessage != null && !licenseErrorMessage.isEmpty()) { + JLabel label = new JLabel("" + licenseErrorMessage + "
" + DEMO_START + ""); + label.setForeground(new Color(0xff0000)); + return label; + } else { + return new JLabel(); + } + } + + private JPanel createButtonsPanel() { + List buttons = createButtons(); + + int colNumber = 1; + int rows = ((buttons.size() - 1) / colNumber) + 1; + int cols = Math.min(buttons.size(), colNumber); + + JPanel panel = new JPanel(new GridLayout(rows, cols, 0, 10)); + panel.setOpaque(false); + + for (JButton button : buttons) { + button.setName("suite." + button.getText()); + // button.setHorizontalTextPosition(JButton.CENTER); + // button.setVerticalTextPosition(JButton.BOTTOM); + button.setFocusable(false); + panel.add(button); + } + return panel; + } + + private List createButtons() { + List buttons = new ArrayList(); + for (Action action : actions) { + final JButton button = new JButton(); + button.setAction(action); + // button.setOpaque(true); + buttons.add(button); + } + return buttons; + } + +} diff --git a/src/eu/engys/gui/casesetup/CaseSetup.java b/src/eu/engys/gui/casesetup/CaseSetup.java new file mode 100644 index 0000000..fdaf894 --- /dev/null +++ b/src/eu/engys/gui/casesetup/CaseSetup.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import com.google.inject.BindingAnnotation; + +@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME) +public @interface CaseSetup { + +} diff --git a/src/eu/engys/gui/casesetup/CaseSetup3DElement.java b/src/eu/engys/gui/casesetup/CaseSetup3DElement.java new file mode 100644 index 0000000..5e79917 --- /dev/null +++ b/src/eu/engys/gui/casesetup/CaseSetup3DElement.java @@ -0,0 +1,50 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup; + +import java.util.Set; + +import javax.inject.Inject; + +import eu.engys.gui.GUIPanel; +import eu.engys.gui.view.AbstractView3DElement; +import eu.engys.gui.view3D.CanvasPanel; + +public class CaseSetup3DElement extends AbstractView3DElement { + + @Inject + public CaseSetup3DElement(@CaseSetup Set panels) { + super(panels); + } + + @Override + public void load(CanvasPanel view3D) { + view3D.getMeshController().newContext(getClass()); + view3D.getGeometryController().newEmptyContext(getClass()); + } + +} diff --git a/src/eu/engys/gui/casesetup/CaseSetupElement.java b/src/eu/engys/gui/casesetup/CaseSetupElement.java new file mode 100644 index 0000000..fd761d3 --- /dev/null +++ b/src/eu/engys/gui/casesetup/CaseSetupElement.java @@ -0,0 +1,118 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup; + +import java.util.HashSet; +import java.util.Set; + +import javax.inject.Inject; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulePanel; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.project.Model; +import eu.engys.core.project.ProjectReader; +import eu.engys.core.project.ProjectWriter; +import eu.engys.core.project.state.State; +import eu.engys.gui.Actions; +import eu.engys.gui.GUIPanel; +import eu.engys.gui.view.AbstractViewElement; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view.ViewElementPanel; +import eu.engys.util.plaf.ILookAndFeel; + +public class CaseSetupElement extends AbstractViewElement { + + private ViewElementPanel viewElementPanel; + + @Inject + @CaseSetup + private ProjectWriter writer; + @Inject + @CaseSetup + private ProjectReader reader; + + @Inject + public CaseSetupElement(@CaseSetup String title, @CaseSetup Set panels, Set modules, @CaseSetup View3DElement view3DElement, @CaseSetup Actions actions, ILookAndFeel lookAndFeel) { + super(title, panels, modules, view3DElement, actions, lookAndFeel); + } + + @Override + public ViewElementPanel getPanel() { + return viewElementPanel; + } + + @Override + public void layoutComponents() { + viewElementPanel = new ViewElementPanel(this); + super.layoutComponents(); + } + + @Override + protected Set getModulePanels() { + Set allPanels = new HashSet(); + for (ModulePanel panel : ModulesUtil.getCaseSetupPanels(modules)) { + allPanels.add((GUIPanel) panel); + } + return allPanels; + } + + @Override + public int getPreferredWidth() { + return 700; + } + + @Override + public void start() { + super.start(); + } + + @Override + public ProjectReader getReader() { + return reader; + } + + @Override + public ProjectWriter getWriter() { + return writer; + } + + @Override + public void load(Model model) { + super.load(model); + ModulesUtil.updateTree(modules, getPanel()); + } + + @Override + public void changeObserved(Object arg) { + if (arg instanceof State) { + ModulesUtil.updateTree(modules, getPanel()); + getActions().update(); + } + super.changeObserved(arg); + } +} diff --git a/src/eu/engys/gui/casesetup/RuntimeControlsPanel.java b/src/eu/engys/gui/casesetup/RuntimeControlsPanel.java new file mode 100644 index 0000000..a44a390 --- /dev/null +++ b/src/eu/engys/gui/casesetup/RuntimeControlsPanel.java @@ -0,0 +1,346 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup; + +import static eu.engys.core.project.system.ControlDict.ADJUSTABLE_RUN_TIME_KEY; +import static eu.engys.core.project.system.ControlDict.ADJUST_TIME_STEP_KEY; +import static eu.engys.core.project.system.ControlDict.DELTA_T_KEY; +import static eu.engys.core.project.system.ControlDict.END_TIME_KEY; +import static eu.engys.core.project.system.ControlDict.FUNCTIONS_KEY; +import static eu.engys.core.project.system.ControlDict.GRAPH_FORMAT_KEY; +import static eu.engys.core.project.system.ControlDict.GRAPH_FORMAT_VALUE; +import static eu.engys.core.project.system.ControlDict.MAX_ALPHA_CO_KEY; +import static eu.engys.core.project.system.ControlDict.MAX_CO_KEY; +import static eu.engys.core.project.system.ControlDict.MAX_DELTA_T_KEY; +import static eu.engys.core.project.system.ControlDict.PURGE_WRITE_KEY; +import static eu.engys.core.project.system.ControlDict.RUN_TIME_VALUE; +import static eu.engys.core.project.system.ControlDict.START_FROM_KEY; +import static eu.engys.core.project.system.ControlDict.START_FROM_VALUES; +import static eu.engys.core.project.system.ControlDict.START_TIME_KEY; +import static eu.engys.core.project.system.ControlDict.START_TIME_VALUE; +import static eu.engys.core.project.system.ControlDict.STOP_AT_KEY; +import static eu.engys.core.project.system.ControlDict.TIME_FORMAT_KEY; +import static eu.engys.core.project.system.ControlDict.TIME_FORMAT_VALUES; +import static eu.engys.core.project.system.ControlDict.TIME_PRECISION_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_COMPRESSION_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_COMPRESSION_VALUES; +import static eu.engys.core.project.system.ControlDict.WRITE_CONTROL_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_CONTROL_VALUES; +import static eu.engys.core.project.system.ControlDict.WRITE_FORMAT_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_FORMAT_VALUES; +import static eu.engys.core.project.system.ControlDict.WRITE_INTERVAL_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_PRECISION_KEY; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.inject.Inject; +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.Solver; +import eu.engys.core.project.state.State; +import eu.engys.core.project.system.ControlDict; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.util.Symbols; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.SelectionValueConfigurator; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; + +public class RuntimeControlsPanel extends DefaultGUIPanel { + + public static final String RUNTIME_CONTROLS = "Runtime Controls"; + + public static final String DATA_WRITING_LABEL = "Data Writing"; + public static final String TIME_SETTINGS_LABEL = "Time Settings"; + public static final String GRAPH_FORMAT_LABEL = "Graph Format"; + public static final String TIME_PRECISION_LABEL = "Time Precision"; + public static final String TIME_FORMAT_LABEL = "Time Format"; + public static final String WRITE_COMPRESSION_LABEL = "Write Compression"; + public static final String WRITE_PRECISION_LABEL = "Write Precision"; + public static final String WRITE_FORMAT_LABEL = "Write Format"; + public static final String PURGE_WRITE_LABEL = "Purge Write"; + public static final String WRITE_CONTROL_LABEL = "Write Control"; + public static final String MAX_TIME_STEP_LABEL = "Max Time Step"; + public static final String MAX_COURANT_ALPHA_LABEL = "Max Courant Alpha"; + public static final String MAX_COURANT_NUMBER_LABEL = "Max Courant Number"; + public static final String ADJUSTABLE_TIME_STEP_LABEL = "Adjustable Time Step"; + public static final String DELTA_T_LABEL = Symbols.DELTA_T + "(s)"; + public static final String END_TIME_LABEL = "End Time"; + public static final String START_FROM_LABEL = "Start From"; + + // public static final String J_PLOT_LABEL = "JPlot"; + // public static final String GRACE_XMRG_LABEL = "Grace/XMRG"; + // public static final String GNU_PLOT_LABEL = "GNUPlot"; + public static final String RAW_LABEL = "Raw"; + // public static final String SCIENTIFIC_LABEL = "Scientific"; + // public static final String FIXED_LABEL = "Fixed"; + public static final String GENERAL_LABEL = "General"; + public static final String COMPRESSED_LABEL = "Compressed"; + public static final String UNCOMPRESSED_LABEL = "Uncompressed"; + // public static final String BINARY_LABEL = "Binary"; + public static final String ASCII_LABEL = "ASCII"; + public static final String CLOCK_TIME_LABEL = "Clock Time"; + public static final String CPU_TIME_LABEL = "CPU Time"; + public static final String RUN_TIME_LABEL = "Run Time"; + public static final String TIME_STEP_LABEL = "Time Step"; + public static final String START_TIME_LABEL = "Start Time"; + public static final String LATEST_TIME_LABEL = "Latest Time"; + public static final String FIRST_TIME_LABEL = "First Time"; + public static final String[] START_FROM_LABELS = { FIRST_TIME_LABEL, LATEST_TIME_LABEL, START_TIME_LABEL }; + public static final String[] WRITE_CONTROL_LABELS = { TIME_STEP_LABEL, RUN_TIME_LABEL, CPU_TIME_LABEL, CLOCK_TIME_LABEL }; + public static final String[] WRITE_FORMAT_LABELS = { ASCII_LABEL }; + // public static final String[] WRITE_FORMAT_LABELS = { ASCII_LABEL, + // BINARY_LABEL }; + public static final String[] WRITE_COMPRESSION_LABELS = { UNCOMPRESSED_LABEL, COMPRESSED_LABEL }; + public static final String[] TIME_FORMAT_LABELS = { GENERAL_LABEL }; + // public static final String[] TIME_FORMAT_LABELS = { GENERAL_LABEL, + // FIXED_LABEL, SCIENTIFIC_LABEL }; + public static final String[] GRAPH_FORMAT_LABELS = { RAW_LABEL }; + // public static final String[] GRAPH_FORMAT_LABELS = { RAW_LABEL, + // GNU_PLOT_LABEL, GRACE_XMRG_LABEL, J_PLOT_LABEL }; + + private DictionaryModel dictionaryModel; + private JCheckBox adjustableTime; + private JComponent maxCourantNumber; + private JComponent maxAlphaCourant; + private JComponent maxTimeStep; + private DoubleField deltaT; + private Solver solver = null; + + private boolean isSaving = false; + + @Inject + public RuntimeControlsPanel(Model model) { + super(RUNTIME_CONTROLS, model); + } + + @Override + public void start() { + super.start(); + updatePanel(model.getState()); + } + + protected JComponent layoutComponents() { + dictionaryModel = new DictionaryModel(new Dictionary("")); + PanelBuilder timeBuilder = new PanelBuilder(); + + JComboBox startFrom = dictionaryModel.bindSelection(START_FROM_KEY, START_FROM_VALUES, START_FROM_LABELS); + final DoubleField startTime = dictionaryModel.bindDouble(START_TIME_KEY); + DoubleField endTime = dictionaryModel.bindDouble(END_TIME_KEY); + + timeBuilder.addComponent(START_FROM_LABEL, startFrom, startTime); + timeBuilder.addComponent(END_TIME_LABEL, endTime); + + startTime.setEnabled(false); + startFrom.addPropertyChangeListener("value", new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + startTime.setEnabled(START_TIME_VALUE.equals(evt.getNewValue())); + } + }); + + deltaT = dictionaryModel.bindDouble(DELTA_T_KEY); + timeBuilder.addComponent(DELTA_T_LABEL, deltaT); + + adjustableTime = dictionaryModel.bindBoolean(ADJUST_TIME_STEP_KEY); + maxCourantNumber = dictionaryModel.bindDouble(MAX_CO_KEY); + maxAlphaCourant = dictionaryModel.bindDouble(MAX_ALPHA_CO_KEY); + maxTimeStep = dictionaryModel.bindDouble(MAX_DELTA_T_KEY); + + timeBuilder.addComponent(ADJUSTABLE_TIME_STEP_LABEL, adjustableTime); + timeBuilder.addComponent(MAX_COURANT_NUMBER_LABEL, maxCourantNumber); + timeBuilder.addComponent(MAX_COURANT_ALPHA_LABEL, maxAlphaCourant); + timeBuilder.addComponent(MAX_TIME_STEP_LABEL, maxTimeStep); + + adjustableTime.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + maxCourantNumber.setEnabled(adjustableTime.isSelected()); + maxAlphaCourant.setEnabled(adjustableTime.isSelected() && model.getState().getMultiphaseModel().isMultiphase()); + maxTimeStep.setEnabled(adjustableTime.isSelected()); + } + }); + adjustableTime.setSelected(false); + maxCourantNumber.setEnabled(false); + maxAlphaCourant.setEnabled(false); + maxTimeStep.setEnabled(false); + + PanelBuilder dataWriteBuilder = new PanelBuilder(); + SelectionValueConfigurator conf = new SelectionValueConfigurator() { + @Override + public String write(String value) { + if (value != null && value.equals(RUN_TIME_VALUE) && adjustableTime.isSelected()) + return ADJUSTABLE_RUN_TIME_KEY; + return value; + } + + @Override + public String read(String value) { + if (value != null && value.equals(ADJUSTABLE_RUN_TIME_KEY)) + return RUN_TIME_VALUE; + return value; + } + }; + dataWriteBuilder.addComponent(WRITE_CONTROL_LABEL, dictionaryModel.bindSelection(WRITE_CONTROL_KEY, WRITE_CONTROL_VALUES, WRITE_CONTROL_LABELS, conf), dictionaryModel.bindDouble(WRITE_INTERVAL_KEY)); + dataWriteBuilder.addComponent(PURGE_WRITE_LABEL, dictionaryModel.bindIntegerPositive(PURGE_WRITE_KEY)); + + JComboBox writeFormat = dictionaryModel.bindSelection(WRITE_FORMAT_KEY, WRITE_FORMAT_VALUES, WRITE_FORMAT_LABELS); + writeFormat.setEnabled(false); + dataWriteBuilder.addComponent(WRITE_FORMAT_LABEL, writeFormat); + + dataWriteBuilder.addComponent(WRITE_PRECISION_LABEL, dictionaryModel.bindIntegerPositive(WRITE_PRECISION_KEY)); + dataWriteBuilder.addComponent(WRITE_COMPRESSION_LABEL, dictionaryModel.bindSelection(WRITE_COMPRESSION_KEY, WRITE_COMPRESSION_VALUES, WRITE_COMPRESSION_LABELS)); + + JComboBox timeFormat = dictionaryModel.bindSelection(TIME_FORMAT_KEY, TIME_FORMAT_VALUES, TIME_FORMAT_LABELS); + timeFormat.setEnabled(false); + dataWriteBuilder.addComponent(TIME_FORMAT_LABEL, timeFormat); + + dataWriteBuilder.addComponent(TIME_PRECISION_LABEL, dictionaryModel.bindIntegerPositive(TIME_PRECISION_KEY)); + + JComboBox graphFormat = dictionaryModel.bindSelection(GRAPH_FORMAT_KEY, GRAPH_FORMAT_VALUE, GRAPH_FORMAT_LABELS); + graphFormat.setEnabled(false); + dataWriteBuilder.addComponent(GRAPH_FORMAT_LABEL, graphFormat); + + JPanel timePanel = timeBuilder.margins(.5, .5, .5, .5).getPanel(); + timePanel.setBorder(BorderFactory.createTitledBorder(TIME_SETTINGS_LABEL)); + timePanel.setName(TIME_SETTINGS_LABEL); + + JPanel dataWritePanel = dataWriteBuilder.margins(.5, .5, .5, .5).getPanel(); + dataWritePanel.setBorder(BorderFactory.createTitledBorder(DATA_WRITING_LABEL)); + dataWritePanel.setName(DATA_WRITING_LABEL); + + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(timePanel); + builder.addComponent(dataWritePanel); + + return builder.removeMargins().getPanel(); + } + + @Override + public void load() { + loadControlDict(); + updatePanel(model.getState()); + } + + @Override + public void save() { + ControlDict controlDict = getModel().getProject().getSystemFolder().getControlDict(); + if (controlDict != null) { + boolean changed = hasControlDictChanged(controlDict); + controlDict.merge(dictionaryModel.getDictionary()); + controlDict.add(STOP_AT_KEY, END_TIME_KEY); + if (changed) { + isSaving = true; + model.projectChanged(); + isSaving = false; + } + } + } + + private boolean hasControlDictChanged(ControlDict controlDict) { + ControlDict d = new ControlDict(controlDict); + d.remove(ControlDict.FUNCTIONS_KEY); + return !d.toString().equals(dictionaryModel.getDictionary().toString()); + } + + @Override + public void stateChanged() { + super.stateChanged(); + State state = model.getState(); + + if (this.solver == null || !(state.getSolver().equals(this.solver))) { + this.solver = state.getSolver(); + loadControlDict(); + updatePanel(state); + } else { + /* + * Entro qua se ho cambiato solo turbulence model e quindi non serve + * svrazzare via quello che ce nella GUI Il file controlDict ora + * contiene i valori di default. Lo mergio con i valori della GUI + * per non perdere i cambiamenti fatti. Ovviamente questo significa + * che quello che ce nella GUI...rimane! + */ + Dictionary controlDict = model.getProject().getSystemFolder().getControlDict(); + if (controlDict != null) { + controlDict.merge(dictionaryModel.getDictionary()); + } + } + } + + @Override + public void projectChanged() { + if (!isSaving) { + loadControlDict(); + } + } + + private void loadControlDict() { + ControlDict controlDict = model.getProject().getSystemFolder().getControlDict(); + if (controlDict != null) { + Dictionary dictionary = new Dictionary(controlDict); + dictionary.remove(FUNCTIONS_KEY); + dictionaryModel.setDictionary(dictionary); + } + } + + private void updatePanel(final State state) { + this.solver = state.getSolver(); + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + boolean isTransient = state.isTransient(); + boolean isSteadyMultiphase = state.isSteady() && state.getMultiphaseModel().isMultiphase(); + boolean isSteadyCoupled = state.isSteady() && state.getSolverType().isCoupled(); + + if (isTransient || isSteadyMultiphase || isSteadyCoupled) { + deltaT.setEnabled(true); + } else { + deltaT.setEnabled(false); + deltaT.setDoubleValue(1); + } + + adjustableTime.setEnabled((isTransient || isSteadyMultiphase) && !isSonic(state)); + maxCourantNumber.setEnabled((isTransient || isSteadyMultiphase) && adjustableTime.isSelected()); + maxAlphaCourant.setEnabled((isTransient || isSteadyMultiphase) && adjustableTime.isSelected() && state.getMultiphaseModel().isMultiphase()); + maxTimeStep.setEnabled((isTransient || isSteadyMultiphase) && adjustableTime.isSelected()); + } + }); + } + + private boolean isSonic(State state) { + return state.isHighMach() && state.getSolverFamily().isPimple(); + } +} diff --git a/src/eu/engys/gui/casesetup/actions/DecomposeCase.java b/src/eu/engys/gui/casesetup/actions/DecomposeCase.java new file mode 100644 index 0000000..ebbab68 --- /dev/null +++ b/src/eu/engys/gui/casesetup/actions/DecomposeCase.java @@ -0,0 +1,139 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.actions; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.loadEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.printHeader; +import static eu.engys.core.OpenFOAMEnvironment.printVariables; +import static eu.engys.core.project.openFOAMProject.LOG; +import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR; +import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR_ALLREGIONS; +import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR_CONSTANT; +import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR_CONSTANT_ALLREGIONS; + +import java.io.File; +import java.nio.file.Paths; +import java.util.concurrent.Executors; + +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.Controller.OpenOptions; +import eu.engys.core.controller.ScriptBuilder; +import eu.engys.core.controller.actions.AbstractRunCommand; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.ExecutorHook; +import eu.engys.core.executor.ExecutorListener.ExecutorState; +import eu.engys.core.executor.ExecutorMonitor; +import eu.engys.core.executor.TerminalExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.util.IOUtils; +import eu.engys.util.Util; + +public class DecomposeCase extends AbstractRunCommand { + + private static final String DECOMPOSE_RUN = "decomposeCase.run"; + private static final String DECOMPOSE_BAT = "decomposeCase.bat"; + + private File logFile; + private String actionName; + private String logName; + + public DecomposeCase(Model model, Controller controller, String actionName, String logName) { + super(model, controller); + this.actionName = actionName; + this.logName = logName; + this.logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, logName).toFile(); + } + + @Override + public void beforeExecute() { + IOUtils.clearFile(logFile); + } + + @Override + public void executeClient() { + File script = getScript(); + File baseDir = model.getProject().getBaseDir(); + + if (terminal == null) { + this.terminal = new TerminalExecutorMonitor(logFile); + } + if (service == null) { + this.service = Executors.newSingleThreadExecutor(); + } + + ExecutorMonitor monitor = new ExecutorMonitor(); + monitor.addHook(ExecutorState.FINISH, new FinishHook()); + + this.executor = Executor.script(script).description(actionName).inFolder(baseDir).inTerminal(terminal).withMonitors(monitor).inService(service).env(getEnvironment(model, logName)); + executor.exec(); + } + + private File getScript() { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? DECOMPOSE_BAT : DECOMPOSE_RUN); + ScriptBuilder sb = new ScriptBuilder(); + writeScript(sb); + + IOUtils.writeLinesToFile(file, sb.getLines()); + + file.setExecutable(true); + return file; + } + + private void writeScript(ScriptBuilder sb) { + printHeader(sb, actionName.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + writeCommand(sb); + } + + private void writeCommand(ScriptBuilder sb) { + if (model.getProject().isMeshOnZero() || model.getProject().isSerial()) { + if (model.getProject().getZeroFolder().hasRegions()) { + sb.append(DECOMPOSE_PAR_ALLREGIONS()); + } else { + sb.append(DECOMPOSE_PAR()); + } + } else { + if (model.getProject().getZeroFolder().hasRegions()) { + sb.append(DECOMPOSE_PAR_CONSTANT_ALLREGIONS()); + } else { + sb.append(DECOMPOSE_PAR_CONSTANT()); + } + } + } + + private class FinishHook implements ExecutorHook { + + @Override + public void run(ExecutorMonitor monitor) { + if (controller.getListener() != null) { + controller.reopenCase(OpenOptions.PARALLEL); + } + } + } + +} diff --git a/src/eu/engys/gui/casesetup/actions/DecomposeCaseAction.java b/src/eu/engys/gui/casesetup/actions/DecomposeCaseAction.java new file mode 100644 index 0000000..d0aa40c --- /dev/null +++ b/src/eu/engys/gui/casesetup/actions/DecomposeCaseAction.java @@ -0,0 +1,129 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.actions; + +import static eu.engys.core.project.openFOAMProject.LOG; + +import java.awt.event.ActionEvent; +import java.io.File; +import java.nio.file.Paths; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.swing.Icon; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.OpenFOAMEnvironment; +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.actions.RunCommand; +import eu.engys.core.executor.TerminalExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.util.IOUtils; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class DecomposeCaseAction extends ViewAction { + + private static final Logger logger = LoggerFactory.getLogger(DecomposeCaseAction.class); + + private static final Icon DECOMPOSE_ICON = ResourcesUtil.getIcon("decompose.icon"); + private static final String DECOMPOSE_LABEL = ResourcesUtil.getString("casesetup.decompose.label"); + private static final String DECOMPOSE_TOOLTIP = ResourcesUtil.getString("casesetup.decompose.tooltip"); + + public static final String ACTION_NAME = "Decompose"; + public static final String LOG_NAME = "decomposeCase.log"; + + private Model model; + private Controller controller; + + private boolean shouldUseWithZeroFlag; + + public DecomposeCaseAction(Model model, Controller controller, boolean shouldUseWithZeroFlag) { + super(DECOMPOSE_LABEL, DECOMPOSE_ICON, DECOMPOSE_TOOLTIP); + this.model = model; + this.controller = controller; + this.shouldUseWithZeroFlag = shouldUseWithZeroFlag; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (controller.isDemo()) { + UiUtil.showDemoMessage(); + } else { + if (OpenFOAMEnvironment.isEnvironementLoaded()) { + _actionPerformed(); + } else { + UiUtil.showCoreEnvironmentNotLoadedWarning(); + } + } + } + + private void _actionPerformed() { + DecomposeCasePanel panel = new DecomposeCasePanel(model); + panel.showDialog(); + if (panel.getStatus().isOK()) { + controller.saveCase(model.getProject().getBaseDir()); + decompose(); + } + } + + private void decompose() { + if (model.getProject().isParallel()) { + decomposeParallelCase(); + } else { + decomposeSerialCase(); + } + } + + private void decomposeSerialCase() { + RunCommand command = new DecomposeCase(model, controller, ACTION_NAME, LOG_NAME); + command.beforeExecute(); + command.executeClient(); + } + + private void decomposeParallelCase() { + File logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, LOG_NAME).toFile(); + + IOUtils.clearFile(logFile); + + TerminalExecutorMonitor terminal = new TerminalExecutorMonitor(logFile); + ExecutorService service = Executors.newSingleThreadExecutor(); + + RunCommand reconstructCase = new ReconstructCase(model, controller, shouldUseWithZeroFlag, ACTION_NAME, LOG_NAME); + reconstructCase.inService(service); + reconstructCase.inTerminal(terminal); + reconstructCase.executeClient(); + + RunCommand decomposeCase = new DecomposeCase(model, controller, ACTION_NAME, LOG_NAME); + decomposeCase.inService(service); + decomposeCase.inTerminal(terminal); + decomposeCase.executeClient(); + } + +} diff --git a/src/eu/engys/gui/casesetup/actions/DecomposeCasePanel.java b/src/eu/engys/gui/casesetup/actions/DecomposeCasePanel.java new file mode 100644 index 0000000..3566091 --- /dev/null +++ b/src/eu/engys/gui/casesetup/actions/DecomposeCasePanel.java @@ -0,0 +1,286 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.actions; + +import static eu.engys.core.project.system.DecomposeParDict.DELTA_KEY; +import static eu.engys.core.project.system.DecomposeParDict.HIERARCHICAL_COEFFS_KEY; +import static eu.engys.core.project.system.DecomposeParDict.HIERARCHICAL_KEY; +import static eu.engys.core.project.system.DecomposeParDict.METHOD_KEY; +import static eu.engys.core.project.system.DecomposeParDict.NUMBER_OF_SUBDOMAINS_KEY; +import static eu.engys.core.project.system.DecomposeParDict.N_KEY; +import static eu.engys.core.project.system.DecomposeParDict.ORDER_KEY; +import static eu.engys.core.project.system.DecomposeParDict.SCOTCH_KEY; +import static eu.engys.core.project.system.DecomposeParDict.TYPE_KEYS; +import static eu.engys.core.project.system.DecomposeParDict.YXZ_KEY; +import static eu.engys.util.ui.ComponentsFactory.labelArrayField; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.DecomposeParDict; +import eu.engys.util.Util; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.IntegerField; + +public class DecomposeCasePanel extends JPanel { + + public static final String DECOMPOSE_CASE_LABEL = "Decompose Case"; + public static final String HIERARCHY_LABEL = "Hierarchy"; + public static final String PROCESSORS_LABEL = "Processors"; + public static final String DECOMPOSITION_TYPE_LABEL = "Decomposition Type"; + + public static final String HIERARCHICAL_LABEL = "Hierarchical"; + public static final String SCOTCH_LABEL = "Scotch"; + private static final String[] TYPE_LABELS = { HIERARCHICAL_LABEL, SCOTCH_LABEL }; + + public enum Status { + OK, CANCEL; + + public boolean isOK() { + return this == OK; + } + + public boolean isCancel() { + return this == CANCEL; + } + } + + private final int X = 1; + private final int Y = 0; + private final int Z = 2; + +// private OkDialogAction okAction = new OkDialogAction(); +// private CancelDialogAction cancelAction = new CancelDialogAction(); + + private JDialog dialog; + + private Model model; + private DictionaryModel mainModel; + private DictionaryModel hierarchicalDictionaryModel; + private IntegerField nProcessorsField; + private IntegerField[] nHierarchyField; + private JComboBox decompositionType; + private Status status = Status.CANCEL; + + public DecomposeCasePanel(Model model) { + super(new BorderLayout()); + setName("decompose.panel"); + this.model = model; + this.mainModel = new DictionaryModel(); + this.hierarchicalDictionaryModel = new DictionaryModel(); + layoutComponents(); + } + + public void load() { + DecomposeParDict decomposeParDict = model.getProject().getSystemFolder().getDecomposeParDict(); + Dictionary dictionary = new Dictionary(decomposeParDict); + dictionary.remove(HIERARCHICAL_COEFFS_KEY); + mainModel.setDictionary(dictionary); + Dictionary coeffsDict = decomposeParDict.isDictionary(HIERARCHICAL_COEFFS_KEY) ? new Dictionary(decomposeParDict.subDict(HIERARCHICAL_COEFFS_KEY)) : new Dictionary(HIERARCHICAL_COEFFS_KEY); + + hierarchicalDictionaryModel.setDictionary(coeffsDict); + recalculateFactors(); + } + + private void layoutComponents() { + PanelBuilder builder = new PanelBuilder(); + decompositionType = mainModel.bindSelection(METHOD_KEY, TYPE_KEYS, TYPE_LABELS); + nProcessorsField = mainModel.bindIntegerPositive(NUMBER_OF_SUBDOMAINS_KEY); + nHierarchyField = hierarchicalDictionaryModel.bindIntegerArray(N_KEY, 3); + + builder.addComponent(DECOMPOSITION_TYPE_LABEL, decompositionType); + builder.addComponent(PROCESSORS_LABEL, nProcessorsField); + builder.addComponent(labelArrayField("x", "y", "z")); + builder.addComponent(HIERARCHY_LABEL, nHierarchyField); + + for (IntegerField f : nHierarchyField) + f.setEnabled(false); + + decompositionType.addPropertyChangeListener("value", new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + for (IntegerField f : nHierarchyField) + f.setEnabled(HIERARCHICAL_KEY.equals(evt.getNewValue())); + + } + }); + nProcessorsField.addPropertyChangeListener(new RecalculateFactorsOnChange()); + nProcessorsField.setIntValue(1); + + add(builder.getPanel()); + } + + public void showDialog() { + createDialog(); + load(); + dialog.setVisible(true); + } + + private void createDialog() { + if (dialog == null) { + dialog = new JDialog(UiUtil.getActiveWindow(), DECOMPOSE_CASE_LABEL); + dialog.setName("create.case.dialog"); + + AbstractAction saveAndCloseDialogAction = new AbstractAction("OK") { + @Override + public void actionPerformed(ActionEvent e) { + if (TYPE_KEYS[0].equals(decompositionType.getSelectedItem()) && !productEqualsToNumberOfSubdomain()) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Product of Hierarchical Coefficients should be equal to the Number of Processors", "Decomposition Error", JOptionPane.ERROR_MESSAGE); + return; + } + save(); + status = Status.OK; + dialog.setVisible(false); + } + }; + + final AbstractAction cancelAction = new AbstractAction("Cancel") { + @Override + public void actionPerformed(ActionEvent e) { + status = Status.CANCEL; + dialog.setVisible(false); + dialog.dispose(); + dialog = null; + } + }; + + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + + JButton okButton = new JButton(saveAndCloseDialogAction); + okButton.setName("OK"); + buttonsPanel.add(okButton); + + JButton cancelButton = new JButton(cancelAction); + cancelButton.setName("Cancel"); + buttonsPanel.add(cancelButton); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(this, BorderLayout.CENTER); + mainPanel.add(buttonsPanel, BorderLayout.SOUTH); + + dialog.add(mainPanel); + dialog.setSize(350, 200); + dialog.setLocationRelativeTo(null); + dialog.setModal(true); + dialog.getRootPane().setDefaultButton(okButton); + + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + cancelAction.actionPerformed(null); + } + }); + } + } + + private boolean productEqualsToNumberOfSubdomain() { + int nOfSubdomains = nProcessorsField.getIntValue(); + int x = nHierarchyField[X].getIntValue(); + int y = nHierarchyField[Y].getIntValue(); + int z = nHierarchyField[Z].getIntValue(); + + return nOfSubdomains == x * y * z; + } + + public void save() { + Dictionary d = new Dictionary(mainModel.getDictionary()); + Dictionary hierarchicalModelDictionary = new Dictionary(hierarchicalDictionaryModel.getDictionary()); +// hierarchicalModelDictionary.setName(HIERARCHICAL_COEFFS_KEY); + fixSubdomainsOrder(hierarchicalModelDictionary); + d.add(hierarchicalModelDictionary); + + DecomposeParDict decomposeParDict = model.getProject().getSystemFolder().getDecomposeParDict(); + decomposeParDict.merge(d); + + if (SCOTCH_KEY.equals(decomposeParDict.lookup(METHOD_KEY)) && decomposeParDict.found(HIERARCHICAL_COEFFS_KEY)) { + decomposeParDict.remove(HIERARCHICAL_COEFFS_KEY); + } else if (HIERARCHICAL_KEY.equals(decomposeParDict.lookup(METHOD_KEY)) && decomposeParDict.found(HIERARCHICAL_COEFFS_KEY)) { + Dictionary hCoeffs = decomposeParDict.subDict(HIERARCHICAL_COEFFS_KEY); + if (!hCoeffs.found(DELTA_KEY)) + hCoeffs.add(DELTA_KEY, "0.001"); + if (!hCoeffs.found(ORDER_KEY)) + hCoeffs.add(ORDER_KEY, YXZ_KEY); + } + } + + private void fixSubdomainsOrder(Dictionary dict) { + if (dict.found(N_KEY)) { + String subdomains = dict.lookup(N_KEY); + String noParenthesis = subdomains.replaceAll("\\(", "").replaceAll("\\)", ""); + String trimmedLine = Util.getTrimmedSingleSpaceLine(noParenthesis); + String[] values = trimmedLine.split(" "); + dict.add(N_KEY, "(" + values[1] + " " + values[0] + " " + values[2] + ")"); + } + } + + private void recalculateFactors() { + int np = nProcessorsField.getIntValue(); + + int[] factors = Util.getFactorsFor(np); + nHierarchyField[X].setIntValue(factors[0]); + nHierarchyField[Y].setIntValue(factors[1]); + nHierarchyField[Z].setIntValue(factors[2]); + } + + public Status getStatus() { + return status; + } + + class RecalculateFactorsOnChange implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + recalculateFactors(); + } + } + + } + + /* + * For tests puroposes only + */ + public JDialog getDialog() { + return dialog; + } + +} diff --git a/src/eu/engys/gui/casesetup/actions/DefaultCaseSetupActions.java b/src/eu/engys/gui/casesetup/actions/DefaultCaseSetupActions.java new file mode 100644 index 0000000..c71bb41 --- /dev/null +++ b/src/eu/engys/gui/casesetup/actions/DefaultCaseSetupActions.java @@ -0,0 +1,73 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.actions; + +import java.awt.Component; +import java.util.List; + +import javax.swing.JToolBar; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; +import eu.engys.gui.Actions; +import eu.engys.util.ui.UiUtil; + +public abstract class DefaultCaseSetupActions implements Actions { + + protected Model model; + protected Controller controller; + protected DecomposeCaseAction decomposeCaseAction; + + public DefaultCaseSetupActions(Model model, Controller controller) { + this.model = model; + this.controller = controller; + this.decomposeCaseAction = new DecomposeCaseAction(model, controller, shouldUseWithZeroFlag()); + } + + protected abstract List getToolbarComponents(); + + protected abstract boolean shouldUseWithZeroFlag(); + + @Override + public JToolBar toolbar() { + JToolBar toolbar = UiUtil.getToolbar("view.element.toolbar"); + for (Component c : getToolbarComponents()) { + if (c == null) { + toolbar.addSeparator(); + } else { + toolbar.add(c); + } + } + return toolbar; + } + + + @Override + public void update() { + decomposeCaseAction.setEnabled(!model.getPatches().isEmpty() && !model.getState().getMultiphaseModel().getKey().equals("ECOMARINE")); + } +} diff --git a/src/eu/engys/gui/casesetup/actions/ReconstructCase.java b/src/eu/engys/gui/casesetup/actions/ReconstructCase.java new file mode 100644 index 0000000..1b2f07b --- /dev/null +++ b/src/eu/engys/gui/casesetup/actions/ReconstructCase.java @@ -0,0 +1,128 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.actions; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.loadEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.printHeader; +import static eu.engys.core.OpenFOAMEnvironment.printVariables; +import static eu.engys.core.project.openFOAMProject.LOG; +import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR; +import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR_ALLREGIONS; +import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR_MESH; +import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR_MESH_ALLREGIONS; +import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR_MESH_CONSTANT; +import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR_MESH_CONSTANT_ALLREGIONS; + +import java.io.File; +import java.nio.file.Paths; +import java.util.concurrent.Executors; + +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.ScriptBuilder; +import eu.engys.core.controller.actions.AbstractRunCommand; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.TerminalExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.util.IOUtils; +import eu.engys.util.Util; + +public class ReconstructCase extends AbstractRunCommand { + + private static final String RECONSTRUCT_CASE_RUN = "reconstructCase.run"; + private static final String RECONSTRUCT_CASE_BAT = "reconstructCase.bat"; + + private String actionName; + private String logName; + private File logFile; + private boolean shouldUseWithZeroFlag; + + public ReconstructCase(Model model, Controller controller, boolean shouldUseWithZeroFlag, String actionName, String logName) { + super(model, controller); + this.shouldUseWithZeroFlag = shouldUseWithZeroFlag; + this.actionName = actionName; + this.logName = logName; + this.logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, logName).toFile(); + } + + @Override + public void executeClient() { + File script = getScript(); + File baseDir = model.getProject().getBaseDir(); + + if (terminal == null) { + this.terminal = new TerminalExecutorMonitor(logFile); + } + if (service == null) { + this.service = Executors.newSingleThreadExecutor(); + } + + this.executor = Executor.script(script).description(actionName).inFolder(baseDir).inTerminal(terminal).inService(service).env(getEnvironment(model, logName)); + executor.exec(); + } + + private File getScript() { + File file = new File(model.getProject().getBaseDir(), Util.isWindows() ? RECONSTRUCT_CASE_BAT : RECONSTRUCT_CASE_RUN); + ScriptBuilder sb = new ScriptBuilder(); + writeScript(sb); + IOUtils.writeLinesToFile(file, sb.getLines()); + file.setExecutable(true); + return file; + } + + private void writeScript(ScriptBuilder sb) { + printHeader(sb, actionName.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + writeCommand(sb); + } + + private void writeCommand(ScriptBuilder sb) { + boolean meshOnZero = model.getProject().isMeshOnZero(); + + if (meshOnZero) { + if (model.getProject().getZeroFolder().hasRegions()) { + sb.append(RECONSTRUCT_PAR_MESH_ALLREGIONS()); + } else { + sb.append(RECONSTRUCT_PAR_MESH()); + } + } else { + if (model.getProject().getZeroFolder().hasRegions()) { + sb.append(RECONSTRUCT_PAR_MESH_CONSTANT_ALLREGIONS()); + } else { + sb.append(RECONSTRUCT_PAR_MESH_CONSTANT()); + } + } + + if (model.getProject().getZeroFolder().hasRegions()) { + sb.append(RECONSTRUCT_PAR_ALLREGIONS(shouldUseWithZeroFlag)); + } else { + sb.append(RECONSTRUCT_PAR(shouldUseWithZeroFlag)); + } + + } + +} diff --git a/src/eu/engys/gui/casesetup/actions/StandardCaseSetupActions.java b/src/eu/engys/gui/casesetup/actions/StandardCaseSetupActions.java new file mode 100644 index 0000000..15ac948 --- /dev/null +++ b/src/eu/engys/gui/casesetup/actions/StandardCaseSetupActions.java @@ -0,0 +1,58 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.actions; + +import static eu.engys.util.ui.UiUtil.createToolBarButton; + +import java.awt.Component; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; +import eu.engys.util.progress.ProgressMonitor; + +public class StandardCaseSetupActions extends DefaultCaseSetupActions { + + @Inject + public StandardCaseSetupActions(Model model, Controller controller, ProgressMonitor monitor) { + super(model, controller); + } + + @Override + protected List getToolbarComponents() { + List components = new ArrayList<>(); + components.add(createToolBarButton(decomposeCaseAction)); + return components; + } + + @Override + protected boolean shouldUseWithZeroFlag() { + return true; + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/AbstractInterpolationTable.java b/src/eu/engys/gui/casesetup/boundaryconditions/AbstractInterpolationTable.java new file mode 100644 index 0000000..00b3ac9 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/AbstractInterpolationTable.java @@ -0,0 +1,405 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.boundaryconditions; + +import static eu.engys.util.RegexpUtils.CLOSED_BRACKET; +import static eu.engys.util.RegexpUtils.DOUBLE; +import static eu.engys.util.RegexpUtils.OPEN_BRACKET; +import static eu.engys.util.RegexpUtils.POINT; +import static eu.engys.util.RegexpUtils.SPACES; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dialog.ModalityType; +import java.awt.FlowLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.EventObject; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.DefaultCellEditor; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTable; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.text.JTextComponent; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlock; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.gui.solver.postprocessing.data.DoubleTimeBlockUnit; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.CopyPasteSupport; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.textfields.DoubleField; + +public abstract class AbstractInterpolationTable extends JPanel { + + private static final String VALUE_VAR = "Value"; + private static final String Z_VAR = "Z"; + private static final String Y_VAR = "Y"; + private static final String X_VAR = "X"; + private static final String VECTOR_PATTERN = OPEN_BRACKET + SPACES + DOUBLE + SPACES + POINT + SPACES + CLOSED_BRACKET; + private static final String SCALAR_PATTERN = OPEN_BRACKET + SPACES + DOUBLE + SPACES + DOUBLE + SPACES + CLOSED_BRACKET; + + private JTable table; + private DefaultTableModel tableModel; + private InterpolationChartPanel chart; + protected String[] columnNames; + private JButton removeButton; + private JSplitPane splitPane; + private JPanel topPanel; + private JPanel bottomPanel; + private JDialog dialog; + private JButton okButton; + protected String[] names; + + public AbstractInterpolationTable(String[] names) { + super(new BorderLayout()); + this.names = names; + setName("interpolation.table"); + setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + setupColumnNames(); + layoutComponents(); + } + + public abstract void load(); + + public boolean isVector() { + return names.length == 3; + } + + public StringBuilder save() { + StringBuilder sb = new StringBuilder(); + sb.append("(\n"); + for (int row = 0; row < table.getRowCount(); row++) { + if (isVector()) { + Double distance = ((Double) table.getValueAt(row, 0)); + double x = ((Double) table.getValueAt(row, 1)); + double y = ((Double) table.getValueAt(row, 2)); + double z = ((Double) table.getValueAt(row, 3)); + String interpolationRow = "( " + distance + " ( " + x + " " + y + " " + z + " ) )"; + sb.append(interpolationRow + "\n"); + } else { + Double time = ((Double) table.getValueAt(row, 0)); + double value = ((Double) table.getValueAt(row, 1)); + String interpolationRow = "( " + time + " " + value + " )"; + sb.append(interpolationRow + "\n"); + } + } + sb.append(")"); + return sb; + } + + protected void loadTable(String tableData) { + if (tableData.startsWith("(") && tableData.endsWith(")")) { + tableData = tableData.substring(1, tableData.length() - 1).trim(); + try { + Pattern regex = Pattern.compile(isVector() ? VECTOR_PATTERN : SCALAR_PATTERN); + Matcher regexMatcher = regex.matcher(tableData); + while (regexMatcher.find()) { + addRow(parseRows(regexMatcher.group(0))); + } + } catch (PatternSyntaxException ex) { + ex.printStackTrace(); + } + } + } + + private Double[] parseRows(String row) { + Pattern innerRegex = Pattern.compile(DOUBLE); + Matcher innerRegexMatcher = innerRegex.matcher(row); + Double[] values = isVector() ? new Double[4] : new Double[2]; + int internalCount = 0; + while (innerRegexMatcher.find()) { + values[internalCount++] = Double.parseDouble(innerRegexMatcher.group(0)); + } + return values; + } + + /* + * GUI + */ + + protected abstract void setupColumnNames(); + + private void layoutComponents() { + createSplitPane(); + add(splitPane, BorderLayout.CENTER); + createTableButtons(); + createTable(); + createChart(); + createDialogButtons(); + createDialog(); + } + + private void createDialog() { + dialog = new JDialog(UiUtil.getActiveWindow(), "Interpolation Table", ModalityType.MODELESS); + dialog.setName("interpolation.dialog"); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + handleDialogClose_Cancel(); + } + }); + + dialog.add(this); + dialog.setSize(600, 600); + dialog.setLocationRelativeTo(null); + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.getRootPane().setDefaultButton(okButton); + } + + public void showDialog() { + load(); + dialog.setVisible(true); + } + + private void handleDialogClose_Cancel() { + dialog.setVisible(false); + } + + private void handleDialogClose_OK() { + save(); + dialog.setVisible(false); + } + + private void createSplitPane() { + this.splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + this.splitPane.setOneTouchExpandable(false); + this.topPanel = new JPanel(new BorderLayout()); + this.bottomPanel = new JPanel(new BorderLayout()); + this.splitPane.setTopComponent(topPanel); + this.splitPane.setBottomComponent(bottomPanel); + this.splitPane.setResizeWeight(0.5); + } + + private void createTableButtons() { + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + JButton addButton = new JButton(new AbstractAction("+") { + + @Override + public void actionPerformed(ActionEvent e) { + addRow(); + } + }); + addButton.setName("add.row.button"); + buttonsPanel.add(addButton); + removeButton = new JButton(new AbstractAction("-") { + + @Override + public void actionPerformed(ActionEvent e) { + removeRows(); + } + }); + buttonsPanel.add(removeButton); + removeButton.setName("rem.row.button"); + removeButton.setEnabled(false); + + topPanel.add(buttonsPanel, BorderLayout.NORTH); + } + + private void createDialogButtons() { + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + okButton = new JButton(new AbstractAction("OK") { + + @Override + public void actionPerformed(ActionEvent e) { + handleDialogClose_OK(); + } + }); + okButton.setName("OK"); + JButton cancelButton = new JButton(new AbstractAction("Cancel") { + + @Override + public void actionPerformed(ActionEvent e) { + handleDialogClose_Cancel(); + } + }); + buttonsPanel.add(okButton); + buttonsPanel.add(cancelButton); + bottomPanel.add(buttonsPanel, BorderLayout.SOUTH); + } + + private void createTable() { + tableModel = new DefaultTableModel(columnNames, 0) { + @Override + public Class getColumnClass(int columnIndex) { + return Double.class; + } + }; + table = new JTable() { + public boolean editCellAt(int row, int column, EventObject e) { + boolean result = super.editCellAt(row, column, e); + final Component editor = getEditorComponent(); + if (e instanceof KeyEvent && editor instanceof JTextComponent) { + ((JTextComponent) editor).selectAll(); + } + + return result; + } + + }; + ((DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer()).setHorizontalAlignment(JLabel.CENTER); + table.setModel(tableModel); + tableModel.addTableModelListener(new TableModelListener() { + @Override + public void tableChanged(TableModelEvent e) { + if (e.getType() == TableModelEvent.UPDATE) { + updateChart(); + } + } + }); + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + removeButton.setEnabled(table.getSelectedRowCount() > 0); + } + }); + setupEditors(table); + + CopyPasteSupport.addSupportTo(table); + topPanel.add(new JScrollPane(table), BorderLayout.CENTER); + } + + private void createChart() { + this.chart = new InterpolationChartPanel(getVariablesList(), columnNames[0]); + chart.layoutComponents(); + chart.initSeries(); + bottomPanel.add(chart, BorderLayout.CENTER); + } + + private List getVariablesList() { + List variables = new ArrayList<>(); + if (isVector()) { + variables.add(X_VAR); + variables.add(Y_VAR); + variables.add(Z_VAR); + } else { + variables.add(VALUE_VAR); + } + return variables; + } + + private void setupEditors(JTable table) { + final DoubleField doubleTextField = ComponentsFactory.doubleField(); + doubleTextField.setMargin(new Insets(0, 0, 0, 0)); + + DefaultCellEditor doubleEditor = new DefaultCellEditor(doubleTextField) { + @Override + public Object getCellEditorValue() { + try { + return Double.valueOf(Double.parseDouble((String) super.getCellEditorValue())); + } catch (NumberFormatException e) { + return Double.valueOf(doubleTextField.getDoubleValue()); + } + } + }; + table.setDefaultEditor(Double.class, doubleEditor); + + final TableCellRenderer r = table.getDefaultRenderer(Double.class); + table.setDefaultRenderer(Double.class, new TableCellRenderer() { + private NumberFormat formatter; + + { + formatter = NumberFormat.getInstance(); + formatter.setMaximumFractionDigits(10); + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel label = (JLabel) r.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (value instanceof Double) { + label.setText(formatter.format(value)); + } + return label; + } + }); + + } + + private void addRow() { + Object[] scalarRow = new Object[] { 0.0, 0.0 }; + Object[] vectorRow = new Object[] { 0.0, 0.0, 0.0, 0.0 }; + tableModel.addRow(isVector() ? vectorRow : scalarRow); + updateChart(); + } + + private void addRow(Object[] row) { + tableModel.addRow(row); + updateChart(); + } + + private void removeRows() { + int[] selectedRow = table.getSelectedRows(); + for (int i = selectedRow.length - 1; i >= 0; i--) { + tableModel.removeRow(selectedRow[i]); + updateChart(); + } + } + + private void updateChart() { + chart.clearData(); + TimeBlocks tbs = new TimeBlocks(); + for (int row = 0; row < table.getRowCount(); row++) { + TimeBlock timeBlock = new TimeBlock(((Double) table.getValueAt(row, 0))); + if (isVector()) { + timeBlock.getUnitsMap().put(X_VAR, new DoubleTimeBlockUnit(X_VAR, ((Double) table.getValueAt(row, 1)))); + timeBlock.getUnitsMap().put(Y_VAR, new DoubleTimeBlockUnit(Y_VAR, ((Double) table.getValueAt(row, 2)))); + timeBlock.getUnitsMap().put(Z_VAR, new DoubleTimeBlockUnit(Z_VAR, ((Double) table.getValueAt(row, 3)))); + } else { + timeBlock.getUnitsMap().put(VALUE_VAR, new DoubleTimeBlockUnit(VALUE_VAR, ((Double) table.getValueAt(row, 1)))); + } + tbs.add(timeBlock); + } + chart.addToDataSet(tbs); + } + + protected void clear() { + tableModel.setRowCount(0); + chart.clearData(); + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/BoundaryConditionsPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/BoundaryConditionsPanel.java new file mode 100644 index 0000000..c5d7408 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/BoundaryConditionsPanel.java @@ -0,0 +1,382 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions; + +import static eu.engys.util.ui.ComponentsFactory.selectField; +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.swing.Icon; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.modules.boundaryconditions.IBoundaryConditionsPanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.core.project.zero.patches.BoundaryConditionsDefaults; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.gui.AbstractGUIPanel; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.util.Util; +import eu.engys.util.ui.ComponentsFactory.SelectField; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.StringField; + +public class BoundaryConditionsPanel extends AbstractGUIPanel implements IBoundaryConditionsPanel { + + public static final String BOUNDARY_CONDITIONS = "Boundary Conditions"; + public static final String PATCH_TYPE_LABEL = "Patch Type"; + public static final String PATCH_NAME_LABEL = "Patch Name"; + + private CardLayout centerPanelLayout; + private JPanel centerPanel; + + private final Set panels; + private Map panelsByType = new HashMap(); + + private StringField patchNameField; + private SelectField patchTypeField; + + private BoundaryType activeBoundaryType; + + private SelectBoundaryConditionAction selectBoundaryConditionListener; + private BoundaryConditionsTreeNodeManager treeNodeManager; + + private PropertyChangeListener listener; + + private Set modules; + + @Inject + public BoundaryConditionsPanel(Model model, Set modules, Set panels) { + super(BOUNDARY_CONDITIONS, model); + this.treeNodeManager = new BoundaryConditionsTreeNodeManager(model, this); + this.panels = panels; + this.modules = modules; + model.addObserver(treeNodeManager); + } + + protected JComponent layoutComponents() { + centerPanelLayout = new CardLayout(); + centerPanel = new JPanel(centerPanelLayout); + centerPanel.add(new JLabel(), "other"); + + PanelBuilder bcTypeBuider = new PanelBuilder(); + + // qui non usare il panel builder altrimenti il bordo del tabbedpane non + // arriva fino in fondo + JPanel panel = new JPanel(new BorderLayout()); + panel.add(bcTypeBuider.margins(0, 0, 1, 0).getPanel(), BorderLayout.NORTH); + panel.add(centerPanel, BorderLayout.CENTER); + + for (BoundaryTypePanel typePanel : panels) { + addTypePanel(typePanel); + } + + + initNameField(); + initTypeField(); + + bcTypeBuider.addComponent(PATCH_NAME_LABEL, patchNameField); + bcTypeBuider.addComponent(PATCH_TYPE_LABEL, patchTypeField); + + return panel; + } + + @Override + public void addTypePanel(BoundaryTypePanel typePanel) { + BoundaryType type = typePanel.getType(); + if (! panelsByType.containsKey(type)) { + typePanel.layoutPanel(); + panelsByType.put(type, typePanel); + centerPanel.add(typePanel.getPanel(), type.getKey()); + ModulesUtil.configureBoundaryConditionsView(modules, typePanel); + } + } + + @Override + public void removeTypePanel(BoundaryTypePanel typePanel) { + BoundaryType type = typePanel.getType(); + if (panelsByType.containsKey(type)) { + panelsByType.remove(type); + centerPanel.remove(typePanel.getPanel()); + ModulesUtil.configureBoundaryConditionsView(modules, typePanel); + } + } + + private void initTypeField() { + patchTypeField = selectField(); + patchTypeField.setSelectedIndex(-1); + patchTypeField.setEnabled(false); + selectBoundaryConditionListener = new SelectBoundaryConditionAction(patchTypeField); + patchTypeField.addActionListener(selectBoundaryConditionListener); + } + + private void initNameField() { + patchNameField = stringField(); + patchNameField.setEnabled(false); + listener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + Patch[] patches = treeNodeManager.getSelectedValues(); + if (patches.length == 1 && patches[0] != null) { + patches[0].setName(patchNameField.getText()); + treeNodeManager.refreshNode(patches[0]); + } + } + }; + patchNameField.addPropertyChangeListener(listener); + } + + class SelectBoundaryConditionAction implements ActionListener { + private JComboBox patchTypeField; + + public SelectBoundaryConditionAction(JComboBox patchTypeField) { + this.patchTypeField = patchTypeField; + } + + @Override + public void actionPerformed(ActionEvent e) { + String selectedType = (String) patchTypeField.getSelectedItem(); + BoundaryType boundaryType = BoundaryType.getType(selectedType); + BoundaryConditions defaults = BoundaryConditionsDefaults.get(boundaryType.getKey()); + Patch[] patches = treeNodeManager.getSelectedValues(); + if (patches.length > 0) { + for (Patch patch : patches) { + fixAMIPatch(patch); + patch.setBoundaryConditions(new BoundaryConditions(defaults)); + patch.setPhisicalType(boundaryType); + } + } + activateBoundaryMesh(patches); + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) patches); + } + + private void fixAMIPatch(Patch patch) { + if (patch.getPhisicalType().isCyclicAMI() && patch.getDictionary().found("neighbourPatch")) { + String neighboutPatchName = patch.getDictionary().lookup("neighbourPatch"); + for (Patch p : model.getPatches().filterProcBoundary()) { + if (p.getName().equals(neighboutPatchName)) { + p.setPhisicalType(BoundaryType.getDefaultType()); + p.setBoundaryConditions(new BoundaryConditions(BoundaryConditionsDefaults.get(BoundaryType.getDefaultKey()))); + p.setDictionary(new Dictionary("")); + } + } + } + } + } + + public void updateSelection(Patch[] currentSelection) { + updatePatchNameField(currentSelection); + updatePatchTypeField(currentSelection); + activateBoundaryMesh(currentSelection); + } + + private void updatePatchNameField(Patch[] patches) { + patchNameField.removePropertyChangeListener(listener); + if (patches.length == 1) { + patchNameField.setValue(patches[0].getName()); + } else { + StringBuilder sb = new StringBuilder(); + for (Patch patch : patches) { + sb.append(patch.getName() + " "); + } + patchNameField.setValue(sb.toString()); + } + patchNameField.addPropertyChangeListener(listener); + } + + private void updatePatchTypeField(Patch[] patches) { + patchTypeField.removeActionListener(selectBoundaryConditionListener); + if (patches.length > 0) { + patchTypeField.setEnabled(true); + if (patchesAreOfTheSameType(patches)) { + patchTypeField.setSelectedItem(patches[0].getPhisicalType().getKey()); + } else { + patchTypeField.setSelectedItem(null); + } + } else { + patchTypeField.setSelectedItem(null); + patchTypeField.setEnabled(false); + } + patchTypeField.addActionListener(selectBoundaryConditionListener); + } + + private boolean patchesAreOfTheSameType(Patch[] patches) { + BoundaryType type = null; + for (Patch patch : patches) { + if (type == null) + type = patch.getPhisicalType(); + else if (patch.getPhisicalType() != type) + return false; + + } + return true; + } + + private void activateBoundaryMesh(Patch[] patches) { + if (patches.length > 0) { + BoundaryType boundaryType = patchesAreOfTheSameType(patches) ? patches[0].getPhisicalType() : null; + + if (boundaryType != null) { + if (boundaryType.hasBoundaryConditions()) { + // System.out.println("BoundaryConditionsPanel.activateBoundaryMesh() " + // + patches[0].getBoundaryConditions().toDictionary()); + centerPanelLayout.show(centerPanel, boundaryType.getKey()); + panelsByType.get(boundaryType).loadFromPatches(patches); + } else { + centerPanelLayout.show(centerPanel, "other"); + } + } else { + centerPanelLayout.show(centerPanel, "other"); + } + setActiveBoundaryType(boundaryType); + } else { + centerPanelLayout.show(centerPanel, "other"); + setActiveBoundaryType(null); + } + } + + private void setActiveBoundaryType(BoundaryType boundaryType) { + this.activeBoundaryType = boundaryType; + } + + @Override + public void load() { + ModulesUtil.configureBoundaryConditionsView(modules, this); + loadTypeField(); + + BoundaryConditionsDefaults.updateBoundaryConditionsDefaultsByFields(model); + for (BoundaryTypePanel panel : panels) { + panel.stateChanged(); + panel.materialsChanged(); + } + } + + @Override + public void save() { + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) treeNodeManager.getSelectedValues()); + } + + @Override + public void clear() { + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) new Patch[0]); + for (BoundaryTypePanel p : panels) { + p.resetToDefault(); + } + } + + public void savePatches(Patch[] values) { + if (values.length > 0 && activeBoundaryType != null) { + for (int i = 0; i < values.length; i++) { + savePatch(values[i]); + } + } + } + + public void savePatch(Patch patch) { + patch.setPhisicalType(activeBoundaryType); + if (panelsByType.containsKey(activeBoundaryType)) { + panelsByType.get(activeBoundaryType).saveToPatch(patch); + } else { + patch.setBoundaryConditions(null); + } + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } + + @Override + public void materialsChanged() { + for (BoundaryTypePanel panel : panels) { + panel.materialsChanged(); + } + } + + @Override + public void stateChanged() { + final Patch[] selectedValues = treeNodeManager.getSelectedValues(); + treeNodeManager.getSelectionHandler().clear(); + + ModulesUtil.configureBoundaryConditionsView(modules, this); + + loadTypeField(); + + BoundaryConditionsDefaults.updateBoundaryConditionsDefaultsByFields(getModel()); + + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + for (BoundaryTypePanel panel : panels) { + panel.stateChanged(); + } + + if (Util.isVarArgsNotNull(selectedValues)) { + treeNodeManager.setSelectedValues(selectedValues); + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) selectedValues); + } + } + }); + } + + private void loadTypeField() { + patchTypeField.removeActionListener(selectBoundaryConditionListener); + patchTypeField.removeAllItems(); + + Map typesMap = BoundaryType.getRegisteredBoundaryTypes(); + for (String type : typesMap.keySet()) { + BoundaryType boundaryType = typesMap.get(type); + + String key = boundaryType.getKey(); + String label = boundaryType.getLabel(); + Icon icon = boundaryType.getIcon(); + + patchTypeField.addItem(key, label, icon); + } + patchTypeField.setSelectedIndex(-1); + patchTypeField.addActionListener(selectBoundaryConditionListener); + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/BoundaryConditionsTreeNodeManager.java b/src/eu/engys/gui/casesetup/boundaryconditions/BoundaryConditionsTreeNodeManager.java new file mode 100644 index 0000000..2195174 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/BoundaryConditionsTreeNodeManager.java @@ -0,0 +1,336 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.boundaryconditions; + +import static eu.engys.core.dictionary.Dictionary.TYPE; + +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; + +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; +import javax.swing.JPopupMenu; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreePath; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.SelectPatchesEvent; +import eu.engys.gui.tree.AbstractSelectionHandler; +import eu.engys.gui.tree.DefaultTreeNodeManager; +import eu.engys.gui.tree.SelectionHandler; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.Util; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.TreeUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.checkboxtree.RootVisibleLoadableTreeNode; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class BoundaryConditionsTreeNodeManager extends DefaultTreeNodeManager { + + private static final Logger logger = LoggerFactory.getLogger(BoundaryConditionsTreeNodeManager.class); + public static final String COPY = "Copy"; + public static final String PASTE = "Paste"; + + private Map patchesMap; + private SelectionHandler selectionHandler; + + private CopyAction copyAction; + private PasteAction pasteAction; + + public BoundaryConditionsTreeNodeManager(Model model, BoundaryConditionsPanel panel) { + super(model, panel); + this.root = new RootVisibleLoadableTreeNode(panel.getTitle()); + this.selectionHandler = new BoundaryConditionsSelectionHandler(panel); + this.copyAction = new CopyAction(panel); + this.pasteAction = new PasteAction(); + this.patchesMap = new HashMap<>(); + } + + @Override + public void update(Observable o, Object arg) { + if (arg instanceof Patches) { + logger.debug("Observerd a change: arg is " + arg.getClass()); + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + selectionHandler.disable(); + loadTree(); + makeVisibleItemsChecked(); + expandTree(); + selectionHandler.enable(); + } + }); + } + } + + private void loadTree() { + logger.debug("Load 'Patches' tree"); + clear(); + for (Patch patch : model.getPatches().patchesToDisplay()) { + addPatch(root, patch); + } + treeChanged(root); + } + + private void makeVisibleItemsChecked() { + logger.debug("Make visible items checked: DO NOTHING!"); + } + + private void expandTree() { + getTree().expandNode(getRoot()); + } + + private void addPatch(DefaultMutableTreeNode parent, Patch patch) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(patch); + parent.add(node); + nodeMap.put(patch, node); + patchesMap.put(node, patch); + } + + public Patch[] getSelectedValues() { + if (getTree() != null) { + TreePath[] selectionPaths = getTree().getSelectedDescendantOf(getRoot()); + Patch[] patches = new Patch[selectionPaths.length]; + for (int i = 0; i < selectionPaths.length; i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPaths[i].getLastPathComponent(); + Patch patch = patchesMap.get(node); + patches[i] = patch; + } + return patches; + } + return new Patch[0]; + } + + public void setSelectedValues(Patch[] patches) { + if (getTree() != null) { + TreePath[] selectionPaths = new TreePath[patches.length]; + for (int i = 0; i < patches.length; i++) { + DefaultMutableTreeNode node = nodeMap.get(patches[i]); + selectionPaths[i] = new TreePath(getTree().getPathToRoot(node)); + } + getTree().setSelectionPaths(selectionPaths); + } + } + + public void clear() { + // clear node before selection handler! + clearNode(root); + selectionHandler.clear(); + nodeMap.clear(); + patchesMap.clear(); + } + + public DefaultMutableTreeNode getRoot() { + return root; + } + + @Override + public Class getRendererClass() { + return Patch.class; + } + + @SuppressWarnings("serial") + public DefaultTreeCellRenderer getRenderer() { + return new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObject = node.getUserObject(); + + if (userObject instanceof Patch) { + Patch renderedPatch = (Patch) userObject; + setText(renderedPatch.getName()); + setIcon(renderedPatch.getPhisicalType().getIcon()); + } else { + setIcon(null); + } + return this; + } + + }; + } + + @Override + public SelectionHandler getSelectionHandler() { + return selectionHandler; + } + + @Override + public PopUpBuilder getPopUpBuilder() { + return new PopUpBuilder() { + @Override + public void populate(JPopupMenu popUp) { + popUp.add(copyAction).setName(COPY); + popUp.add(pasteAction).setName(PASTE); + } + }; + } + + private final class CopyAction extends AbstractAction { + + private BoundaryConditionsPanel panel; + + public CopyAction(BoundaryConditionsPanel panel) { + super(COPY); + this.panel = panel; + } + + @Override + public void actionPerformed(ActionEvent e) { + Patch[] selectedValues = getSelectedValues(); + if (Util.isVarArgsNotNullAndOfSize(1, selectedValues)) { + Patch patch = selectedValues[0]; + panel.savePatch(patch); + Dictionary bc = patch.getBoundaryConditions().toDictionary(); + bc.add(TYPE, patch.getPhisicalType().getKey()); + StringSelection contents = new StringSelection(bc.toString()); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, contents); + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Only Single Selection Allowed", "Copy Error", JOptionPane.ERROR_MESSAGE); + } + } + } + + private final class PasteAction extends AbstractAction { + + public PasteAction() { + super(PASTE); + } + + @Override + public void actionPerformed(ActionEvent e) { + Patch[] selectedValues = getSelectedValues(); + getTree().clearSelection(); + if (Util.isVarArgsNotNull(selectedValues)) { + Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this); + try { + String dictionaryString = (String) contents.getTransferData(DataFlavor.stringFlavor); + if (dictionaryString.startsWith("\nboundaryConditions")) { + Dictionary dictionary = DictionaryUtils.readDictionary(dictionaryString).getDictionaries().get(0); + BoundaryType type = BoundaryType.getType(dictionary.lookup("type")); + for (Patch patch : selectedValues) { + patch.setPhisicalType(type); + patch.getBoundaryConditions().fromDictionary(dictionary); + } + setSelectedValues(selectedValues); + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Invalid Format", "Paste Error", JOptionPane.ERROR_MESSAGE); + } + } catch (Exception ee) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "An Error Occurred", "Paste Error", JOptionPane.ERROR_MESSAGE); + } + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Empty Selection", "Paste Error", JOptionPane.ERROR_MESSAGE); + } + } + } + + private final class BoundaryConditionsSelectionHandler extends AbstractSelectionHandler { + + private BoundaryConditionsPanel panel; + private Patch[] currentSelection; + + public BoundaryConditionsSelectionHandler(BoundaryConditionsPanel panel) { + this.panel = panel; + } + + @Override + public void handleSelection(boolean fire3DEvent, Object... selection) { + if (currentSelection != null && currentSelection.length > 0) { + panel.savePatches(currentSelection); + } + if (TreeUtil.isConsistent(selection, Patch.class)) { + this.currentSelection = Arrays.copyOf(selection, selection.length, Patch[].class); + } else { + this.currentSelection = new Patch[0]; + } + panel.updateSelection(currentSelection); + getTree().repaint(); + + if (fire3DEvent) { + EventManager.triggerEvent(this, new SelectPatchesEvent(currentSelection)); + } + } + + @Override + public void handleVisibility(VisibleItem item) { + } + + @Override + public void process3DSelectionEvent(Picker picker, Actor actor, boolean keep) { + if (getTree() != null && actor != null && actor.getVisibleItem() instanceof Patch) { + Patch patch = (Patch) actor.getVisibleItem(); + DefaultMutableTreeNode selectedNode = nodeMap.get(patch); + if (selectedNode != null) { + if (keep) { + getTree().addSelectedNode(selectedNode); + } else { + getTree().setSelectedNode(selectedNode); + } + } + } + } + + @Override + public void process3DVisibilityEvent(boolean selected) { + if (getTree() != null) { + for (DefaultMutableTreeNode node : nodeMap.values()) { + if (selected) { + getTree().getCheckManager().selectNode(node); + } else { + getTree().getCheckManager().deselectNode(node); + } + } + } + } + + public void clear() { + currentSelection = null; + } + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/InterpolationChartPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/InterpolationChartPanel.java new file mode 100644 index 0000000..43bab73 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/InterpolationChartPanel.java @@ -0,0 +1,100 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.boundaryconditions; + +import java.util.List; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.XYSeries; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlock; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlockUnit; +import eu.engys.gui.solver.postprocessing.data.DoubleTimeBlockUnit; +import eu.engys.gui.solver.postprocessing.panels.HistoryChartPanel; +import eu.engys.util.ui.textfields.DoubleField; + +public class InterpolationChartPanel extends HistoryChartPanel { + + private static final Logger logger = LoggerFactory.getLogger(InterpolationChartPanel.class); + + public InterpolationChartPanel(List seriesNames, String domainAxisLabel) { + super("", seriesNames, domainAxisLabel, "", false); + } + + @Override + protected void createChart() { + this.chart = ChartFactory.createXYLineChart("", "", "", dataset, PlotOrientation.VERTICAL, true, true, false); + + NumberAxis domainAxis = new NumberAxis(domainAxisLabel); + domainAxis.setAutoRangeStickyZero(false); + domainAxis.setAutoRangeIncludesZero(true); + + NumberAxis rangeAxis = new NumberAxis(rangeAxisLabel); + rangeAxis.setNumberFormatOverride(DoubleField.getFormatForDISPLAY(10)); + + chart.getXYPlot().setDomainAxis(domainAxis); + chart.getXYPlot().setRangeAxis(rangeAxis); + + XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer(); + renderer.setDrawOutlines(true); + renderer.setUseFillPaint(true); + } + + @Override + protected void addTimeBlock(final TimeBlock block) { + for (TimeBlockUnit unit : block.getUnitsMap().values()) { + if (unit instanceof DoubleTimeBlockUnit) { + addTimeUnit(block.getTime(), unit); + } + } + } + + private void addTimeUnit(double time, TimeBlockUnit unit) { + String varName = unit.getVarName(); + if (dataset.getSeriesIndex(varName) != -1) { + XYSeries xyserie = dataset.getSeries(varName); + DoubleTimeBlockUnit doubleUnit = (DoubleTimeBlockUnit) unit; + xyserie.add(time, doubleUnit.getValue()); + } else { + logger.error("Series not found for {}", varName); + } + } + + @Override + public void initSeries() { + super.initSeries(); + XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer(); + for (String varName : seriesNames) { + renderer.setSeriesShapesVisible(dataset.getSeriesIndex(varName), true); + } + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/NonUniformComboBoxController.java b/src/eu/engys/gui/casesetup/boundaryconditions/NonUniformComboBoxController.java new file mode 100644 index 0000000..264fa9f --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/NonUniformComboBoxController.java @@ -0,0 +1,71 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.boundaryconditions; + +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.DATA_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FILE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FILE_NAME_KEY; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryModel.DictionaryError; +import eu.engys.core.dictionary.model.DictionaryModel.DictionaryListener; +import eu.engys.util.ui.builder.JComboBoxController; + +public class NonUniformComboBoxController extends JComboBoxController { + private DictionaryModel model; + + public NonUniformComboBoxController(DictionaryModel model) { + super(); + this.model = model; + model.addDictionaryListener(new DictionaryListener() { + @Override + public void dictionaryChanged() throws DictionaryError { + Dictionary dict = NonUniformComboBoxController.this.model.getDictionary(); + if (dict != null && dict.found(FILE_NAME_KEY) && dict.lookup(FILE_NAME_KEY).length() > 2) { + setSelectedKey(FILE_KEY); + } else { + setSelectedKey(DATA_KEY); + } + } + }); + addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Dictionary dict = NonUniformComboBoxController.this.model.getDictionary(); + String key = getSelectedKey(); + if (key.equals(DATA_KEY) && dict.found(FILE_NAME_KEY)) { + dict.remove(FILE_NAME_KEY); + } else if (key.equals(FILE_KEY) && !dict.found(FILE_NAME_KEY)) { + dict.add(FILE_NAME_KEY, "\"\""); + } + } + }); + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/NonUniformInterpolationTable.java b/src/eu/engys/gui/casesetup/boundaryconditions/NonUniformInterpolationTable.java new file mode 100644 index 0000000..c2b9e06 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/NonUniformInterpolationTable.java @@ -0,0 +1,76 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.boundaryconditions; + +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.DATA_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FILE_NAME_KEY; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.parser.ListField2; + +public class NonUniformInterpolationTable extends AbstractInterpolationTable { + + public static final String DISTANCE_M_LABEL = "Distance [m]"; + + private DictionaryModel dictionaryModel; + + public NonUniformInterpolationTable(DictionaryModel dictionaryModel, String[] names) { + super(names); + this.dictionaryModel = dictionaryModel; + } + + @Override + protected void setupColumnNames() { + if (isVector()) { + this.columnNames = new String[] { DISTANCE_M_LABEL, names[0], names[1], names[2] }; + } else { + this.columnNames = new String[] { DISTANCE_M_LABEL, names[0] }; + } + } + + @Override + public void load() { + clear(); + Dictionary dict = dictionaryModel.getDictionary(); + if (dict.found(DATA_KEY)) { + if (dict.isList2(DATA_KEY)) { + // Fix for alpha1 which is read with DictionaryReader2 + loadTable(ListField2.convertToString(dict.getList2(DATA_KEY))); + } else { + loadTable(dict.lookup(DATA_KEY).trim()); + } + } + } + + @Override + public StringBuilder save() { + StringBuilder sb = super.save(); + dictionaryModel.getDictionary().add(DATA_KEY, sb.toString()); + dictionaryModel.getDictionary().remove(FILE_NAME_KEY); + return sb; + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/TimeVaryingComboBoxController.java b/src/eu/engys/gui/casesetup/boundaryconditions/TimeVaryingComboBoxController.java new file mode 100644 index 0000000..cd454d9 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/TimeVaryingComboBoxController.java @@ -0,0 +1,92 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.boundaryconditions; + +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.DATA_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FILE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TABLE_FILE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TABLE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.isTableFile; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryModel.DictionaryError; +import eu.engys.core.dictionary.model.DictionaryModel.DictionaryListener; +import eu.engys.util.ui.builder.JComboBoxController; + +public class TimeVaryingComboBoxController extends JComboBoxController { + private DictionaryModel model; + + public TimeVaryingComboBoxController(DictionaryModel model, final String dictionaryKey) { + super(); + this.model = model; + model.addDictionaryListener(new DictionaryListener() { + @Override + public void dictionaryChanged() throws DictionaryError { + Dictionary dict = TimeVaryingComboBoxController.this.model.getDictionary(); + if (isTableFile(dict, dictionaryKey)) { + setSelectedKey(FILE_KEY); + } else { + setSelectedKey(DATA_KEY); + } + } + }); + addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Dictionary dict = TimeVaryingComboBoxController.this.model.getDictionary(); + String key = getSelectedKey(); + if (key.equals(DATA_KEY)) { + fixData(dictionaryKey, dict); + } else if (key.equals(FILE_KEY)) { + fixFile(dictionaryKey, dict); + } + } + + private void fixData(final String dictionaryKey, Dictionary dict) { + if(dict.found(dictionaryKey)){ + dict.remove(dictionaryKey); + } + if(!dict.found(dictionaryKey + " " + TABLE_KEY)){ + dict.add(dictionaryKey + " " + TABLE_KEY, "()"); + } + } + + private void fixFile(final String dictionaryKey, Dictionary dict) { + if(dict.found(dictionaryKey + " " + TABLE_KEY)){ + dict.remove(dictionaryKey + " " + TABLE_KEY); + } + if(!dict.found(dictionaryKey)){ + dict.add(dictionaryKey, TABLE_FILE_KEY); + } + } + + }); + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/TimeVaryingInterpolationTable.java b/src/eu/engys/gui/casesetup/boundaryconditions/TimeVaryingInterpolationTable.java new file mode 100644 index 0000000..36e7f2d --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/TimeVaryingInterpolationTable.java @@ -0,0 +1,73 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.boundaryconditions; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.parser.ListField2; + +public class TimeVaryingInterpolationTable extends AbstractInterpolationTable { + + private DictionaryModel dictionaryModel; + private String dictionaryKey; + + public TimeVaryingInterpolationTable(DictionaryModel dictionaryModel, String dictionaryKey, String[] names) { + super(names); + this.dictionaryModel = dictionaryModel; + this.dictionaryKey = dictionaryKey; + } + + @Override + protected void setupColumnNames() { + if (isVector()) { + this.columnNames = new String[] { "Time Step [s]", names[0], names[1], names[2] }; + } else { + this.columnNames = new String[] { "Time Step [s]", names[0] }; + } + } + + @Override + public void load() { + clear(); + Dictionary dict = dictionaryModel.getDictionary(); + if (dict.found(dictionaryKey)) { + if (dict.isList2(dictionaryKey)) { + // Fix for alpha1 which is read with DictionaryReader2 + loadTable(ListField2.convertToString(dict.getList2(dictionaryKey))); + } else { + loadTable(dict.lookup(dictionaryKey)); + } + } + } + + @Override + public StringBuilder save() { + StringBuilder sb = super.save(); + dictionaryModel.getDictionary().add(dictionaryKey, sb.toString()); + return sb; + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/factories/CyclicFactory.java b/src/eu/engys/gui/casesetup/boundaryconditions/factories/CyclicFactory.java new file mode 100644 index 0000000..653bf10 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/factories/CyclicFactory.java @@ -0,0 +1,141 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.boundaryconditions.factories; + +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.BRIDGE_OVERLAP_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.COUPLING_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.COUPLING_LABEL; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.MATCH_TOLERANCE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.NEIGHBOUR_PATCH_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.ROTATIONAL_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.ROTATIONAL_LABEL; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.ROTATION_ANGLE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.ROTATION_AXIS_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.ROTATION_CENTRE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.SEPARATION_VECTOR_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.TRANSFORM_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.TRANSLATIONAL_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.TRANSLATIONAL_LABEL; +import static eu.engys.gui.casesetup.boundaryconditions.panels.AbstractCyclicAMISettingsPanel.WEIGHT_CORRECTION_KEY; +import eu.engys.core.dictionary.Dictionary; + +public class CyclicFactory { + + public static final String CYCLIC_AMI_KEY = "cyclicAMI"; + public static final String CYCLIC_KEY = "cyclic"; + + public static final Dictionary BOUNDARY_CONDITION = new Dictionary("patch") { + { + add(TYPE, CYCLIC_KEY); + add(VALUE, "uniform 0"); + } + }; + + public static final Dictionary BOUNDARY_CONDITION_VECTOR = new Dictionary("patch") { + { + add(TYPE, CYCLIC_KEY); + add(VALUE, "uniform (0 0 0)"); + } + }; + + public static final Dictionary CYCLIC = new Dictionary("patch") { + { + add(TYPE, CYCLIC_KEY); + add(MATCH_TOLERANCE_KEY, "0.0001"); + add(NEIGHBOUR_PATCH_KEY, ""); + } + }; + + public static final Dictionary AMI_BOUNDARY_CONDITION = new Dictionary("patch") { + { + add(TYPE, CYCLIC_AMI_KEY); + add(VALUE, "uniform 0"); + } + }; + + public static final Dictionary AMI_BOUNDARY_CONDITION_VECTOR = new Dictionary("patch") { + { + add(TYPE, CYCLIC_AMI_KEY); + add(VALUE, "uniform (0 0 0)"); + } + }; + + public static final Dictionary CYCLIC_AMI = new Dictionary("patch") { + { + add(TYPE, CYCLIC_AMI_KEY); + add(MATCH_TOLERANCE_KEY, "0.0001"); + add(NEIGHBOUR_PATCH_KEY, ""); + add(TRANSFORM_KEY, COUPLING_KEY); + add(BRIDGE_OVERLAP_KEY, "true"); + } + }; + + public static final Dictionary CYCLIC_AMI_OS = new Dictionary("patch") { + { + add(TYPE, CYCLIC_AMI_KEY); + add(MATCH_TOLERANCE_KEY, "0.0001"); + add(WEIGHT_CORRECTION_KEY, "0.2"); + add(NEIGHBOUR_PATCH_KEY, ""); + add(TRANSFORM_KEY, COUPLING_KEY); + add(BRIDGE_OVERLAP_KEY, "true"); + } + }; + + public static final Dictionary CYCLIC_AMI_COUPLING = new Dictionary("") { + { + add(TYPE, COUPLING_LABEL); + add(TRANSFORM_KEY, COUPLING_KEY); + } + }; + + public static final Dictionary CYCLIC_AMI_ROTATIONAL = new Dictionary("") { + { + add(TYPE, ROTATIONAL_LABEL); + add(TRANSFORM_KEY, ROTATIONAL_KEY); + add(ROTATION_AXIS_KEY, "(1 0 0)"); + add(ROTATION_CENTRE_KEY, "(0 0 0)"); + } + }; + + public static final Dictionary CYCLIC_AMI_ROTATIONAL_OS = new Dictionary("") { + { + add(TYPE, ROTATIONAL_LABEL); + add(TRANSFORM_KEY, ROTATIONAL_KEY); + add(ROTATION_AXIS_KEY, "(1 0 0)"); + add(ROTATION_CENTRE_KEY, "(0 0 0)"); + add(ROTATION_ANGLE_KEY, "30"); + } + }; + + public static final Dictionary CYCLIC_AMI_TRANSLATIONAL = new Dictionary("") { + { + add(TYPE, TRANSLATIONAL_LABEL); + add(TRANSFORM_KEY, TRANSLATIONAL_KEY); + add(SEPARATION_VECTOR_KEY, "(0 0 0)"); + } + }; + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/factories/PressureFactory.java b/src/eu/engys/gui/casesetup/boundaryconditions/factories/PressureFactory.java new file mode 100644 index 0000000..bc73fc9 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/factories/PressureFactory.java @@ -0,0 +1,135 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.factories; + +import static eu.engys.core.project.zero.fields.Fields.P; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.CLAMP_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FILE_NAME_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FIXED_FLUX_PRESSURE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FIXED_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FREESTREAM_PRESSURE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.OUT_OF_BOUNDS_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.PRESSURE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.RHO_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TABLE_FILE_COEFFS_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TABLE_FILE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TABLE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TOTAL_PRESSURE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.UNIFORM_TOTAL_PRESSURE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ZERO_GRADIENT_KEY; +import eu.engys.core.dictionary.Dictionary; + +public class PressureFactory { + + public static final Dictionary totalPressure = new Dictionary(P) { + { + add(TYPE, TOTAL_PRESSURE_KEY); + add(VALUE, "uniform 0"); + add("p0", "uniform 0"); + add("gamma", "1.4"); + } + }; + + public static final Dictionary uniformTotalPressure = new Dictionary(P) { + { + add(TYPE, UNIFORM_TOTAL_PRESSURE_KEY); + add(VALUE, "uniform 0"); + add(RHO_KEY, RHO_KEY); + add("gamma", "1.4"); + add("p0", "0"); + add(PRESSURE_KEY, TABLE_KEY + " ()"); + add(OUT_OF_BOUNDS_KEY, CLAMP_KEY); + } + }; + + public static final Dictionary fixedValuePressure_COMP = new Dictionary(P) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform 1e5"); + } + }; + + public static final Dictionary fixedValuePressure = new Dictionary(P) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform 0"); + } + }; + + public static final Dictionary staticValuePressure_COMP = new Dictionary(P) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform 1e5"); + } + }; + + public static final Dictionary staticValuePressure = new Dictionary(P) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform 0"); + } + }; + + public static final Dictionary zeroGradientPressure = new Dictionary(P) { + { + add(TYPE, ZERO_GRADIENT_KEY); + } + }; + + public static final Dictionary fixedFluxPressure = new Dictionary(P) { + { + add(TYPE, FIXED_FLUX_PRESSURE_KEY); + add(VALUE, "uniform 0"); + add(RHO_KEY, "rhok"); + } + }; + + public static final Dictionary freestreamPressure = new Dictionary(P) { + { + add(TYPE, FREESTREAM_PRESSURE_KEY); + } + }; + + // For Tests only + public static final Dictionary uniformTotalPressure_FILE = new Dictionary(P) { + { + add(TYPE, UNIFORM_TOTAL_PRESSURE_KEY); + add(VALUE, "uniform 0"); + add(RHO_KEY, RHO_KEY); + add("gamma", "1.4"); + add("p0", "0"); + add(PRESSURE_KEY, TABLE_FILE_KEY); + add(new Dictionary(TABLE_FILE_COEFFS_KEY) { + { + add(FILE_NAME_KEY, "\"\""); + add(OUT_OF_BOUNDS_KEY, CLAMP_KEY); + } + }); + } + }; + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/factories/StandardPhaseFactory.java b/src/eu/engys/gui/casesetup/boundaryconditions/factories/StandardPhaseFactory.java new file mode 100644 index 0000000..a5cf7ab --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/factories/StandardPhaseFactory.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.factories; + +import static eu.engys.core.project.zero.fields.Fields.ALPHA; +import eu.engys.core.dictionary.Dictionary; + +public class StandardPhaseFactory { + + public static final Dictionary fixedValueVelocity = new Dictionary(ALPHA) { + { + add("type", "fixedValue"); + add("value", "uniform 1"); + } + }; + + public static final Dictionary inletOutlet = new Dictionary(ALPHA) { + { + add("type", "inletOutlet"); + add("value", "uniform 0.1"); + add("inletValue", "uniform 0.1"); + } + }; + + public static final Dictionary zeroGradient = new Dictionary(ALPHA) { + { + add("type", "zeroGradient"); + } + }; + + public static final Dictionary calculated = new Dictionary(ALPHA) { + { + add("type", "calculated"); + } + }; +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/factories/StandardPressureFactory.java b/src/eu/engys/gui/casesetup/boundaryconditions/factories/StandardPressureFactory.java new file mode 100644 index 0000000..5ad5f1b --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/factories/StandardPressureFactory.java @@ -0,0 +1,43 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.factories; + +import eu.engys.core.dictionary.Dictionary; + +public class StandardPressureFactory extends PressureFactory { + + public static final Dictionary totalPressure = new Dictionary("p"){ + { + add("type", "totalPressure"); + add("value", "uniform 0"); + add("p0", "uniform 0"); + add("gamma", "0"); + add("rho", "rho"); + } + }; + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/factories/StandardVelocityFactory.java b/src/eu/engys/gui/casesetup/boundaryconditions/factories/StandardVelocityFactory.java new file mode 100644 index 0000000..ac34345 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/factories/StandardVelocityFactory.java @@ -0,0 +1,32 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.factories; + + +public class StandardVelocityFactory { + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/factories/TemperatureFactory.java b/src/eu/engys/gui/casesetup/boundaryconditions/factories/TemperatureFactory.java new file mode 100644 index 0000000..3e13d44 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/factories/TemperatureFactory.java @@ -0,0 +1,173 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.factories; + +import eu.engys.core.dictionary.Dictionary; + +public class TemperatureFactory { + + public static final Dictionary fixedValue = new Dictionary("T") { + { + add(TYPE, "fixedValue"); + add("value", "uniform 300"); + } + }; + + public static final Dictionary zeroGradient = new Dictionary("T") { + { + add(TYPE, "zeroGradient"); + } + }; + + public static final Dictionary advectiveTemperature = new Dictionary("T") { + { + add(TYPE, "advective"); + } + }; + + public static final Dictionary totalTemperature = new Dictionary("T") { + { + add(TYPE, "totalTemperature"); + add("value", "uniform 300"); + add("U", "U"); + add("phi", "phi"); + add("psi", "0"); + add("gamma", "1.4"); + add("T0", "uniform 300"); + } + + }; + + public static final Dictionary inletOutletTotalTemperature = new Dictionary("T") { + { + add(TYPE, "inletOutletTotalTemperature"); + add("value", "uniform 300"); + add("U", "U"); + add("phi", "phi"); + add("psi", "0"); + add("gamma", "1.4"); + add("T0", "uniform 300"); + } + + }; + + public static final Dictionary inletOutlet = new Dictionary("T") { + { + add(TYPE, "inletOutlet"); + add("value", "uniform 300"); + add("inletValue", "uniform 300"); + } + }; + + public static final Dictionary turbulentHeatFluxTemperature_FLUX = new Dictionary("T") { + { + add(TYPE, "incompressible::turbulentHeatFluxTemperature"); + add("value", "uniform 300"); + add("q", "uniform 10.0"); + add("heatSource", "flux"); + add("alphaEff", "kappaEff"); + add("Cp", "Cp0"); + } + }; + + public static final Dictionary turbulentHeatFluxTemperature_FLUX_COMP = new Dictionary("T") { + { + add(TYPE, "compressible::turbulentHeatFluxTemperature"); + add("value", "uniform 300"); + add("q", "uniform 10.0"); + add("heatSource", "flux"); + add("kappa", "fluidThermo"); + add("kappaName", "default"); + } + }; + + public static final Dictionary turbulentHeatFluxTemperatureOCFD_FLUX = new Dictionary("T") { + { + add(TYPE, "turbulentHeatFluxTemperature"); + add("value", "uniform 300"); + add("q", "uniform 10.0"); + add("heatSource", "flux"); + add("alphaEff", "alphaEff"); + } + }; + + public static final Dictionary turbulentHeatFluxTemperatureOCFD_FLUX_COMP = new Dictionary("T") { + { + add(TYPE, "compressible::turbulentHeatFluxTemperature"); + add("value", "uniform 300"); + add("q", "uniform 10.0"); + add("heatSource", "flux"); + add("kappa", "fluidThermo"); + add("kappaName", "default"); + add("Qr", "none"); + } + }; + + public static final Dictionary turbulentHeatFluxTemperature_POWER = new Dictionary("T") { + { + add(TYPE, "incompressible::turbulentHeatFluxTemperature"); + add("value", "uniform 300"); + add("q", "uniform 10.0"); + add("heatSource", "power"); + add("alphaEff", "kappaEff"); + add("Cp", "Cp0"); + } + }; + + public static final Dictionary turbulentHeatFluxTemperatureOCFD_POWER = new Dictionary("T") { + { + add(TYPE, "turbulentHeatFluxTemperature"); + add("value", "uniform 300"); + add("q", "uniform 10.0"); + add("heatSource", "power"); + add("alphaEff", "alphaEff"); + } + }; + + public static final Dictionary turbulentHeatFluxTemperature_POWER_COMP = new Dictionary("T") { + { + add(TYPE, "compressible::turbulentHeatFluxTemperature"); + add("value", "uniform 300"); + add("q", "uniform 10.0"); + add("heatSource", "power"); + add("kappa", "fluidThermo"); + add("kappaName", "none"); + } + }; + + public static final Dictionary turbulentHeatFluxTemperatureOCFD_POWER_COMP = new Dictionary("T") { + { + add(TYPE, "compressible::turbulentHeatFluxTemperature"); + add("value", "uniform 300"); + add("q", "uniform 10.0"); + add("heatSource", "power"); + add("kappa", "fluidThermo"); + add("kappaName", "default"); + add("Qr", "none"); + } + }; +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/factories/TurbulenceFactory.java b/src/eu/engys/gui/casesetup/boundaryconditions/factories/TurbulenceFactory.java new file mode 100644 index 0000000..123f71c --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/factories/TurbulenceFactory.java @@ -0,0 +1,303 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.factories; + +import static eu.engys.core.project.zero.fields.Fields.EPSILON; +import static eu.engys.core.project.zero.fields.Fields.K; +import static eu.engys.core.project.zero.fields.Fields.MUT; +import static eu.engys.core.project.zero.fields.Fields.MU_SGS; +import static eu.engys.core.project.zero.fields.Fields.NUT; +import static eu.engys.core.project.zero.fields.Fields.NU_SGS; +import static eu.engys.core.project.zero.fields.Fields.NU_TILDA; +import static eu.engys.core.project.zero.fields.Fields.OMEGA; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.CLAMP_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.COMPRESSIBLE_TURBULENT_MIXING_LENGTH_DISSIPATION_RATE_INLET_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.COMPRESSIBLE_TURBULENT_MIXING_LENGTH_FREQUENCY_INLET_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.CS_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FIXED_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.INLET_OUTLET_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.INLET_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.INTENSITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.KS_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.LENGTH_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.MIXING_LENGTH_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.MUT_K_ROUGH_WALL_FUNCTION_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.MUT_U_ROUGH_WALL_FUNCTION_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.NUT_K_ATM_ROUGH_WALL_FUNCTION_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.NUT_K_ROUGH_WALL_FUNCTION_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.NUT_TURBULENT_INTENSITY_LENGTH_SCALE_INLET_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.NUT_U_ROUGH_WALL_FUNCTION_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.OUT_OF_BOUNDS_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ROUGHNESS_CONSTANT_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ROUGHNESS_FACTOR_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ROUGHNESS_HEIGHT_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TABLE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TURBULENT_INTENSITY_KINETIC_ENERGY_INLET_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TURBULENT_MIXING_LENGTH_DISSIPATION_RATE_INLET_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.TURBULENT_MIXING_LENGTH_FREQUENCY_INLET_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.UNIFORM_FIXED_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.UNIFORM_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.Z0_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ZERO_GRADIENT_KEY; +import eu.engys.core.dictionary.Dictionary; + +public class TurbulenceFactory { + + /* + * Fixed + */ + + public static final Dictionary kFixedValue = new Dictionary(K) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform 0.01"); + } + }; + public static final Dictionary omegaFixedValue = new Dictionary(OMEGA) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform 0.01"); + } + }; + public static final Dictionary epsilonFixedValue = new Dictionary(EPSILON) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform 0.01"); + } + }; + public static final Dictionary nutildaFixedValue = new Dictionary(NU_TILDA) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform 0.01"); + } + }; + + /* + * Mixed + */ + public static final Dictionary kMixingLength = new Dictionary(K) { + { + add(TYPE, TURBULENT_INTENSITY_KINETIC_ENERGY_INLET_KEY); + add(VALUE, "uniform 0.01"); + add(INTENSITY_KEY, "0.05"); + } + }; + public static final Dictionary epsilonMixingLength = new Dictionary(EPSILON) { + { + add(TYPE, TURBULENT_MIXING_LENGTH_DISSIPATION_RATE_INLET_KEY); + add(VALUE, "uniform 0.01"); + add(MIXING_LENGTH_KEY, "0.01"); + } + }; + public static final Dictionary epsilonMixingLength_COMP = new Dictionary(EPSILON) { + { + add(TYPE, COMPRESSIBLE_TURBULENT_MIXING_LENGTH_DISSIPATION_RATE_INLET_KEY); + add(VALUE, "uniform 0.01"); + add(MIXING_LENGTH_KEY, "0.01"); + } + }; + public static final Dictionary omegaMixingLength = new Dictionary(OMEGA) { + { + add(TYPE, TURBULENT_MIXING_LENGTH_FREQUENCY_INLET_KEY); + add(VALUE, "uniform 0.01"); + add(MIXING_LENGTH_KEY, "0.01"); + } + }; + public static final Dictionary omegaMixingLength_COMP = new Dictionary(OMEGA) { + { + add(TYPE, COMPRESSIBLE_TURBULENT_MIXING_LENGTH_FREQUENCY_INLET_KEY); + add(VALUE, "uniform 0.01"); + add(MIXING_LENGTH_KEY, "0.01"); + } + }; + public static final Dictionary nuTildaMixingLength = new Dictionary(NU_TILDA) { + { + add(TYPE, NUT_TURBULENT_INTENSITY_LENGTH_SCALE_INLET_KEY); + add(VALUE, "uniform 0.01"); + add(INTENSITY_KEY, "0.05"); + add(LENGTH_KEY, "0.01"); + } + }; + + /* + * Time-varying + */ + public static final Dictionary kTimeVarying = new Dictionary(K) { + { + add(TYPE, UNIFORM_FIXED_VALUE_KEY); + add(VALUE, "uniform 0.01"); + add(UNIFORM_VALUE_KEY, TABLE_KEY + " ()"); + add(OUT_OF_BOUNDS_KEY, CLAMP_KEY); + } + }; + public static final Dictionary omegaTimeVarying = new Dictionary(OMEGA) { + { + add(TYPE, UNIFORM_FIXED_VALUE_KEY); + add(VALUE, "uniform 0.01"); + add(UNIFORM_VALUE_KEY, TABLE_KEY + " ()"); + add(OUT_OF_BOUNDS_KEY, CLAMP_KEY); + } + }; + public static final Dictionary epsilonTimeVarying = new Dictionary(EPSILON) { + { + add(TYPE, UNIFORM_FIXED_VALUE_KEY); + add(VALUE, "uniform 0.01"); + add(UNIFORM_VALUE_KEY, TABLE_KEY + " ()"); + add(OUT_OF_BOUNDS_KEY, CLAMP_KEY); + } + }; + public static final Dictionary nuTildaTimeVarying = new Dictionary(NU_TILDA) { + { + add(TYPE, UNIFORM_FIXED_VALUE_KEY); + add(VALUE, "uniform 0.01"); + add(UNIFORM_VALUE_KEY, TABLE_KEY + " ()"); + add(OUT_OF_BOUNDS_KEY, CLAMP_KEY); + } + }; + + /* + * Inlet outlet + */ + + public static final Dictionary kInletOutlet = new Dictionary(K) { + { + add(TYPE, INLET_OUTLET_KEY); + add(VALUE, "uniform 0.01"); + add(INLET_VALUE_KEY, "uniform 0.01"); + } + }; + public static final Dictionary omegaInletOutlet = new Dictionary(OMEGA) { + { + add(TYPE, INLET_OUTLET_KEY); + add(VALUE, "uniform 0.01"); + add(INLET_VALUE_KEY, "uniform 0.01"); + } + }; + public static final Dictionary epsilonInletOutlet = new Dictionary(EPSILON) { + { + add(TYPE, INLET_OUTLET_KEY); + add(VALUE, "uniform 0.01"); + add(INLET_VALUE_KEY, "uniform 0.01"); + } + }; + public static final Dictionary nuTildaInletOutlet = new Dictionary(NU_TILDA) { + { + add(TYPE, INLET_OUTLET_KEY); + add(VALUE, "uniform 0.01"); + add(INLET_VALUE_KEY, "uniform 0.01"); + } + }; + + /* + * Zero Gradient + */ + public static final Dictionary kZeroGradient = new Dictionary(K) { + { + add(TYPE, ZERO_GRADIENT_KEY); + } + }; + public static final Dictionary omegaZeroGradient = new Dictionary(OMEGA) { + { + add(TYPE, ZERO_GRADIENT_KEY); + } + }; + public static final Dictionary epsilonZeroGradient = new Dictionary(EPSILON) { + { + add(TYPE, ZERO_GRADIENT_KEY); + } + }; + public static final Dictionary nuTildaZeroGradient = new Dictionary(NU_TILDA) { + { + add(TYPE, ZERO_GRADIENT_KEY); + } + }; + + /* + * Wall + */ + public static final Dictionary nutkRoughWallFunction = new Dictionary(NUT) { + { + add(TYPE, NUT_K_ROUGH_WALL_FUNCTION_KEY); + add(VALUE, "uniform 0"); + add(KS_KEY, "uniform 0"); + add(CS_KEY, "uniform 0.5"); + } + }; + public static final Dictionary nutkAtmRoughWallFunction = new Dictionary(NUT) { + { + add(TYPE, NUT_K_ATM_ROUGH_WALL_FUNCTION_KEY); + add(VALUE, "uniform 0"); + add(Z0_KEY, "uniform 0"); + } + }; + public static final Dictionary nutURoughWallFunction = new Dictionary(NUT) { + { + add(TYPE, NUT_U_ROUGH_WALL_FUNCTION_KEY); + add(VALUE, "uniform 0"); + add(ROUGHNESS_HEIGHT_KEY, "1e-5"); + add(ROUGHNESS_CONSTANT_KEY, "0.5"); + add(ROUGHNESS_FACTOR_KEY, "1"); + } + }; + public static final Dictionary nuSgsURoughWallFunction = new Dictionary(NU_SGS) { + { + add(TYPE, NUT_U_ROUGH_WALL_FUNCTION_KEY); + add(VALUE, "uniform 0"); + add(ROUGHNESS_HEIGHT_KEY, "1e-5"); + add(ROUGHNESS_CONSTANT_KEY, "0.5"); + add(ROUGHNESS_FACTOR_KEY, "1"); + } + }; + + public static final Dictionary mutKRoughWallFunction = new Dictionary(MUT) { + { + add(TYPE, MUT_K_ROUGH_WALL_FUNCTION_KEY); + add(VALUE, "uniform 0"); + add(KS_KEY, "uniform 0"); + add(CS_KEY, "uniform 0.5"); + } + }; + public static final Dictionary mutURoughWallFunction = new Dictionary(MUT) { + { + add(TYPE, MUT_U_ROUGH_WALL_FUNCTION_KEY); + add(VALUE, "uniform 0"); + add(ROUGHNESS_HEIGHT_KEY, "1e-5"); + add(ROUGHNESS_CONSTANT_KEY, "0.5"); + add(ROUGHNESS_FACTOR_KEY, "1"); + } + }; + public static final Dictionary muSgsURoughWallFunction = new Dictionary(MU_SGS) { + { + add(TYPE, MUT_U_ROUGH_WALL_FUNCTION_KEY); + add(VALUE, "uniform 0"); + add(ROUGHNESS_HEIGHT_KEY, "1e-5"); + add(ROUGHNESS_CONSTANT_KEY, "0.5"); + add(ROUGHNESS_FACTOR_KEY, "1"); + } + }; + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/factories/VelocityFactory.java b/src/eu/engys/gui/casesetup/boundaryconditions/factories/VelocityFactory.java new file mode 100644 index 0000000..2f03cca --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/factories/VelocityFactory.java @@ -0,0 +1,245 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.factories; + +import static eu.engys.core.project.zero.fields.Fields.U; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ACCOMMODATION_COEFFICIENT_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ADVECTIVE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ALPHA_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.AXIS_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.CYLINDRICAL_INLET_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FIXED_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FLOW_RATE_INLET_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FLOW_RATE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FLUX_CORRECTED_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FREESTREAM_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.FREESTREAM_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.INLET_DIRECTION_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.INLET_OUTLET_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.INLET_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.MASS_FLOW_RATE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.MAXWELL_SLIP_U_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.MOVING_WALL_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.NO_SLIP_WALL_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.PHI_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.PRESSURE_DIRECT_INLET_OUTLET_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.PRESSURE_DIRECT_INLET_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.PRESSURE_INLET_OUTLET_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.PRESSURE_INLET_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.REF_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.RHO_INLET_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.RHO_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ROTATING_WALL_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.SLIP_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.SLIP_WALL_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.SURFACE_NORMAL_FIXED_VALUE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.UWALL; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.VARIABLE_HEIGHT_FLOW_RATE_INLET_VELOCITY_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.VOLUMETRIC_FLOW_RATE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.ZERO_GRADIENT_KEY; +import eu.engys.core.dictionary.Dictionary; + +public class VelocityFactory { + + public static final Dictionary fixedValueVelocity = new Dictionary(U) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform (0 0 0)"); + } + }; + public static final Dictionary movingWallVelocity = new Dictionary(U) { + { + add(TYPE, MOVING_WALL_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + } + }; + public static final Dictionary zeroGradientVelocity = new Dictionary(U) { + { + add(TYPE, ZERO_GRADIENT_KEY); + add(VALUE, "uniform (0 0 0)"); + } + }; + public static final Dictionary advectiveVelocity = new Dictionary(U) { + { + add(TYPE, ADVECTIVE_KEY); + } + }; + public static final Dictionary inletOutletVelocity = new Dictionary(U) { + { + add(TYPE, INLET_OUTLET_KEY); + add(VALUE, "uniform (0 0 0)"); + add(INLET_VALUE_KEY, "uniform (0 0 0)"); + } + }; + public static final Dictionary cylindricalInletVelocity = new Dictionary(U) { + { + add(TYPE, CYLINDRICAL_INLET_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + add(AXIS_KEY, "(0 0 1)"); + add("centre", "(0 0 0)"); + add("axialVelocity", "30"); + add("rpm", "100"); + add("radialVelocity", "-10"); + } + }; + public static final Dictionary surfaceNormalFixedValue = new Dictionary(U) { + { + add(TYPE, SURFACE_NORMAL_FIXED_VALUE_KEY); + add(VALUE, "uniform (0 0 0)"); + add(REF_VALUE_KEY, "uniform -1.5"); + } + }; + + public static final Dictionary volumetricFlowRateInletVelocity = new Dictionary(U) { + { + add(TYPE, FLOW_RATE_INLET_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + add(VOLUMETRIC_FLOW_RATE_KEY, "0.1"); + } + }; + + public static final Dictionary massFlowRateInletVelocity = new Dictionary(U) { + { + add(TYPE, FLOW_RATE_INLET_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + add(MASS_FLOW_RATE_KEY, "0.1"); + add(RHO_KEY, "rho"); + } + }; + + public static final Dictionary massFlowRateInletVelocity_INCOMPRESSIBLE = new Dictionary(U) { + { + add(TYPE, FLOW_RATE_INLET_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + add(MASS_FLOW_RATE_KEY, "0.1"); + add(RHO_KEY, "rho"); + add(RHO_INLET_KEY, "1.0"); + } + }; + + public static final Dictionary variableHeightFlowRateInletVelocity = new Dictionary(U) { + { + add(TYPE, VARIABLE_HEIGHT_FLOW_RATE_INLET_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + add(FLOW_RATE_KEY, "0.2"); + add(ALPHA_KEY, "alpha.water"); + } + }; + + public static final Dictionary pressureInletVelocity = new Dictionary(U) { + { + add(TYPE, PRESSURE_INLET_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + } + }; + + public static final Dictionary fluxCorrectedVelocity = new Dictionary(U) { + { + add(TYPE, FLUX_CORRECTED_VELOCITY_KEY); + } + }; + + public static final Dictionary pressureDirectedInletVelocity = new Dictionary(U) { + { + add(TYPE, PRESSURE_DIRECT_INLET_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + add(INLET_DIRECTION_KEY, "(1 0 0)"); + } + }; + + public static final Dictionary pressureInletOutletVelocity = new Dictionary(U) { + { + add(TYPE, PRESSURE_INLET_OUTLET_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + } + }; + + public static final Dictionary pressureDirectedInletOutletVelocity = new Dictionary(U) { + { + add(TYPE, PRESSURE_DIRECT_INLET_OUTLET_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + add(INLET_DIRECTION_KEY, "(1 0 0)"); + } + }; + + public static final Dictionary freestreamVelocity = new Dictionary(U) { + { + add(TYPE, FREESTREAM_KEY); + add(VALUE, "uniform (0 0 0)"); + add(PHI_KEY, PHI_KEY); + add(FREESTREAM_VALUE_KEY, "uniform (0 0 0)"); + } + }; + + public static final Dictionary slipWall = new Dictionary(U) { + { + add(TYPE, SLIP_KEY); + } + }; + + public static final Dictionary slipWallCoupled = new Dictionary(U) { + { + add(TYPE, SLIP_WALL_KEY); + } + }; + + public static final Dictionary maxwellSlipWall = new Dictionary(U) { + { + add(TYPE, MAXWELL_SLIP_U_KEY); + add(VALUE, "uniform (0 0 0)"); + add(ACCOMMODATION_COEFFICIENT_KEY, "0.85"); + add("thermalCreep", "on"); + add("curvature", "on"); + add(UWALL, "uniform (0 0 0)"); + } + }; + + public static final Dictionary noSlipWall = new Dictionary(U) { + { + add(TYPE, FIXED_VALUE_KEY); + add(VALUE, "uniform (0 0 0)"); + } + }; + + public static final Dictionary noSlipWallCoupled = new Dictionary(U) { + { + add(TYPE, NO_SLIP_WALL_KEY); + add(VALUE, "uniform (0 0 0)"); + } + }; + + public static final Dictionary standardRotatingWallVelocity = new Dictionary(U) { + { + add(TYPE, ROTATING_WALL_VELOCITY_KEY); + add(VALUE, "uniform (0 0 0)"); + add("origin", "(0 0 0)"); + add("axis", "(1 0 0)"); + add("omega", "5"); + } + }; + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/AbstractBoundaryTypePanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/AbstractBoundaryTypePanel.java new file mode 100644 index 0000000..781b6fb --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/AbstractBoundaryTypePanel.java @@ -0,0 +1,341 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.modules.boundaryconditions.ParametersPanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.core.project.zero.patches.Patch; + +public abstract class AbstractBoundaryTypePanel extends JPanel implements BoundaryTypePanel { + + private static final Logger logger = LoggerFactory.getLogger(BoundaryTypePanel.class); + + private ParametersPanel momentumPanel; + private ParametersPanel turbulencePanel; + private ParametersPanel thermalPanel; + private ParametersPanel pScalarsPanel; + private ParametersPanel phasePanel; + + private Map indexes = new HashMap<>(); + private Map components = new HashMap<>(); + private Map parametersPanels = new HashMap<>(); + + private JTabbedPane tabPanel; + + protected final Model model; + + public AbstractBoundaryTypePanel(Model model) { + super(new BorderLayout()); + this.model = model; + } + + @Override + public void layoutPanel() { + tabPanel = new JTabbedPane(); + tabPanel.setName("boundary.conditions.tab"); + tabPanel.putClientProperty("Synthetica.tabbedPane.tabIndex", 0); + tabPanel.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + tabChanged(); + } + }); + add(tabPanel, BorderLayout.CENTER); + setName(getClass().getSimpleName()); + } + + @Override + public void addMomentumPanel(ParametersPanel momentumPanel) { + if (tabPanel.indexOfTab(MOMENTUM) < 0) { + this.momentumPanel = momentumPanel; + components.put(MOMENTUM, momentumPanel.getComponent()); + } + } + + @Override + public void addTurbulencePanel(ParametersPanel turbulencePanel) { + if (tabPanel.indexOfTab(TURBULENCE) < 0) { + this.turbulencePanel = turbulencePanel; + components.put(TURBULENCE, turbulencePanel.getComponent()); + } + } + + @Override + public void addThermalPanel(ParametersPanel thermalPanel) { + if (tabPanel.indexOfTab(THERMAL) < 0) { + this.thermalPanel = thermalPanel; + components.put(THERMAL, thermalPanel.getComponent()); + } + } + + protected void addPScalarsPanel(ParametersPanel pScalarsPanel) { + if (tabPanel.indexOfTab(PASSIVE_SCALARS) < 0) { + this.pScalarsPanel = pScalarsPanel; + components.put(PASSIVE_SCALARS, pScalarsPanel.getComponent()); + } + } + + protected void addPhasePanel(ParametersPanel phasePanel) { + if (tabPanel.indexOfTab(PHASE_FRACTION) < 0) { + this.phasePanel = phasePanel; + components.put(PHASE_FRACTION, phasePanel.getComponent()); + } + } + + @Override + public void addPanel(String name, ParametersPanel pPanel, int index) { + if (tabPanel.indexOfTab(name) < 0) { + components.put(name, pPanel.getComponent()); + if (index >= 0) + indexes.put(name, index); + parametersPanels.put(name, pPanel); + } + } + + @Override + public void addPanel(String name, ParametersPanel pPanel) { + addPanel(name, pPanel, -1); + } + + + private void tabChanged() { + int selectedIndex = tabPanel.getSelectedIndex(); + if (selectedIndex < 0) { + return; + } + String title = tabPanel.getTitleAt(selectedIndex); + if (model == null || model.getState() == null) { + return; + } + if (title.equals(MOMENTUM)) { + momentumPanel.tabChanged(model); + } else if (title.equals(THERMAL)) { + thermalPanel.tabChanged(model); + } else if (title.equals(TURBULENCE)) { + turbulencePanel.tabChanged(model); + } else if (title.equals(PASSIVE_SCALARS)) { + pScalarsPanel.tabChanged(model); + } else if (title.equals(PHASE_FRACTION)) { + phasePanel.tabChanged(model); + } else { + if (parametersPanels.containsKey(title)) { + parametersPanels.get(title).tabChanged(model); + } + } + } + + @Override + public void stateChanged() { + State state = model.getState(); + setEnabledAt(MOMENTUM, !state.getMultiphaseModel().isMultiphase()); + setEnabledAt(TURBULENCE, (state.getTurbulenceModel() != null && !state.getTurbulenceModel().getType().isLaminar())); + setEnabledAt(THERMAL, state.isEnergy()); + setEnabledAt(PHASE_FRACTION, state.getMultiphaseModel().isMultiphase()); + + for (String title : parametersPanels.keySet()) { + setEnabledAt(title, parametersPanels.get(title).isEnabled(model)); + } + + if (isEnabledAt(MOMENTUM)) + momentumPanel.stateChanged(model); + if (isEnabledAt(THERMAL)) + thermalPanel.stateChanged(model); + if (isEnabledAt(TURBULENCE)) + turbulencePanel.stateChanged(model); + if (isEnabledAt(PASSIVE_SCALARS)) + pScalarsPanel.stateChanged(model); + if (isEnabledAt(PHASE_FRACTION)) + phasePanel.stateChanged(model); + + for (String title : parametersPanels.keySet()) { + if (isEnabledAt(title)) + parametersPanels.get(title).stateChanged(model); + } + } + + @Override + public void resetToDefault() { + if (isEnabledAt(MOMENTUM)) + momentumPanel.resetToDefault(model); + if (isEnabledAt(THERMAL)) + thermalPanel.resetToDefault(model); + if (isEnabledAt(TURBULENCE)) + turbulencePanel.resetToDefault(model); + if (isEnabledAt(PASSIVE_SCALARS)) + pScalarsPanel.resetToDefault(model); + if (isEnabledAt(PHASE_FRACTION)) + phasePanel.resetToDefault(model); + + for (String title : parametersPanels.keySet()) { + if (isEnabledAt(title)) + parametersPanels.get(title).resetToDefault(model); + } + } + + @Override + public void materialsChanged() { + if (isEnabledAt(MOMENTUM)) + momentumPanel.materialsChanged(model); + if (isEnabledAt(PHASE_FRACTION)) + phasePanel.materialsChanged(model); + + for (String title : parametersPanels.keySet()) { + if (isEnabledAt(title)) { + parametersPanels.get(title).materialsChanged(model); + } + } + } + + private void setEnabledAt(String name, boolean enable) { + // System.out.println("AbstractBoundaryTypePanel.setEnabledAt() "+name+" is "+ + // (enable? "ENABLED" : "DISABLED")); + int index = tabPanel.indexOfTab(name); + if (enable && index < 0 && components.containsKey(name)) { + if (indexes.containsKey(name)) { + tabPanel.insertTab(name, null, components.get(name), null, indexes.get(name)); + } else { + tabPanel.addTab(name, components.get(name)); + } + } else if (!enable && index >= 0) { + tabPanel.removeTabAt(index); + } + } + + private boolean isEnabledAt(String name) { + int index = tabPanel.indexOfTab(name); + return index >= 0; + } + + @Override + public void loadFromPatches(Patch... patches) { + BoundaryConditions bc = patches[0].getBoundaryConditions(); + String patchName = patches[0].getName(); + if (bc != null) { + boolean multipleSelection = patches.length > 1; + // System.out.println("AbstractBoundaryTypePanel.loadFromPatches() multipleSelection: "+multipleSelection); + if (momentumPanel != null && isEnabledAt(MOMENTUM)) { + momentumPanel.setMultipleEditing(multipleSelection); + momentumPanel.loadFromBoundaryConditions(patchName, bc); + } + if (turbulencePanel != null && isEnabledAt(TURBULENCE)) { + turbulencePanel.setMultipleEditing(multipleSelection); + turbulencePanel.loadFromBoundaryConditions(patchName, bc); + } + if (thermalPanel != null && isEnabledAt(THERMAL)) { + thermalPanel.setMultipleEditing(multipleSelection); + thermalPanel.loadFromBoundaryConditions(patchName, bc); + } + if (pScalarsPanel != null && isEnabledAt(PASSIVE_SCALARS)) { + pScalarsPanel.setMultipleEditing(multipleSelection); + pScalarsPanel.loadFromBoundaryConditions(patchName, bc); + } + if (phasePanel != null && isEnabledAt(PHASE_FRACTION)) { + phasePanel.setMultipleEditing(multipleSelection); + phasePanel.loadFromBoundaryConditions(patchName, bc); + } + for (String title : parametersPanels.keySet()) { + if (isEnabledAt(title)) { + ParametersPanel parametersPanel = parametersPanels.get(title); + parametersPanel.setMultipleEditing(multipleSelection); + parametersPanel.loadFromBoundaryConditions(patchName, bc); + } + } + } else { + logger.warn("BoundaryConditions are null"); + } + } + + @Override + public void saveToPatch(Patch patch) { + if (patch.getBoundaryConditions() == null) { + patch.setBoundaryConditions(new BoundaryConditions()); + } + BoundaryConditions bc = patch.getBoundaryConditions(); + String patchName = patch.getName(); + if (momentumPanel != null && isEnabledAt(MOMENTUM) && momentumPanel.canEdit()) + momentumPanel.saveToBoundaryConditions(patchName, bc); + if (turbulencePanel != null && isEnabledAt(TURBULENCE) && turbulencePanel.canEdit()) + turbulencePanel.saveToBoundaryConditions(patchName, bc); + if (thermalPanel != null && isEnabledAt(THERMAL) && thermalPanel.canEdit()) + thermalPanel.saveToBoundaryConditions(patchName, bc); + if (pScalarsPanel != null && isEnabledAt(PASSIVE_SCALARS) && pScalarsPanel.canEdit()) + pScalarsPanel.saveToBoundaryConditions(patchName, bc); + if (phasePanel != null && isEnabledAt(PHASE_FRACTION) && phasePanel.canEdit()) + phasePanel.saveToBoundaryConditions(patchName, bc); + for (String title : parametersPanels.keySet()) { + if (isEnabledAt(title)) { + parametersPanels.get(title).saveToBoundaryConditions(patchName, bc); + } + } + } + + @Override + public Component getPanel() { + return this; + } + + @Override + public ParametersPanel getMomentumPanel() { + return momentumPanel; + } + + @Override + public ParametersPanel getTurbulencePanel() { + return turbulencePanel; + } + + @Override + public ParametersPanel getThermalPanel() { + return thermalPanel; + } + + @Override + public ParametersPanel getPanel(String name) { + return parametersPanels.get(name); + } + + public ParametersPanel getPhasePanel() { + return phasePanel; + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/AbstractCyclicAMISettingsPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/AbstractCyclicAMISettingsPanel.java new file mode 100644 index 0000000..33656ad --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/AbstractCyclicAMISettingsPanel.java @@ -0,0 +1,333 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.AMI_BOUNDARY_CONDITION; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.AMI_BOUNDARY_CONDITION_VECTOR; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.CYCLIC_AMI_COUPLING; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.CYCLIC_AMI_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.CYCLIC_AMI_TRANSLATIONAL; + +import java.awt.BorderLayout; +import java.awt.Component; + +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.modules.boundaryconditions.ParametersPanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Field.FieldType; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.core.project.zero.patches.BoundaryConditionsDefaults; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; + +public abstract class AbstractCyclicAMISettingsPanel extends JPanel implements BoundaryTypePanel { + + public static final String MATCH_TOLERANCE_KEY = "matchTolerance"; + public static final String NEIGHBOUR_PATCH_KEY = "neighbourPatch"; + public static final String SEPARATION_VECTOR_LABEL = "Separation Vector"; + public static final String SEPARATION_VECTOR_KEY = "separationVector"; + public static final String ROTATION_CENTRE_KEY = "rotationCentre"; + public static final String ROTATION_AXIS_KEY = "rotationAxis"; + public static final String TRANSFORM_KEY = "transform"; + public static final String COUPLING_KEY = "noOrdering"; + public static final String TRANSLATIONAL_KEY = "translational"; + public static final String ROTATIONAL_KEY = "rotational"; + public static final String ROTATION_ANGLE_KEY = "rotationAngle"; + public static final String WEIGHT_CORRECTION_KEY = "lowWeightCorrection"; + public static final String BRIDGE_OVERLAP_KEY = "bridgeOverlap"; + + public static final String ROTATION_ANGLE_LABEL = "Rotation [deg]"; + public static final String WEIGHT_CORRECTION_LABEL = "Weight Correction"; + public static final String TRANSFORM_LABEL = "Transform"; + public static final String COUPLING_LABEL = "Coupling"; + public static final String TRANSLATIONAL_LABEL = "Translational"; + public static final String ROTATIONAL_LABEL = "Rotational"; + public static final String CENTRE_LABEL = "Centre"; + public static final String AXIS_LABEL = "Axis"; + public static final String NEIGHBOUR_PATCH_LABEL = "Neighbour Patch"; + public static final String MATCH_TOLERANCE_LABEL = "Match Tolerance"; + + protected DictionaryModel cyclicModel; + protected DictionaryModel rotationalModel; + protected DictionaryModel couplingModel; + private DictionaryModel translationalModel; + + protected Model model; + + protected DictionaryPanelBuilder transformBuilder; + + public AbstractCyclicAMISettingsPanel(Model model) { + super(new BorderLayout()); + this.model = model; + this.cyclicModel = new DictionaryModel(); + this.couplingModel = new DictionaryModel(); + this.rotationalModel = new DictionaryModel(); + this.translationalModel = new DictionaryModel(); + } + + @Override + public void resetToDefault() { + this.couplingModel.setDictionary(new Dictionary(CYCLIC_AMI_COUPLING)); + this.translationalModel.setDictionary(new Dictionary(CYCLIC_AMI_TRANSLATIONAL)); + } + + @Override + public void layoutPanel() { + resetToDefault(); + + PanelBuilder builder = new PanelBuilder(); + + bindAmiParameters(builder); + + transformBuilder = new DictionaryPanelBuilder(); + transformBuilder.startChoice(TRANSFORM_LABEL); + + bindCouplingParameters(); + + bindRotationalParameters(); + + bindTranslationalParameters(); + + transformBuilder.endChoice(); + transformBuilder.selectDictionary(couplingModel.getDictionary()); + + builder.addFill(transformBuilder.removeMargins().getPanel()); + + add(builder.getPanel()); + } + + protected abstract void bindAmiParameters(PanelBuilder builder); + + private void bindCouplingParameters() { + transformBuilder.startDictionary(COUPLING_LABEL, couplingModel); + transformBuilder.endDictionary(); + } + + protected abstract void bindRotationalParameters(); + + private void bindTranslationalParameters() { + transformBuilder.startDictionary(TRANSLATIONAL_LABEL, translationalModel); + transformBuilder.addComponent(SEPARATION_VECTOR_LABEL, translationalModel.bindPoint(SEPARATION_VECTOR_KEY)); + transformBuilder.endDictionary(); + } + + @Override + public BoundaryType getType() { + return BoundaryType.CYCLIC_AMI; + } + + @Override + public Component getPanel() { + return this; + } + + @Override + public void saveToPatch(Patch patch) { + Dictionary cyclicDict = new Dictionary(cyclicModel.getDictionary()); + Dictionary transformDict = new Dictionary(transformBuilder.getSelectedModel().getDictionary()); + transformDict.remove(TYPE); + cyclicDict.merge(transformDict); + + patch.setBoundaryConditions(getAMIBoundaryConditions()); + Dictionary oldPatchDict = new Dictionary(patch.getDictionary()); + Dictionary oldPatchCyclicDict = extractCyclicDict(oldPatchDict); + oldPatchCyclicDict.merge(cyclicDict); + patch.setDictionary(oldPatchCyclicDict); + + updateNeighbourPatchDictionary(patch.getName(), oldPatchDict, cyclicDict); + } + + protected Dictionary extractCyclicDict(Dictionary dictionary) { + Dictionary cyclicDict = new Dictionary(dictionary); + cyclicDict.remove(TRANSFORM_KEY); + cyclicDict.remove(SEPARATION_VECTOR_KEY); + cyclicDict.remove(ROTATION_AXIS_KEY); + cyclicDict.remove(ROTATION_CENTRE_KEY); + return cyclicDict; + } + + protected Dictionary extractTransformDict(Dictionary dictionary) { + Dictionary transformDict = new Dictionary(""); + if (dictionary.found(TRANSFORM_KEY)) { + transformDict.add(TRANSFORM_KEY, dictionary.lookup(TRANSFORM_KEY)); + } + if (dictionary.found(SEPARATION_VECTOR_KEY)) { + transformDict.add(SEPARATION_VECTOR_KEY, dictionary.lookup(SEPARATION_VECTOR_KEY)); + } + if (dictionary.found(ROTATION_AXIS_KEY)) { + transformDict.add(ROTATION_AXIS_KEY, dictionary.lookup(ROTATION_AXIS_KEY)); + } + if (dictionary.found(ROTATION_CENTRE_KEY)) { + transformDict.add(ROTATION_CENTRE_KEY, dictionary.lookup(ROTATION_CENTRE_KEY)); + } + switch (dictionary.lookup(TRANSFORM_KEY)) { + case COUPLING_KEY: + transformDict.add(TYPE, COUPLING_LABEL); + break; + case ROTATIONAL_KEY: + transformDict.add(TYPE, ROTATIONAL_LABEL); + break; + case TRANSLATIONAL_KEY: + transformDict.add(TYPE, TRANSLATIONAL_LABEL); + break; + default: + transformDict.add(TYPE, COUPLING_LABEL); + break; + } + return transformDict; + } + + private BoundaryConditions getAMIBoundaryConditions() { + BoundaryConditions boundaryConditions = new BoundaryConditions(); + for (Field field : model.getFields().values()) { + if (field.getFieldType() == FieldType.SCALAR) { + boundaryConditions.add(field.getName(), new Dictionary(AMI_BOUNDARY_CONDITION)); + } else { + boundaryConditions.add(field.getName(), new Dictionary(AMI_BOUNDARY_CONDITION_VECTOR)); + } + } + return boundaryConditions; + } + + private void updateNeighbourPatchDictionary(String patchName, Dictionary oldDict, Dictionary newDict) { + Patch neighbourPatch = model.getPatches().patchesToDisplay().toMap().get(newDict.lookup(NEIGHBOUR_PATCH_KEY)); + if (neighbourPatch != null) { + fixPreviousRelatedNeighbourPatches(patchName, neighbourPatch.getName()); + setNeighbourPatchToAMI(patchName, newDict, neighbourPatch); + } else if (isAlreadyCyclicAMIWithoutNeighbour(oldDict)) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "No Neighbour Patch selected!\n", "Cyclic AMI Warning", JOptionPane.WARNING_MESSAGE); + } + } + + private void fixPreviousRelatedNeighbourPatches(String patchName, String neighbourPatchName) { + for (Patch p : model.getPatches().patchesToDisplay()) { + if (isRelatedPatch(p, patchName, neighbourPatchName)) { + setToDefaultType(p); + } + } + } + + private void setToDefaultType(Patch p) { + p.setPhisicalType(BoundaryType.getDefaultType()); + p.setBoundaryConditions(new BoundaryConditions(BoundaryConditionsDefaults.get(BoundaryType.getDefaultKey()))); + p.setDictionary(new Dictionary("")); + } + + private void setNeighbourPatchToAMI(String patchName, Dictionary newDict, Patch neighbourPatch) { + neighbourPatch.setBoundaryConditions(getAMIBoundaryConditions()); + neighbourPatch.setPhisicalType(BoundaryType.CYCLIC_AMI); + if (newDict.found(SEPARATION_VECTOR_KEY)) { + invertSeparationVector(newDict); + } + neighbourPatch.getDictionary().merge(newDict); + neighbourPatch.getDictionary().add(NEIGHBOUR_PATCH_KEY, patchName); + } + + private boolean isAlreadyCyclicAMIWithoutNeighbour(Dictionary dict) { + boolean notNull = dict != null; + boolean isCyclicAMI = dict.found(TYPE) && dict.lookup(TYPE).equals(CYCLIC_AMI_KEY); + boolean withoutNeighbour = dict.found(NEIGHBOUR_PATCH_KEY) && dict.lookup(NEIGHBOUR_PATCH_KEY).equals(""); + return notNull && isCyclicAMI && withoutNeighbour; + } + + private boolean isRelatedPatch(Patch p, String patchName, String neighbourPatchName) { + boolean isNotCurrentOrNeighbourPatch = !p.getName().equals(patchName) && !p.getName().equals(neighbourPatchName); + boolean isAMI = p.getPhisicalType().isCyclicAMI(); + boolean hasNeighbour = p.getDictionary() != null && p.getDictionary().found(NEIGHBOUR_PATCH_KEY); + if (hasNeighbour) { + boolean neighbourEqualsCurrentPatch = p.getDictionary().lookup(NEIGHBOUR_PATCH_KEY).equals(patchName); + boolean neighbourEqualsNeighbourPatch = p.getDictionary().lookup(NEIGHBOUR_PATCH_KEY).equals(neighbourPatchName); + return (isNotCurrentOrNeighbourPatch && isAMI && hasNeighbour && (neighbourEqualsCurrentPatch || neighbourEqualsNeighbourPatch)); + } + return false; + } + + private void invertSeparationVector(Dictionary d) { + String[] sepVector = d.lookupArray(SEPARATION_VECTOR_KEY); + StringBuilder sb = new StringBuilder("("); + for (String value : sepVector) { + double doubleValue = Double.parseDouble(value); + sb.append(-doubleValue + " "); + } + sb.append(")"); + d.add(SEPARATION_VECTOR_KEY, sb.toString()); + } + + @Override + public void stateChanged() { + } + + @Override + public void addMomentumPanel(ParametersPanel momentumPanel) { + } + + @Override + public void addTurbulencePanel(ParametersPanel momentumPanel) { + } + + @Override + public void addThermalPanel(ParametersPanel momentumPanel) { + } + + @Override + public void addPanel(String name, ParametersPanel pPanel) { + } + + @Override + public void addPanel(String name, ParametersPanel pPanel, int index) { + } + + @Override + public ParametersPanel getMomentumPanel() { + return null; + } + + @Override + public ParametersPanel getTurbulencePanel() { + return null; + } + + @Override + public ParametersPanel getThermalPanel() { + return null; + } + + @Override + public ParametersPanel getPanel(String name) { + return null; + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/AbstractParametersPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/AbstractParametersPanel.java new file mode 100644 index 0000000..69e87ac --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/AbstractParametersPanel.java @@ -0,0 +1,162 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.JCheckBox; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.modules.boundaryconditions.ParametersPanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryConditions; + +public abstract class AbstractParametersPanel extends JPanel implements ParametersPanel { + + private final JCheckBox allowEditing; + + protected final DictionaryPanelBuilder builder; + + private BoundaryTypePanel parentPanel; + + public AbstractParametersPanel(BoundaryTypePanel parent) { + super(new BorderLayout()); + this.parentPanel = parent; + + setName(getClass().getSimpleName()); + setOpaque(false); + + allowEditing = new JCheckBox(new AbstractAction("Allow Multiple Patches Editing") { + @Override + public void actionPerformed(ActionEvent e) { + builder.setEnabled(allowEditing.isSelected()); + canEdit = allowEditing.isSelected(); + } + }); + allowEditing.setFont(allowEditing.getFont().deriveFont(allowEditing.getFont().getSize2D() - 2)); + allowEditing.setOpaque(false); + + builder = new DictionaryPanelBuilder(); + + add(allowEditing, BorderLayout.NORTH); + add(builder.removeMargins().getPanel(), BorderLayout.CENTER); + init(); + populatePanel(); + } + + protected abstract void init(); + + protected abstract void populatePanel(); + + @Override + public JPanel getComponent() { + return this; + } + + public BoundaryTypePanel getParentPanel() { + return parentPanel; + } + + @Override + public void stateChanged(Model model) { + } + + @Override + public void materialsChanged(Model model) { + } + + @Override + public void tabChanged(Model model) { + } + + public void loadFromDictionary(Dictionary dictionary) { + } + + public void saveToDictionary(Dictionary dictionary) { + saveToDictionary(dictionary, builder); + } + + public static final void saveToDictionary(Dictionary dictionary, DictionaryPanelBuilder builder) { + DictionaryModel model = builder.getSelectedModel(); + if (model != null) { + Dictionary selected = new Dictionary(model.getDictionary()); +// System.out.println("AbstractParametersPanel.saveToDictionary() ---------"+selected.getName()+"--------- "); +// System.out.println("AbstractParametersPanel.saveToDictionary() ---------"+selected+"--------- "); + dictionary.add(selected); + for (DictionaryModel companion : model.getCompanions()) { + // System.out.println("AbstractParametersPanel.saveToDictionary() companion is "+companion.getDictionary().getName()); + dictionary.add(new Dictionary(companion.getDictionary())); + } + } + } + + public abstract void saveToBoundaryConditions(String patchName, BoundaryConditions bc); + + public abstract void loadFromBoundaryConditions(String patchName, BoundaryConditions bc); + + private boolean canEdit = false; + + @Override + public void setMultipleEditing(boolean multipleSelection) { + builder.setEnabled(!multipleSelection); + allowEditing.setVisible(multipleSelection); + allowEditing.setSelected(false); + canEdit = !multipleSelection; + } + + @Override + public boolean canEdit() { + return canEdit; + } + + @Override + public DictionaryModel getDictionaryModel() { + return builder.getSelectedModel(); + } + +// @Override +// public void selectDictionary(Dictionary dictionary) { +// builder.selectDictionary(dictionary); +// } +// +// @Override +// public void selectDictionaryByModel(DictionaryModel model, Dictionary dict) { +// builder.selectDictionaryByKey(model.getKey(), dict); +// } +// +// @Override +// public void selectDictionaries(Dictionary dictionary, Dictionary companion) { +// builder.selectDictionaries(dictionary, companion); +// } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/CyclicSettingsPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/CyclicSettingsPanel.java new file mode 100644 index 0000000..a816212 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/CyclicSettingsPanel.java @@ -0,0 +1,168 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels; + +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.BOUNDARY_CONDITION; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.BOUNDARY_CONDITION_VECTOR; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.CYCLIC; + +import java.awt.BorderLayout; +import java.awt.Component; + +import javax.inject.Inject; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.modules.boundaryconditions.ParametersPanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Field.FieldType; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.gui.ListBuilderFactory; +import eu.engys.util.ui.builder.PanelBuilder; + +public class CyclicSettingsPanel extends JPanel implements BoundaryTypePanel { + + private DictionaryModel cyclicModel; + + private Model model; + + @Inject + public CyclicSettingsPanel(Model model) { + super(new BorderLayout()); + this.model = model; + this.cyclicModel = new DictionaryModel(); + } + + @Override + public void resetToDefault() { + cyclicModel.setDictionary(new Dictionary(CYCLIC)); + } + + @Override + public void layoutPanel() { + PanelBuilder builder = new PanelBuilder(); + cyclicModel.setDictionary(new Dictionary(CYCLIC)); + builder.addComponent("Match Tolerance", cyclicModel.bindDouble("matchTolerance")); + builder.addComponent("Neighbour Patch", cyclicModel.bindSelection("neighbourPatch", ListBuilderFactory.getPatchesListBuilder(model))); + add(builder.getPanel()); + } + + @Override + public BoundaryType getType() { + return BoundaryType.CYCLIC; + } + + @Override + public Component getPanel() { + return this; + } + + @Override + public void loadFromPatches(Patch... patches) { + if (patches.length == 1) { + Dictionary dictionary = patches[0].getDictionary(); + if (dictionary.found(Dictionary.TYPE) && dictionary.lookup(Dictionary.TYPE).equals("cyclic")) { + cyclicModel.setDictionary(dictionary); + } else { + cyclicModel.setDictionary(new Dictionary(CYCLIC)); + } + } + } + + @Override + public void saveToPatch(Patch patch) { + Dictionary newDict = cyclicModel.getDictionary(); + + patch.setBoundaryConditions(getBoundaryConditions()); + patch.getDictionary().merge(newDict); + } + + private BoundaryConditions getBoundaryConditions() { + BoundaryConditions boundaryConditions = new BoundaryConditions(); + for (Field field : model.getFields().values()) { + if (field.getFieldType() == FieldType.SCALAR) { + boundaryConditions.add(field.getName(), new Dictionary(BOUNDARY_CONDITION)); + } else { + boundaryConditions.add(field.getName(), new Dictionary(BOUNDARY_CONDITION_VECTOR)); + } + } + return boundaryConditions; + } + + @Override + public void stateChanged() { + } + + @Override + public void materialsChanged() { + } + + @Override + public void addMomentumPanel(ParametersPanel momentumPanel) { + } + + @Override + public void addTurbulencePanel(ParametersPanel momentumPanel) { + } + + @Override + public void addThermalPanel(ParametersPanel momentumPanel) { + } + + @Override + public ParametersPanel getMomentumPanel() { + return null; + } + + @Override + public ParametersPanel getTurbulencePanel() { + return null; + } + + @Override + public ParametersPanel getThermalPanel() { + return null; + } + + @Override + public ParametersPanel getPanel(String name) { + return null; + } + + @Override + public void addPanel(String name, ParametersPanel pPanel) { + } + + @Override + public void addPanel(String name, ParametersPanel pPanel, int index) { + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/MomentumParametersPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/MomentumParametersPanel.java new file mode 100644 index 0000000..cb2a1d7 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/MomentumParametersPanel.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryConditions; + +public abstract class MomentumParametersPanel extends AbstractParametersPanel { + + public MomentumParametersPanel(BoundaryTypePanel parent) { + super(parent); + } + + @Override + public String getTitle() { + return "Momentum"; + } + + public boolean isEnabled(Model model) { + return true; + } + + @Override + public void loadFromBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getMomentum(); + loadFromDictionary(dictionary); + } + + @Override + public void saveToBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getMomentum(); + saveToDictionary(dictionary); + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/PhaseParametersPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/PhaseParametersPanel.java new file mode 100644 index 0000000..75a7320 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/PhaseParametersPanel.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.patches.BoundaryConditions; + +public abstract class PhaseParametersPanel extends AbstractParametersPanel { + + public PhaseParametersPanel(BoundaryTypePanel parent) { + super(parent); + } + + @Override + public String getTitle() { + return AbstractBoundaryTypePanel.PHASE_FRACTION; + } + + public boolean isEnabled(Model model) { + State state = model.getState(); + return state.getMultiphaseModel().isMultiphase(); + } + + @Override + public void saveToBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getPhase(); + saveToDictionary(dictionary); + } + + @Override + public void loadFromBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getPhase(); + loadFromDictionary(dictionary); + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/StandardCyclicAMISettingsPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/StandardCyclicAMISettingsPanel.java new file mode 100644 index 0000000..139ee3f --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/StandardCyclicAMISettingsPanel.java @@ -0,0 +1,108 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.CYCLIC_AMI_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.CYCLIC_AMI_OS; +import static eu.engys.gui.casesetup.boundaryconditions.factories.CyclicFactory.CYCLIC_AMI_ROTATIONAL_OS; + +import javax.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.gui.ListBuilderFactory; +import eu.engys.util.ui.builder.PanelBuilder; + +public class StandardCyclicAMISettingsPanel extends AbstractCyclicAMISettingsPanel { + + @Inject + public StandardCyclicAMISettingsPanel(Model model) { + super(model); + } + + @Override + public void resetToDefault() { + super.resetToDefault(); + this.cyclicModel.setDictionary(new Dictionary(CYCLIC_AMI_OS)); + this.rotationalModel.setDictionary(new Dictionary(CYCLIC_AMI_ROTATIONAL_OS)); + } + + @Override + protected void bindAmiParameters(PanelBuilder builder) { + builder.addComponent(MATCH_TOLERANCE_LABEL, cyclicModel.bindDouble(MATCH_TOLERANCE_KEY)); + builder.addComponent(WEIGHT_CORRECTION_LABEL, cyclicModel.bindDouble(WEIGHT_CORRECTION_KEY)); + builder.addComponent(NEIGHBOUR_PATCH_LABEL, cyclicModel.bindSelection(NEIGHBOUR_PATCH_KEY, ListBuilderFactory.getPatchesListBuilder(model))); + } + + @Override + protected void bindRotationalParameters() { + transformBuilder.startDictionary(ROTATIONAL_LABEL, rotationalModel); + transformBuilder.addComponent(AXIS_LABEL, rotationalModel.bindPoint(ROTATION_AXIS_KEY)); + transformBuilder.addComponent(CENTRE_LABEL, rotationalModel.bindPoint(ROTATION_CENTRE_KEY)); + transformBuilder.addComponent(ROTATION_ANGLE_LABEL, rotationalModel.bindDoubleAngle_360(ROTATION_ANGLE_KEY)); + transformBuilder.endDictionary(); + } + + @Override + public void loadFromPatches(Patch... patches) { + if (patches.length == 1) { + Dictionary dictionary = patches[0].getDictionary(); + if (dictionary.found(TYPE) && dictionary.lookup(TYPE).equals(CYCLIC_AMI_KEY)) { + Dictionary cyclicDict = extractCyclicDict(dictionary); + Dictionary transformDict = extractTransformDict(dictionary); + cyclicModel.setDictionary(cyclicDict); + transformBuilder.selectDictionary(transformDict); + } else { + cyclicModel.setDictionary(new Dictionary(CYCLIC_AMI_OS)); + transformBuilder.selectDictionary(couplingModel.getDictionary()); + } + } + } + + @Override + protected Dictionary extractCyclicDict(Dictionary dictionary) { + Dictionary cyclicDict = super.extractCyclicDict(dictionary); + cyclicDict.remove(ROTATION_ANGLE_KEY); + return cyclicDict; + } + + @Override + protected Dictionary extractTransformDict(Dictionary dictionary) { + Dictionary transformDict = super.extractTransformDict(dictionary); + if (dictionary.found(ROTATION_ANGLE_KEY)) { + transformDict.add(ROTATION_ANGLE_KEY, dictionary.lookup(ROTATION_ANGLE_KEY)); + } + return transformDict; + } + + @Override + public void materialsChanged() { + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/ThermalParametersPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/ThermalParametersPanel.java new file mode 100644 index 0000000..3df271f --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/ThermalParametersPanel.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels; + +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.patches.BoundaryConditions; + +public abstract class ThermalParametersPanel extends AbstractParametersPanel { + + public ThermalParametersPanel(BoundaryTypePanel parent) { + super(parent); + } + + @Override + public String getTitle() { + return "Thermal"; + } + + public boolean isEnabled(Model model) { + State state = model.getState(); + return state.isEnergy(); + } + + @Override + public void saveToBoundaryConditions(String patchName, BoundaryConditions bc) { + saveToDictionary(bc.getThermal()); + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/TurbulenceParametersPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/TurbulenceParametersPanel.java new file mode 100644 index 0000000..2b011e4 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/TurbulenceParametersPanel.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels; + +import static eu.engys.gui.casesetup.boundaryconditions.utils.TurbulenceUtils.setKEpsilon; +import static eu.engys.gui.casesetup.boundaryconditions.utils.TurbulenceUtils.setKEquationEddy; +import static eu.engys.gui.casesetup.boundaryconditions.utils.TurbulenceUtils.setKOmega; +import static eu.engys.gui.casesetup.boundaryconditions.utils.TurbulenceUtils.setSpalartAllmaras; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.TurbulenceModelType; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.patches.BoundaryConditions; + +public abstract class TurbulenceParametersPanel extends AbstractParametersPanel { + + public static final String TURBULENCE = "Turbulence"; + private TurbulenceModelType type; + + public TurbulenceParametersPanel(BoundaryTypePanel parent) { + super(parent); + } + + @Override + public String getTitle() { + return TURBULENCE; + } + + public boolean isEnabled(Model model) { + State state = model.getState(); + return (state.getTurbulenceModel() != null && state.getTurbulenceModel().getType() != TurbulenceModelType.LAMINAR); + } + + @Override + public void stateChanged(Model model) { + TurbulenceModelType type = model.getState().getTurbulenceModel().getType(); + if (this.type == null || this.type != type) { + this.type = type; + if (type.isKepsilon()) { + setKEpsilon(builder); + } else if (type.isKomega()) { + setKOmega(builder); + } else if (type.isSpalartAllmaras()) { + setSpalartAllmaras(builder); + } else if (type.isKEquationeddy()) { + setKEquationEddy(builder); + } + } + } + + @Override + public void saveToBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getTurbulence(); + saveToDictionary(dictionary); + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/MomentumPatch.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/MomentumPatch.java new file mode 100644 index 0000000..99c9a18 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/MomentumPatch.java @@ -0,0 +1,421 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels.patch; + +import static eu.engys.core.project.zero.fields.Fields.P; +import static eu.engys.core.project.zero.fields.Fields.U; +import static eu.engys.gui.casesetup.boundaryconditions.factories.PressureFactory.fixedFluxPressure; +import static eu.engys.gui.casesetup.boundaryconditions.factories.PressureFactory.fixedValuePressure; +import static eu.engys.gui.casesetup.boundaryconditions.factories.PressureFactory.fixedValuePressure_COMP; +import static eu.engys.gui.casesetup.boundaryconditions.factories.PressureFactory.freestreamPressure; +import static eu.engys.gui.casesetup.boundaryconditions.factories.PressureFactory.zeroGradientPressure; +import static eu.engys.gui.casesetup.boundaryconditions.factories.StandardPressureFactory.totalPressure; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.cylindricalInletVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.fixedValueVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.freestreamVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.inletOutletVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.massFlowRateInletVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.pressureDirectedInletOutletVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.pressureDirectedInletVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.pressureInletOutletVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.pressureInletVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.surfaceNormalFixedValue; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.variableHeightFlowRateInletVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.volumetricFlowRateInletVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.zeroGradientVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.MASS_FLOW_RATE_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.VOLUMETRIC_FLOW_RATE_KEY; +import static eu.engys.util.Symbols.CUBE; +import static eu.engys.util.Symbols.M2_S2; +import static eu.engys.util.Symbols.PASCAL; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.gui.casesetup.boundaryconditions.panels.MomentumParametersPanel; +import eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils; +import eu.engys.util.Symbols; +import eu.engys.util.ui.builder.JComboBoxController; +import eu.engys.util.ui.textfields.DoubleField; + +public class MomentumPatch extends MomentumParametersPanel { + + public static final String TOTAL_PRESSURE_LABEL = "Total Pressure"; + public static final String INLET_OUTLET_VELOCITY_LABEL = "Inlet Outlet Velocity"; + public static final String FREESTREAM_LABEL = "Freestream"; + public static final String PRESSURE_DIRECTED_INLET_OUTLET_VELOCITY_LABEL = "Pressure Directed Inlet Outlet Velocity"; + public static final String PRESSURE_INLET_OUTLET_VELOCITY_LABEL = "Pressure Inlet Outlet Velocity"; + public static final String PRESSURE_DIRECTED_INLET_VELOCITY_LABEL = "Pressure Directed Inlet Velocity"; + public static final String PRESSURE_INLET_VELOCITY_LABEL = "Pressure Inlet Velocity"; + public static final String VOLUMETRIC_FLOW_RATE_INLET_LABEL = "Volumetric Flow Rate Inlet"; + public static final String VARIABLE_HEIGHT_FLOW_RATE_INLET_LABEL = "Variable Height Flow Rate Inlet"; + public static final String MASS_FLOW_RATE_INLET_LABEL = "Mass Flow Rate Inlet"; + public static final String SURFACE_NORMAL_FIXED_VALUE_LABEL = "Surface Normal Fixed Value"; + public static final String CYLINDRICAL_INLET_VELOCITY_LABEL = "Cylindrical Inlet Velocity"; + public static final String FIXED_VALUE_LABEL = "Fixed Value"; + public static final String ZERO_GRADIENT_LABEL = "Zero Gradient"; + public static final String FREESTREAM_PRESSURE_LABEL = "Freestream Pressure"; + public static final String FIXED_FLUX_PRESSURE_LABEL = "Fixed Flux Pressure"; + public static final String PRESSURE_COMP = "Pressure " + PASCAL; + public static final String PRESSURE_INCOMP = "Pressure " + M2_S2; + + private DictionaryPanelBuilder velocityBuilder; + private JComboBoxController velocityTypeChoice; + + private DictionaryPanelBuilder pressureBuilder; + private JComboBoxController pressureChoice; + + private JLabel totalPressureLabel; + private JLabel fixedPressureLabel; + + private DoubleField fixedPressureField; + private DoubleField totalPressureField; + + private DictionaryModel fixedValueVelocityModel; + private DictionaryModel cylindricalInletVelocityModel; + private DictionaryModel surfaceNormalFixedValuemodel; + private DictionaryModel massFlowRateModel; + private DictionaryModel variableHeightFlowRateModel; + private DictionaryModel volumetricFlowRateModel; + private DictionaryModel pressureInletVelocityModel; + private DictionaryModel pressureDirectedInletVelocityModel; + private DictionaryModel pressureInletOutletVelocityModel; + private DictionaryModel pressureDirectedInletOutletVelocityModel; + private DictionaryModel freeStreamVelocityModel; + private DictionaryModel inletOutletVelocityModel; + private DictionaryModel zeroGradientVelocityModel; + + private DictionaryModel fixedValuePressureModel; + private DictionaryModel fixedFluxPressureModel; + private DictionaryModel freestreamPressureModel; + private DictionaryModel totalPressureModel; + private DictionaryModel zeroGradientPressureModel; + + public MomentumPatch(BoundaryTypePanel parent) { + super(parent); + } + + @Override + protected void init() { + // Velocity + fixedValueVelocityModel = new DictionaryModel(); + cylindricalInletVelocityModel = new DictionaryModel(); + surfaceNormalFixedValuemodel = new DictionaryModel(); + massFlowRateModel = new DictionaryModel(); + volumetricFlowRateModel = new DictionaryModel(); + variableHeightFlowRateModel = new DictionaryModel(); + pressureInletVelocityModel = new DictionaryModel(); + pressureDirectedInletVelocityModel = new DictionaryModel(); + pressureInletOutletVelocityModel = new DictionaryModel(); + pressureDirectedInletOutletVelocityModel = new DictionaryModel(); + freeStreamVelocityModel = new DictionaryModel(); + inletOutletVelocityModel = new DictionaryModel(); + zeroGradientVelocityModel = new DictionaryModel(); + + // Pressure + fixedValuePressureModel = new DictionaryModel(); + fixedFluxPressureModel = new DictionaryModel(); + freestreamPressureModel = new DictionaryModel(); + totalPressureModel = new DictionaryModel(); + zeroGradientPressureModel = new DictionaryModel(); + } + + @Override + public void resetToDefault(Model model) { + // Velocity + fixedValueVelocityModel.setDictionary(new Dictionary(fixedValueVelocity)); + cylindricalInletVelocityModel.setDictionary(new Dictionary(cylindricalInletVelocity)); + surfaceNormalFixedValuemodel.setDictionary(new Dictionary(surfaceNormalFixedValue)); + variableHeightFlowRateModel.setDictionary(new Dictionary(variableHeightFlowRateInletVelocity)); + massFlowRateModel.setDictionary(new Dictionary(massFlowRateInletVelocity)); + volumetricFlowRateModel.setDictionary(new Dictionary(volumetricFlowRateInletVelocity)); + pressureInletVelocityModel.setDictionary(new Dictionary(pressureInletVelocity)); + pressureDirectedInletVelocityModel.setDictionary(new Dictionary(pressureDirectedInletVelocity)); + pressureInletOutletVelocityModel.setDictionary(new Dictionary(pressureInletOutletVelocity)); + pressureDirectedInletOutletVelocityModel.setDictionary(new Dictionary(pressureDirectedInletOutletVelocity)); + freeStreamVelocityModel.setDictionary(new Dictionary(freestreamVelocity)); + inletOutletVelocityModel.setDictionary(new Dictionary(inletOutletVelocity)); + zeroGradientVelocityModel.setDictionary(new Dictionary(zeroGradientVelocity)); + + // Pressure + updateFixedValuePressureModel(model); + totalPressureModel.setDictionary(new Dictionary(totalPressure)); + freestreamPressureModel.setDictionary(new Dictionary(freestreamPressure)); + fixedFluxPressureModel.setDictionary(new Dictionary(fixedFluxPressure)); + zeroGradientPressureModel.setDictionary(new Dictionary(zeroGradientPressure)); + + } + + @Override + public DictionaryModel getDictionaryModel() { + DictionaryModel velocityModel = velocityBuilder.getSelectedModel(); + velocityModel.setCompanion(pressureBuilder.getSelectedModel()); + return velocityModel; + } + + @Override + public void populatePanel() { + resetToDefault(null); + /* VELOCITY */ + velocityBuilder = new DictionaryPanelBuilder(); + velocityTypeChoice = (JComboBoxController) velocityBuilder.startChoice("Velocity Type"); + + buildFixedValueVelocity(); + buildCylindricalInletVelocity(); + buildSurfaceNormalFixedValue(); + buildMassFlowRate(); + buildVolumetricFlowRate(); + buildVariableHeightFlowRate(); + buildPressureInletVelocity(); + buildPressureDirectedInletVelocity(); + buildPressureInletOutletVelocity(); + buildPressureDirectedInletOutletVelocity(); + buildFreestream(); + buildInletOutlet(); + buildZeroGradientVelocity(); + velocityBuilder.endChoice(); + + /* PRESSURE */ + pressureBuilder = new DictionaryPanelBuilder(); + pressureChoice = (JComboBoxController) pressureBuilder.startChoice("Pressure Type"); + buildFixedValuePressure(); + buildTotalPressure(); + buildFreestreamPressure(); + buildBuoyantPressure(); + buildZeroGradientPressure(); + pressureBuilder.endChoice(); + + /* ---- */ + JPanel velocityPanel = velocityBuilder.getPanel(); + JPanel pressurePanel = pressureBuilder.getPanel(); + velocityPanel.setBorder(BorderFactory.createTitledBorder("Velocity")); + pressurePanel.setBorder(BorderFactory.createTitledBorder("Pressure")); + builder.addComponent(velocityPanel); + builder.addComponent(pressurePanel); + } + + /** + * VELOCITY + */ + private void buildFixedValueVelocity() { + velocityBuilder.startDictionary(FIXED_VALUE_LABEL, fixedValueVelocityModel); + BoundaryConditionsUtils.buildSimpleFixedVelocityPanel(velocityBuilder, fixedValueVelocityModel); + velocityBuilder.endDictionary(); + } + + private void buildCylindricalInletVelocity() { + velocityBuilder.startDictionary(CYLINDRICAL_INLET_VELOCITY_LABEL, cylindricalInletVelocityModel); + BoundaryConditionsUtils.buildFixedCylindricalVelocityPanel(velocityBuilder, cylindricalInletVelocityModel); + velocityBuilder.endDictionary(); + } + + private void buildSurfaceNormalFixedValue() { + velocityBuilder.startDictionary(SURFACE_NORMAL_FIXED_VALUE_LABEL, surfaceNormalFixedValuemodel); + velocityBuilder.addComponent("Velocity Magnitude " + Symbols.M_S, surfaceNormalFixedValuemodel.bindUniformDouble("refValue", -Double.MAX_VALUE, 0, 0)); + velocityBuilder.endDictionary(); + } + + private void buildMassFlowRate() { + velocityBuilder.startDictionary(MASS_FLOW_RATE_INLET_LABEL, massFlowRateModel); + velocityBuilder.addComponent("Mass Flow Rate [kg/s]", massFlowRateModel.bindConstantDouble("massFlowRate")); + velocityBuilder.endDictionary(); + } + + private void buildVolumetricFlowRate() { + velocityBuilder.startDictionary(VOLUMETRIC_FLOW_RATE_INLET_LABEL, volumetricFlowRateModel); + velocityBuilder.addComponent("Volumetric Flow Rate [m" + CUBE + "/s]", volumetricFlowRateModel.bindConstantDouble("volumetricFlowRate")); + velocityBuilder.endDictionary(); + } + + private void buildVariableHeightFlowRate() { + velocityBuilder.startDictionary(VARIABLE_HEIGHT_FLOW_RATE_INLET_LABEL, variableHeightFlowRateModel); + velocityBuilder.addComponent("Volumetric Flow Rate [m" + CUBE + "/s]", variableHeightFlowRateModel.bindDouble("flowRate")); + velocityBuilder.endDictionary(); + } + + public void buildPressureInletVelocity() { + velocityBuilder.startDictionary(PRESSURE_INLET_VELOCITY_LABEL, pressureInletVelocityModel); + velocityBuilder.endDictionary(); + } + + public void buildPressureDirectedInletVelocity() { + velocityBuilder.startDictionary(PRESSURE_DIRECTED_INLET_VELOCITY_LABEL, pressureDirectedInletVelocityModel); + velocityBuilder.addComponent("Inlet Direction", pressureDirectedInletVelocityModel.bindPoint("inletDirection")); + velocityBuilder.endDictionary(); + } + + public void buildPressureInletOutletVelocity() { + velocityBuilder.startDictionary(PRESSURE_INLET_OUTLET_VELOCITY_LABEL, pressureInletOutletVelocityModel); + velocityBuilder.endDictionary(); + } + + public void buildPressureDirectedInletOutletVelocity() { + velocityBuilder.startDictionary(PRESSURE_DIRECTED_INLET_OUTLET_VELOCITY_LABEL, pressureDirectedInletOutletVelocityModel); + velocityBuilder.addComponent("Inlet Direction", pressureDirectedInletOutletVelocityModel.bindPoint("inletDirection")); + velocityBuilder.endDictionary(); + } + + private void buildFreestream() { + velocityBuilder.startDictionary(FREESTREAM_LABEL, freeStreamVelocityModel); + BoundaryConditionsUtils.buildFreestreamVelocityPanel(velocityBuilder, freeStreamVelocityModel); + velocityBuilder.endDictionary(); + } + + public void buildInletOutlet() { + velocityBuilder.startDictionary(INLET_OUTLET_VELOCITY_LABEL, inletOutletVelocityModel); + velocityBuilder.addComponent("Inlet Value", inletOutletVelocityModel.bindUniformPoint("inletValue")); + velocityBuilder.endDictionary(); + } + + private void buildZeroGradientVelocity() { + velocityBuilder.startDictionary(ZERO_GRADIENT_LABEL, zeroGradientVelocityModel); + velocityBuilder.endDictionary(); + } + + /** + * PRESSURE + */ + private void buildFixedValuePressure() { + fixedPressureLabel = new JLabel(PRESSURE_INCOMP); + fixedPressureField = fixedValuePressureModel.bindUniformDouble("value"); + pressureBuilder.startDictionary(FIXED_VALUE_LABEL, fixedValuePressureModel); + pressureBuilder.addComponent(fixedPressureLabel, fixedPressureField); + pressureBuilder.endDictionary(); + } + + private void buildTotalPressure() { + totalPressureLabel = new JLabel(PRESSURE_INCOMP); + pressureBuilder.startDictionary(TOTAL_PRESSURE_LABEL, totalPressureModel); + totalPressureField = totalPressureModel.bindUniformDouble("p0"); + pressureBuilder.addComponent(totalPressureLabel, totalPressureField); + pressureBuilder.endDictionary(); + } + + private void buildFreestreamPressure() { + pressureBuilder.startDictionary(FREESTREAM_PRESSURE_LABEL, freestreamPressureModel); + pressureBuilder.endDictionary(); + } + + private void buildBuoyantPressure() { + pressureBuilder.startDictionary(FIXED_FLUX_PRESSURE_LABEL, fixedFluxPressureModel); + pressureBuilder.endDictionary(); + } + + private void buildZeroGradientPressure() { + pressureBuilder.startDictionary(ZERO_GRADIENT_LABEL, zeroGradientPressureModel); + pressureBuilder.endDictionary(); + } + + /** + * END + */ + + @Override + public void loadFromBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getMomentum(); + + if (dictionary.subDict(U) != null) { + Dictionary uDict = new Dictionary(dictionary.subDict(U)); + if (uDict.found(MASS_FLOW_RATE_KEY)) { + velocityBuilder.selectDictionaryByKey(massFlowRateModel.getKey(), uDict); + } else if (uDict.found(VOLUMETRIC_FLOW_RATE_KEY)) { + velocityBuilder.selectDictionaryByKey(volumetricFlowRateModel.getKey(), uDict); + } else { + velocityBuilder.selectDictionary(uDict); + } + } else { + velocityBuilder.selectDictionary(null); + } + + Dictionary p = dictionary.subDict(P); + if (p != null) { + pressureBuilder.selectDictionary(new Dictionary(p)); + } else { + pressureBuilder.selectDictionary(null); + } + } + + @Override + public void saveToBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary momentum = bc.getMomentum(); + DictionaryModel velocityModel = velocityBuilder.getSelectedModel(); + DictionaryModel pressureModel = pressureBuilder.getSelectedModel(); + + momentum.add(new Dictionary(velocityModel.getDictionary())); + momentum.add(new Dictionary(pressureModel.getDictionary())); + } + + @Override + public void stateChanged(Model model) { + updateGUI(model); + updateFixedValuePressureModel(model); + } + + private void updateGUI(Model model) { + pressureChoice.clearDisabledIndexes(); + velocityTypeChoice.clearDisabledIndexes(); + + if (model.getState() != null && model.getState().isCompressible()) { + fixedPressureLabel.setText(PRESSURE_COMP); + totalPressureLabel.setText(PRESSURE_COMP); + + fixedPressureField.setName(PRESSURE_COMP); + totalPressureField.setName(PRESSURE_COMP); + + velocityTypeChoice.clearDisabledIndexes(); + + velocityTypeChoice.addDisabledItem(VOLUMETRIC_FLOW_RATE_INLET_LABEL); + } else { + fixedPressureLabel.setText(PRESSURE_INCOMP); + totalPressureLabel.setText(PRESSURE_INCOMP); + + fixedPressureField.setName(PRESSURE_INCOMP); + totalPressureField.setName(PRESSURE_INCOMP); + + velocityTypeChoice.addDisabledItem(MASS_FLOW_RATE_INLET_LABEL); + } + + if (!model.getState().getMultiphaseModel().isMultiphase()) { + velocityTypeChoice.addDisabledItem(VARIABLE_HEIGHT_FLOW_RATE_INLET_LABEL); + } + } + + private void updateFixedValuePressureModel(Model model) { + if (model != null && model.getState() != null && model.getState().isCompressible()) { + fixedValuePressureModel.setDictionary(new Dictionary(fixedValuePressure_COMP)); + } else { + fixedValuePressureModel.setDictionary(new Dictionary(fixedValuePressure)); + } + } +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/PatchSettingsPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/PatchSettingsPanel.java new file mode 100644 index 0000000..92699b0 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/PatchSettingsPanel.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels.patch; + +import javax.inject.Inject; + +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.gui.casesetup.boundaryconditions.panels.AbstractBoundaryTypePanel; + +public class PatchSettingsPanel extends AbstractBoundaryTypePanel { + + @Inject + public PatchSettingsPanel(Model model) { + super(model); + setName("Turbulence"); + } + + @Override + public void layoutPanel() { + super.layoutPanel(); + MomentumPatch momentum = new MomentumPatch(this); + TurbulencePatch turbulence = new TurbulencePatch(this); + ThermalPatch thermal = new ThermalPatch(this); + PhasePatch phase = new PhasePatch(model, this); + + addMomentumPanel(momentum); + addTurbulencePanel(turbulence); + addThermalPanel(thermal); + addPhasePanel(phase); + } + + @Override + public BoundaryType getType() { + return BoundaryType.PATCH; + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/PhasePatch.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/PhasePatch.java new file mode 100644 index 0000000..a7fc777 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/PhasePatch.java @@ -0,0 +1,140 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels.patch; + +import static eu.engys.gui.casesetup.boundaryconditions.factories.StandardPhaseFactory.calculated; +import static eu.engys.gui.casesetup.boundaryconditions.factories.StandardPhaseFactory.fixedValueVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.StandardPhaseFactory.inletOutlet; +import static eu.engys.gui.casesetup.boundaryconditions.factories.StandardPhaseFactory.zeroGradient; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.materials.Materials; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.gui.casesetup.boundaryconditions.panels.PhaseParametersPanel; + +public class PhasePatch extends PhaseParametersPanel { + + public static final String FIXED_VALUE_LABEL = "Fixed Value"; + public static final String ZERO_GRADIENT_LABEL = "Zero Gradient"; + public static final String INLET_OUTLET_LABEL = "Inlet Outlet"; + public static final String CALCULATED_LABEL = "Calculated"; + + private DictionaryModel fixedModel; + private DictionaryModel inletOutletModel; + private DictionaryModel zeroGradientModel; + private DictionaryModel calculatedModel; + private Model model; + + public PhasePatch(Model model, BoundaryTypePanel parent) { + super(parent); + this.model = model; + } + + @Override + protected void init() { + fixedModel = new DictionaryModel(); + inletOutletModel = new DictionaryModel(); + zeroGradientModel = new DictionaryModel(); + calculatedModel = new DictionaryModel(); + } + + @Override + public void stateChanged(Model model) { + resetToDefault(model); + } + + @Override + public void materialsChanged(Model model) { + resetToDefault(model); + } + + @Override + public void resetToDefault(Model model) { + String alphaFieldName = ""; + if (model != null) { + Materials materials = model.getMaterials(); + String mat1Name = (materials != null && materials.size() > 0) ? materials.get(0).getName() : ""; + alphaFieldName = Fields.ALPHA + "." + mat1Name; + } else { + alphaFieldName = Fields.ALPHA; + } + + fixedModel.setDictionary(new Dictionary(alphaFieldName, fixedValueVelocity)); + inletOutletModel.setDictionary(new Dictionary(alphaFieldName, inletOutlet)); + zeroGradientModel.setDictionary(new Dictionary(alphaFieldName, zeroGradient)); + calculatedModel.setDictionary(new Dictionary(alphaFieldName, calculated)); + } + + @Override + public void populatePanel() { + resetToDefault(null); + builder.startChoice("Type"); + buildFixedValues(); + buildInletOutlet(); + buildZeroGradient(); + buildCalculated(); + builder.endChoice(); + } + + private void buildFixedValues() { + builder.startDictionary(FIXED_VALUE_LABEL, fixedModel); + builder.addComponent("Value", fixedModel.bindUniformDouble("value", 0.0, 1.0)); + builder.endDictionary(); + } + + private void buildInletOutlet() { + builder.startDictionary(INLET_OUTLET_LABEL, inletOutletModel); + builder.addComponent("Inlet Value", inletOutletModel.bindUniformDouble("inletValue", 0.0, 1.0)); + builder.endDictionary(); + } + + private void buildZeroGradient() { + builder.startDictionary(ZERO_GRADIENT_LABEL, zeroGradientModel); + builder.endDictionary(); + } + + private void buildCalculated() { + builder.startDictionary(CALCULATED_LABEL, calculatedModel); + builder.endDictionary(); + } + + @Override + public void loadFromBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getPhase(); + if (model.getState().getMultiphaseModel().isMultiphase()) { + String alphaField = Fields.ALPHA + "." + model.getMaterials().getFirstMaterialName(); + Dictionary alphaDict = dictionary.subDict(alphaField); + if (alphaDict != null) { + builder.selectDictionary(alphaDict); + } + } + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/ThermalPatch.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/ThermalPatch.java new file mode 100644 index 0000000..27d0ec3 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/ThermalPatch.java @@ -0,0 +1,124 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels.patch; + +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.fixedValue; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.inletOutlet; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.inletOutletTotalTemperature; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.totalTemperature; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.zeroGradient; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.gui.casesetup.boundaryconditions.panels.ThermalParametersPanel; + +public class ThermalPatch extends ThermalParametersPanel { + + private DictionaryModel fixedTemperatureModel; + private DictionaryModel totalTemperatureModel; + private DictionaryModel inletOutletModel; + private DictionaryModel zeroGradientModel; + private DictionaryModel inletOutletTotalTemperatureModel; + + public ThermalPatch(BoundaryTypePanel parent) { + super(parent); + } + + @Override + protected void init() { + fixedTemperatureModel = new DictionaryModel(); + totalTemperatureModel = new DictionaryModel(); + inletOutletModel = new DictionaryModel(); + zeroGradientModel = new DictionaryModel(); + inletOutletTotalTemperatureModel = new DictionaryModel(); + } + + @Override + public void resetToDefault(Model model) { + fixedTemperatureModel.setDictionary(new Dictionary(fixedValue)); + totalTemperatureModel.setDictionary(new Dictionary(totalTemperature)); + inletOutletModel.setDictionary(new Dictionary(inletOutlet)); + zeroGradientModel.setDictionary(new Dictionary(zeroGradient)); + inletOutletTotalTemperatureModel.setDictionary(new Dictionary(inletOutletTotalTemperature)); + } + + @Override + public void populatePanel() { + resetToDefault(null); + + builder.startChoice("Type"); + buildFixedTemperaturePanel(); + buildTotalTemperaturePanel(); + buildInletOutlet(); + buildZeroGradient(); + buildInletOutletTotalTemperature(); + builder.endChoice(); + } + + private void buildFixedTemperaturePanel() { + builder.startDictionary("Fixed Temperature", fixedTemperatureModel); + builder.addComponent("Temperature Value [K]", fixedTemperatureModel.bindUniformDouble("value")); + builder.endDictionary(); + } + + private void buildTotalTemperaturePanel() { + builder.startDictionary("Total Temperature", totalTemperatureModel); + builder.addComponent("Compressibility", totalTemperatureModel.bindDouble("psi")); + builder.addComponent("Ratio Of Specific Heats", totalTemperatureModel.bindDouble("gamma")); + builder.addComponent("Temperature Value [K]", totalTemperatureModel.bindUniformDouble("T0")); + builder.endDictionary(); + } + + private void buildInletOutlet() { + builder.startDictionary("Inlet Outlet", inletOutletModel); + builder.addComponent("Temperature Value [K]", inletOutletModel.bindUniformDouble("value", "inletValue")); + builder.endDictionary(); + } + + private void buildZeroGradient() { + builder.startDictionary("Zero Gradient", zeroGradientModel); + builder.endDictionary(); + } + + private void buildInletOutletTotalTemperature() { + builder.startDictionary("Inlet Outlet Total Temperature", inletOutletTotalTemperatureModel); + builder.addComponent("Compressibility", inletOutletTotalTemperatureModel.bindDouble("psi")); + builder.addComponent("Ratio Of Specific Heats", inletOutletTotalTemperatureModel.bindDouble("gamma")); + builder.addComponent("Temperature Value [K]", inletOutletTotalTemperatureModel.bindUniformDouble("T0")); + builder.endDictionary(); + } + + @Override + public void loadFromBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getThermal(); + Dictionary T = dictionary.subDict("T"); + builder.selectDictionary(T); + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/TurbulencePatch.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/TurbulencePatch.java new file mode 100644 index 0000000..d1c2e8e --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/patch/TurbulencePatch.java @@ -0,0 +1,197 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels.patch; + +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.epsilonFixedValue; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.epsilonInletOutlet; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.epsilonMixingLength; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.epsilonMixingLength_COMP; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.epsilonZeroGradient; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.kFixedValue; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.kInletOutlet; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.kMixingLength; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.kZeroGradient; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.nuTildaInletOutlet; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.nuTildaZeroGradient; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.nutildaFixedValue; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.omegaFixedValue; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.omegaInletOutlet; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.omegaMixingLength; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.omegaMixingLength_COMP; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TurbulenceFactory.omegaZeroGradient; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.gui.casesetup.boundaryconditions.panels.TurbulenceParametersPanel; +import eu.engys.gui.casesetup.boundaryconditions.utils.TurbulenceUtils; +import eu.engys.util.ui.builder.JComboBoxController; + +public class TurbulencePatch extends TurbulenceParametersPanel { + + private JComboBoxController typeChoice; + + private DictionaryModel dictKFixedModel; + private DictionaryModel dictOmegaFixedModel; + private DictionaryModel dictEpsilonFixedModel; + private DictionaryModel dictNuTildaFixedModel; + private DictionaryModel dictKInletOutletModel; + private DictionaryModel dictOmegaInletOutletModel; + private DictionaryModel dictEpsilonInletOutletModel; + private DictionaryModel dictNuTildaInletOutletModel; + private DictionaryModel dictKZeroGradientModel; + private DictionaryModel dictOmegaZeroGradientModel; + private DictionaryModel dictEpsilonZeroGradientModel; + private DictionaryModel dictNuTildaZeroGradientModel; + private DictionaryModel dictKTurbulentIntensityModel; + private DictionaryModel dictOmegaTurbulentIntensityModel; + private DictionaryModel dictEpsilonTurbulentIntensityModel; + + public TurbulencePatch(BoundaryTypePanel parent) { + super(parent); + } + + @Override + protected void init() { + dictKFixedModel = new DictionaryModel(); + dictOmegaFixedModel = new DictionaryModel(); + dictEpsilonFixedModel = new DictionaryModel(); + dictNuTildaFixedModel = new DictionaryModel(); + + dictKInletOutletModel = new DictionaryModel(); + dictOmegaInletOutletModel = new DictionaryModel(); + dictEpsilonInletOutletModel = new DictionaryModel(); + dictNuTildaInletOutletModel = new DictionaryModel(); + + dictKZeroGradientModel = new DictionaryModel(); + dictOmegaZeroGradientModel = new DictionaryModel(); + dictEpsilonZeroGradientModel = new DictionaryModel(); + dictNuTildaZeroGradientModel = new DictionaryModel(); + + dictKTurbulentIntensityModel = new DictionaryModel(); + dictOmegaTurbulentIntensityModel = new DictionaryModel(); + dictEpsilonTurbulentIntensityModel = new DictionaryModel(); + } + + @Override + public void resetToDefault(Model model) { + dictKFixedModel.setDictionary(new Dictionary(kFixedValue)); + dictOmegaFixedModel.setDictionary(new Dictionary(omegaFixedValue)); + dictEpsilonFixedModel.setDictionary(new Dictionary(epsilonFixedValue)); + dictNuTildaFixedModel.setDictionary(new Dictionary(nutildaFixedValue)); + + dictKInletOutletModel.setDictionary(new Dictionary(kInletOutlet)); + dictOmegaInletOutletModel.setDictionary(new Dictionary(omegaInletOutlet)); + dictEpsilonInletOutletModel.setDictionary(new Dictionary(epsilonInletOutlet)); + dictNuTildaInletOutletModel.setDictionary(new Dictionary(nuTildaInletOutlet)); + + dictKZeroGradientModel.setDictionary(new Dictionary(kZeroGradient)); + dictOmegaZeroGradientModel.setDictionary(new Dictionary(omegaZeroGradient)); + dictEpsilonZeroGradientModel.setDictionary(new Dictionary(epsilonZeroGradient)); + dictNuTildaZeroGradientModel.setDictionary(new Dictionary(nuTildaZeroGradient)); + + dictKTurbulentIntensityModel.setDictionary(new Dictionary(kMixingLength)); + + if (model != null && model.getState() != null && model.getState().isCompressible()) { + dictOmegaTurbulentIntensityModel.setDictionary(new Dictionary(omegaMixingLength_COMP)); + dictEpsilonTurbulentIntensityModel.setDictionary(new Dictionary(epsilonMixingLength_COMP)); + } else { + dictOmegaTurbulentIntensityModel.setDictionary(new Dictionary(omegaMixingLength)); + dictEpsilonTurbulentIntensityModel.setDictionary(new Dictionary(epsilonMixingLength)); + } + } + + @Override + public void populatePanel() { + resetToDefault(null); + typeChoice = (JComboBoxController) builder.startChoice("Type"); + TurbulenceUtils.buildFixedKnownValuesPanel(builder, dictKFixedModel, dictOmegaFixedModel, dictEpsilonFixedModel, dictNuTildaFixedModel); + TurbulenceUtils.buildInletOutletPanel(builder, dictKInletOutletModel, dictOmegaInletOutletModel, dictEpsilonInletOutletModel, dictNuTildaInletOutletModel); + TurbulenceUtils.buildTurbulentIntensityAndMixingLengthPanel(builder, dictKTurbulentIntensityModel, dictOmegaTurbulentIntensityModel, dictEpsilonTurbulentIntensityModel, null); + TurbulenceUtils.buildZeroGradientPanel(builder, dictKZeroGradientModel, dictOmegaZeroGradientModel, dictEpsilonZeroGradientModel, dictNuTildaZeroGradientModel); + builder.endChoice(); + } + + public void loadFromBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getTurbulence(); + Dictionary k = dictionary.subDict(Fields.K); + Dictionary omega = dictionary.subDict(Fields.OMEGA); + Dictionary epsilon = dictionary.subDict(Fields.EPSILON); + Dictionary nutilda = dictionary.subDict(Fields.NU_TILDA); + + if (nutilda != null) { + builder.selectDictionary(nutilda); + } else if (k != null) { + if (omega != null) { + builder.selectDictionaries(omega, k); + } else if (epsilon != null) { + builder.selectDictionaries(epsilon, k); + } else { + builder.selectDictionary(k); + } + } + } + + @Override + public void tabChanged(Model model) { + super.tabChanged(model); + + fixIntensityAndMixingVisibility(model); + } + + @Override + public void stateChanged(Model model) { + super.stateChanged(model); + fixIntensityAndMixingVisibility(model); + + State state = model.getState(); + if (state.isCompressible()) { + dictEpsilonTurbulentIntensityModel.setDictionary(new Dictionary(epsilonMixingLength_COMP)); + dictOmegaTurbulentIntensityModel.setDictionary(new Dictionary(omegaMixingLength_COMP)); + } else if (state.isIncompressible()) { + dictEpsilonTurbulentIntensityModel.setDictionary(new Dictionary(epsilonMixingLength)); + dictOmegaTurbulentIntensityModel.setDictionary(new Dictionary(omegaMixingLength)); + } + + } + + private void fixIntensityAndMixingVisibility(Model model) { + State state = model.getState(); + typeChoice.clearDisabledIndexes(); + if (state.getTurbulenceModel().getType().isSpalartAllmaras()) { + typeChoice.addDisabledItem(TurbulenceUtils.BY_TURB_INTENSITY_AND_MIXING_LENGTH_LABEL); + } + + if (state.getTurbulenceModel().getType().isKEquationeddy()) { + typeChoice.addDisabledItem(TurbulenceUtils.BY_TURB_INTENSITY_AND_MIXING_LENGTH_LABEL); + } + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/wall/StandardMomentumWall.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/wall/StandardMomentumWall.java new file mode 100644 index 0000000..f543a22 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/wall/StandardMomentumWall.java @@ -0,0 +1,151 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels.wall; + +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.fixedValueVelocity; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.noSlipWall; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.slipWall; +import static eu.engys.gui.casesetup.boundaryconditions.factories.VelocityFactory.standardRotatingWallVelocity; + +import java.util.Arrays; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.gui.casesetup.boundaryconditions.panels.MomentumParametersPanel; +import eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils; + +public class StandardMomentumWall extends MomentumParametersPanel { + + private static final String MOVING_WALL = "Moving Wall"; + private static final String FIXED_WALL = "Fixed Wall"; + public static final String[] TYPE_KEYS = { "noslip", "slip" }; + public static final String[] TYPE_LABELS = { "No-slip", "Slip" }; + + private DictionaryModel noSlipModel; + private DictionaryModel slipModel; + private DictionaryModel fixedVelocityModel; + private DictionaryModel rotatingWallModel; + + public StandardMomentumWall(BoundaryTypePanel parent) { + super(parent); + } + + @Override + protected void init() { + noSlipModel = new DictionaryModel(); + slipModel = new DictionaryModel(); + fixedVelocityModel = new DictionaryModel(); + rotatingWallModel = new DictionaryModel(); + } + + @Override + public void resetToDefault(Model model) { + noSlipModel.setDictionary(new Dictionary(noSlipWall)); + slipModel.setDictionary(new Dictionary(slipWall)); + fixedVelocityModel.setDictionary(new Dictionary(fixedValueVelocity)); + rotatingWallModel.setDictionary(new Dictionary(standardRotatingWallVelocity)); + } + + @Override + public void populatePanel() { + resetToDefault(null); + builder.startChoice("Type"); + fixedWallPanel(builder); + movingWallPanel(builder); + builder.endChoice(); + } + + public void fixedWallPanel(DictionaryPanelBuilder builder) { + builder.startGroup(FIXED_WALL); + builder.startChoice("Wall Type"); + + builder.startDictionary("No-slip", noSlipModel); + builder.endDictionary(); + + builder.startDictionary("Slip", slipModel); + builder.endDictionary(); + + builder.endChoice(); + builder.endGroup(); + } + + public void movingWallPanel(DictionaryPanelBuilder builder) { + builder.startGroup(MOVING_WALL); + builder.startChoice("Velocity Type"); + + buildFixedVelocityPanel(builder); + buildRotatingWallPanel(builder); + + builder.endChoice(); + builder.endGroup(); + } + + private void buildFixedVelocityPanel(DictionaryPanelBuilder builder) { + builder.startDictionary("Fixed Velocity", fixedVelocityModel); + BoundaryConditionsUtils.buildSimpleFixedVelocityPanel(builder, fixedVelocityModel); + builder.endDictionary(); + } + + private void buildRotatingWallPanel(DictionaryPanelBuilder builder) { + builder.startDictionary("Rotating Wall", rotatingWallModel); + builder.addComponent("Origin", rotatingWallModel.bindPoint("origin")); + builder.addComponent("Axis", rotatingWallModel.bindPoint("axis")); + builder.addComponent("Omega [rad/s]", rotatingWallModel.bindDouble("omega")); + builder.endDictionary(); + } + + public void loadFromBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getMomentum(); + Dictionary U = dictionary.subDict("U"); + Dictionary p = dictionary.subDict("p"); + if (U != null) { + String U_type = U.lookup("type"); + if (U_type.contains("slip")) { + builder.selectDictionary(U); + } else if (U_type.equals("fixedValue")) { + if (U.found("value")) { + double[] value = U.lookupDoubleArray("value"); + double[] zeros = new double[] { 0, 0, 0 }; + if (Arrays.equals(value, zeros)) { + builder.selectDictionaryByModel(noSlipModel, U); + } else { + builder.selectDictionaryByModel(fixedVelocityModel, U); + } + } else { + + } + } else if (U_type.equals("tangentialVelocity") || U_type.equals("timeVaryingUniformFixedValue") || U_type.equals("rotatingWallVelocity") || U_type.equals("wheelVelocity")) { + builder.selectDictionary(U); + } + } + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/wall/StandardThermalWall.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/wall/StandardThermalWall.java new file mode 100644 index 0000000..4a51b31 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/wall/StandardThermalWall.java @@ -0,0 +1,140 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels.wall; + +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.fixedValue; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.turbulentHeatFluxTemperatureOCFD_FLUX; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.turbulentHeatFluxTemperatureOCFD_FLUX_COMP; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.turbulentHeatFluxTemperatureOCFD_POWER; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.turbulentHeatFluxTemperatureOCFD_POWER_COMP; +import static eu.engys.gui.casesetup.boundaryconditions.factories.TemperatureFactory.zeroGradient; +import static eu.engys.util.Symbols.SQUARE; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.patches.BoundaryConditions; +import eu.engys.gui.casesetup.boundaryconditions.panels.ThermalParametersPanel; + +public class StandardThermalWall extends ThermalParametersPanel { + + private DictionaryModel heatPowerModel; + private DictionaryModel heatFluxModel; + private DictionaryModel fixedTemperatureModel; + private DictionaryModel zeroGradientModel; + + public StandardThermalWall(BoundaryTypePanel parent) { + super(parent); + } + + @Override + protected void init() { + fixedTemperatureModel = new DictionaryModel(); + heatFluxModel = new DictionaryModel(); + heatPowerModel = new DictionaryModel(); + zeroGradientModel = new DictionaryModel(); + } + + @Override + public void resetToDefault(Model model) { + fixedTemperatureModel.setDictionary(new Dictionary(fixedValue)); + if (model != null && model.getState() != null && model.getState().isCompressible()) { + heatFluxModel.setDictionary(new Dictionary(turbulentHeatFluxTemperatureOCFD_FLUX_COMP)); + heatPowerModel.setDictionary(new Dictionary(turbulentHeatFluxTemperatureOCFD_POWER_COMP)); + } else { + heatFluxModel.setDictionary(new Dictionary(turbulentHeatFluxTemperatureOCFD_FLUX)); + heatPowerModel.setDictionary(new Dictionary(turbulentHeatFluxTemperatureOCFD_POWER)); + } + zeroGradientModel.setDictionary(new Dictionary(zeroGradient)); + } + + @Override + public void populatePanel() { + resetToDefault(null); + builder.startChoice("Type"); + buildFixedTemperaturePanel(); + buildHeatFluxPanel(); + buildTotalHeatPanel(); + buildZeroGradientPanel(); + builder.endChoice(); + } + + private void buildFixedTemperaturePanel() { + builder.startDictionary("Fixed Temperature", fixedTemperatureModel); + builder.addComponent("Temperature Value [K]", fixedTemperatureModel.bindUniformDouble("value")); + builder.endDictionary(); + } + + private void buildHeatFluxPanel() { + builder.startDictionary("Heat Flux", heatFluxModel); + builder.addComponent("Wall Heat Flux [W/m"+SQUARE+"]", heatFluxModel.bindUniformDouble("q")); + builder.endDictionary(); + } + + private void buildTotalHeatPanel() { + builder.startDictionary("Total Heat Load", heatPowerModel); + builder.addComponent("Total Heat Load At Wall [W]", heatPowerModel.bindUniformDouble("q")); + builder.endDictionary(); + } + + private void buildZeroGradientPanel() { + builder.startDictionary("Zero Gradient", zeroGradientModel); + builder.endDictionary(); + } + + @Override + public void stateChanged(Model model) { + State state = model.getState(); + if (state.isCompressible()) { + heatFluxModel.setDictionary(new Dictionary(turbulentHeatFluxTemperatureOCFD_FLUX_COMP)); + heatPowerModel.setDictionary(new Dictionary(turbulentHeatFluxTemperatureOCFD_POWER_COMP)); + } else if (state.isIncompressible()) { + heatFluxModel.setDictionary(new Dictionary(turbulentHeatFluxTemperatureOCFD_FLUX)); + heatPowerModel.setDictionary(new Dictionary(turbulentHeatFluxTemperatureOCFD_POWER)); + } + } + + @Override + public void loadFromBoundaryConditions(String patchName, BoundaryConditions bc) { + Dictionary dictionary = bc.getThermal(); + Dictionary T = dictionary.subDict("T"); + if (T != null) { + if (T.found("heatSource")) { + String source = T.lookup("heatSource"); + if (source.equals("power")) { + builder.selectDictionaryByModel(heatPowerModel, T); + } else if (source.equals("flux")) { + builder.selectDictionaryByModel(heatFluxModel, T); + } + } else { + builder.selectDictionary(T); + } + } + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/panels/wall/StandardWallSettingsPanel.java b/src/eu/engys/gui/casesetup/boundaryconditions/panels/wall/StandardWallSettingsPanel.java new file mode 100644 index 0000000..8ea8fd3 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/panels/wall/StandardWallSettingsPanel.java @@ -0,0 +1,56 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.panels.wall; + +import javax.inject.Inject; + +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.gui.casesetup.boundaryconditions.panels.AbstractBoundaryTypePanel; + +public class StandardWallSettingsPanel extends AbstractBoundaryTypePanel { + + @Inject + public StandardWallSettingsPanel(Model model) { + super(model); + } + + @Override + public void layoutPanel() { + super.layoutPanel(); + StandardMomentumWall momentum = new StandardMomentumWall(this); + StandardThermalWall thermal = new StandardThermalWall(this); + addMomentumPanel(momentum); + addThermalPanel(thermal); + } + + @Override + public BoundaryType getType() { + return BoundaryType.WALL; + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/utils/BoundaryConditionsUtils.java b/src/eu/engys/gui/casesetup/boundaryconditions/utils/BoundaryConditionsUtils.java new file mode 100644 index 0000000..5a83ec0 --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/utils/BoundaryConditionsUtils.java @@ -0,0 +1,350 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.utils; + +import static eu.engys.core.dictionary.Dictionary.TYPE; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.JButton; + +import net.java.dev.designgridlayout.Componentizer; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.gui.casesetup.boundaryconditions.TimeVaryingComboBoxController; +import eu.engys.gui.casesetup.boundaryconditions.TimeVaryingInterpolationTable; +import eu.engys.util.Symbols; + +public class BoundaryConditionsUtils { + + /* + * TYPES + */ + public static final String ADVECTIVE_KEY = "advective"; + public static final String ALPHA_CONTACT_ANGLE_KEY = "alphaContactAngle"; + public static final String CYLINDRICAL_INLET_VELOCITY_KEY = "cylindricalInletVelocity"; + public static final String COMPRESSIBLE_TURBULENT_MIXING_LENGTH_DISSIPATION_RATE_INLET_KEY = "compressible::turbulentMixingLengthDissipationRateInlet"; + public static final String COMPRESSIBLE_TURBULENT_MIXING_LENGTH_FREQUENCY_INLET_KEY = "compressible::turbulentMixingLengthFrequencyInlet"; + public static final String CONSTANT_ALPHA_CONTACT_ANGLE_KEY = "constantAlphaContactAngle"; + + public static final String COUPLED_TOTAL_VELOCITY_KEY = "coupledTotalVelocity"; + public static final String COUPLED_TOTAL_PRESSURE_KEY = "coupledTotalPressure"; + + public static final String DYNAMIC_ALPHA_CONTACT_ANGLE_KEY = "dynamicAlphaContactAngle"; + public static final String FIXED_FLUX_PRESSURE_KEY = "fixedFluxPressure"; + public static final String FIXED_MEAN_VALUE_KEY = "fixedMeanValue"; + public static final String FIXED_VALUE_KEY = "fixedValue"; + public static final String FLOW_RATE_INLET_VELOCITY_KEY = "flowRateInletVelocity"; + public static final String FLOW_RATE_OUTLET_VELOCITY_KEY = "flowRateOutletVelocity"; + public static final String FLUX_CORRECTED_VELOCITY_KEY = "fluxCorrectedVelocity"; + public static final String FREESTREAM_PRESSURE_KEY = "freestreamPressure"; + public static final String FREESTREAM_KEY = "freestream"; + public static final String INLET_OUTLET_KEY = "inletOutlet"; + public static final String INTERPOLATED_CYLINDRICAL_VELOCITY_KEY = "interpolatedCylindricalVelocity"; + public static final String INTERPOLATED_FIXED_VALUE_KEY = "interpolatedFixedValue"; + public static final String INTERPOLATED_INLET_OUTLET_KEY = "interpolatedInletOutlet"; + public static final String MAXWELL_SLIP_U_KEY = "maxwellSlipU"; + public static final String MOVING_WALL_VELOCITY_KEY = "movingWallVelocity"; + public static final String MOVING_WALL_COUPLED_VELOCITY_KEY = "movingNoSlipWall"; + public static final String MUT_K_ROUGH_WALL_FUNCTION_KEY = "mutKRoughWallFunction"; + public static final String MUT_U_ROUGH_WALL_FUNCTION_KEY = "mutURoughWallFunction"; + public static final String NUT_K_ROUGH_WALL_FUNCTION_KEY = "nutkRoughWallFunction"; + public static final String NUT_K_ATM_ROUGH_WALL_FUNCTION_KEY = "nutkAtmRoughWallFunction"; + public static final String NUT_U_ROUGH_WALL_FUNCTION_KEY = "nutURoughWallFunction"; + public static final String NUT_TURBULENT_INTENSITY_LENGTH_SCALE_INLET_KEY = "nutTurbulentIntensityLengthScaleInlet"; + public static final String PRESSURE_DIRECT_INLET_VELOCITY_KEY = "pressureDirectedInletVelocity"; + public static final String PRESSURE_DIRECT_INLET_OUTLET_VELOCITY_KEY = "pressureDirectedInletOutletVelocity"; + public static final String PRESSURE_INLET_OUTLET_VELOCITY_KEY = "pressureInletOutletVelocity"; + public static final String PRESSURE_INLET_VELOCITY_KEY = "pressureInletVelocity"; + public static final String RESISTIVE_PRESSURE_KEY = "resistivePressure"; + public static final String RESISTIVE_VELOCITY_KEY = "resistiveVelocity"; + public static final String ROTATING_WALL_VELOCITY_KEY = "rotatingWallVelocity"; + public static final String ROTATING_WALL_COUPLED_VELOCITY_KEY = "rotatingNoSlipWall"; + public static final String SLIP_KEY = "slip"; + public static final String SLIP_WALL_KEY = "slipWall"; + public static final String NO_SLIP_WALL_KEY = "noSlipWall"; + public static final String SUPERSONIC_FREESTREAM_KEY = "supersonicFreestream"; + public static final String SURFACE_NORMAL_FIXED_VALUE_KEY = "surfaceNormalFixedValue"; + public static final String TANGENTIAL_VELOCITY_KEY = "tangentialVelocity"; + public static final String TOTAL_PRESSURE_KEY = "totalPressure"; + public static final String TURBULENT_INTENSITY_KINETIC_ENERGY_INLET_KEY = "turbulentIntensityKineticEnergyInlet"; + public static final String TURBULENT_MIXING_LENGTH_DISSIPATION_RATE_INLET_KEY = "turbulentMixingLengthDissipationRateInlet"; + public static final String TURBULENT_MIXING_LENGTH_FREQUENCY_INLET_KEY = "turbulentMixingLengthFrequencyInlet"; + public static final String UNIFORM_FIXED_VALUE_KEY = "uniformFixedValue"; + public static final String UNIFORM_TOTAL_PRESSURE_KEY = "uniformTotalPressure"; + public static final String VARIABLE_HEIGHT_FLOW_RATE_INLET_VELOCITY_KEY = "variableHeightFlowRateInletVelocity"; + public static final String VELOCITY_GRADIENT_DISSIPATION_INLET_OUTLET_KEY = "velocityGradientDissipationInletOutlet"; + public static final String WAVE_TRANSMISSIVE_KEY = "waveTransmissive"; + public static final String WHEEL_VELOCITY_KEY = "wheelVelocity"; + public static final String WIND_PROFILE_DIRECTION_VELOCITY_KEY = "windProfileDirectionVelocity"; + public static final String ZERO_GRADIENT_KEY = "zeroGradient"; + + /* + * OTHER KEYS + */ + public static final String ACCOMMODATION_COEFFICIENT_KEY = "accommodationCoeff"; + public static final String ALPHA_KEY = "alpha"; + public static final String AXIS_KEY = "axis"; + public static final String CENTRE_KEY = "centre"; + public static final String CLAMP_KEY = "clamp"; + public static final String CS_KEY = "Cs"; + public static final String DATA_KEY = "data"; + public static final String DIRECTION_KEY = "direction"; + public static final String DISTANCE_ALONG_VECTOR_KEY = "distanceAlongVector"; + public static final String DISTANCE_TYPE_KEY = "distanceType"; + public static final String FIELD_KEY = "field"; + public static final String FILE_KEY = "file"; + public static final String FILE_NAME_KEY = "fileName"; + public static final String FLOW_RATE_KEY = "flowRate"; + public static final String FREESTREAM_VALUE_KEY = "freestreamValue"; + public static final String GAMMA_KEY = "gamma"; + public static final String GRADIENT_KEY = "gradient"; + public static final String INLET_VALUE_KEY = "inletValue"; + public static final String INLET_DIRECTION_KEY = "inletDirection"; + public static final String INTENSITY_KEY = "intensity"; + public static final String KS_KEY = "Ks"; + public static final String LENGTH_KEY = "length"; + public static final String LIMIT_KEY = "limit"; + public static final String MASS_FLOW_RATE_KEY = "massFlowRate"; + public static final String MEAN_VALUE_KEY = "meanValue"; + public static final String MIXING_LENGTH_KEY = "mixingLength"; + public static final String NONE_KEY = "none"; + public static final String NORMAL_KEY = "normal"; + public static final String OMEGA_KEY = "omega"; + public static final String ORIGIN_KEY = "origin"; + public static final String OUT_OF_BOUNDS_KEY = "outOfBounds"; + public static final String P0_KEY = "p0"; + public static final String PHASE_KEY = "phase"; + public static final String PHI_KEY = "phi"; + public static final String POINT_KEY = "point"; + public static final String POINT_DISTANCE_KEY = "pointDistance"; + public static final String PRESSURE_KEY = "pressure"; + public static final String RHO_KEY = "rho"; + public static final String RHO_INLET_KEY = "rhoInlet"; + public static final String REF_VALUE_KEY = "refValue"; + public static final String ROUGHNESS_CONSTANT_KEY = "roughnessConstant"; + public static final String ROUGHNESS_HEIGHT_KEY = "roughnessHeight"; + public static final String ROUGHNESS_FACTOR_KEY = "roughnessFactor"; + public static final String TABLE_KEY = "table"; + public static final String TABLE_FILE_KEY = "tableFile"; + public static final String THETA_0_KEY = "theta0"; + public static final String THETA_A_KEY = "thetaA"; + public static final String THETA_PROPERTIES_KEY = "thetaProperties"; + public static final String THETA_R_KEY = "thetaR"; + public static final String U_THETA_KEY = "uTheta"; + public static final String UNIFORM_VALUE_KEY = "uniformValue"; + public static final String UNIFORM_KEY = "uniform"; + public static final String USE_WALL_DISTANCE_KEY = "useWallDistance"; + public static final String UWALL = "Uwall"; + public static final String VOLUMETRIC_FLOW_RATE_KEY = "volumetricFlowRate"; + public static final String VALUE_KEY = "value"; + public static final String WALL_DISTANCE_KEY = "wallDistance"; + public static final String WIND_DIRECTION_KEY = "windDirection"; + public static final String X_KEY = "x"; + public static final String XOFFSET_KEY = "xoffset"; + public static final String XSCALE_KEY = "xscale"; + public static final String YOFFSET_KEY = "yoffset"; + public static final String Y_KEY = "y"; + public static final String YSCALE_KEY = "yscale"; + public static final String Z_KEY = "z"; + public static final String Z0_KEY = "z0"; + + /* + * LISTS + */ + public static final String[] LIMIT_KEYS = { NONE_KEY, GRADIENT_KEY, "zeroGradient", ALPHA_KEY }; + + // TO ORDER + + public static final String[] INTERP_ALGO_TYPE_KEYS = { "repeat", "clamp", "warn", "error" }; + public static final String TABLE_FILE_COEFFS_KEY = "tableFileCoeffs"; + + public static final String[] INTERP_ALGO_TYPE_LABELS = { "Repeat", "Clamp", "Warn", "Error" }; + + public static final String ZERO_GRADIENT_LABEL = "Zero Gradient"; + public static final String FIXED_VALUE_LABEL = "Fixed Value"; + + public static final String NON_UNIFORM_TEMPERATURE_LABEL = "Non-uniform Temperature"; + public static final String NON_UNIFORM_TURBULENCE_LABEL = "Non-uniform Turbulence"; + public static final String NON_UNIFORM_PHASE_FRACTION_LABEL = "Non-uniform Phase Fraction"; + + public static final String TIME_VARYING_LABEL = "Time-varying"; + public static final String TIME_VARYING_VELOCITY_LABEL = "Time-varying Velocity"; + public static final String TIME_VARYING_FLOW_RATE_LABEL = "Time-varying Flow Rate"; + public static final String TIME_VARYING_TEMPERATURE_LABEL = "Time-varying Temperature"; + public static final String TIME_VARYING_TURBULENCE_LABEL = "Time-varying Turbulence"; + public static final String TIME_VARYING_PHASE_FRACTION_LABEL = "Time-varying Phase Fraction"; + + public static final String TABLE_DATA_LABEL = "Table Data"; + public static final String INTERPOLATION_PROFILE_LABEL = "Interpolation Profile"; + public static final String FROM_FILE_LABEL = "From File"; + + public static final String INTERPOLATION_ALGORITHM_LABEL = "Interpolation Algorithm"; + + public static final String VELOCITY_LABEL = "Velocity " + Symbols.M_S; + + public static void buildSimpleFixedVelocityPanel(DictionaryPanelBuilder builder, DictionaryModel model) { + builder.addComponent(VELOCITY_LABEL, model.bindUniformPoint("value")); + } + + public static void buildFreestreamVelocityPanel(DictionaryPanelBuilder builder, DictionaryModel model) { + builder.addComponent(VELOCITY_LABEL, model.bindUniformPoint("value", "freestreamValue")); + } + + public static void buildFixedCylindricalVelocityPanel(DictionaryPanelBuilder builder, DictionaryModel model) { + builder.addComponent("Axis", model.bindPoint("axis")); + builder.addComponent("Centre", model.bindPoint("centre")); + builder.addComponent("Axial Velocity", model.bindDouble("axialVelocity")); + builder.addComponent("RPM", model.bindDouble("rpm")); + builder.addComponent("Radial Velocity", model.bindDouble("radialVelocity")); + } + + public static void buildTimeVaryingScalarPanel(DictionaryPanelBuilder builder, DictionaryModel model, String dictionaryKey, String name) { + buildTimeVaryingInterpolationTablePanel(builder, model, dictionaryKey, new String[]{name}); + } + + public static void buildTimeVaryingVectorPanel(DictionaryPanelBuilder builder, DictionaryModel model, String dictionaryKey, String X, String Y, String Z) { + buildTimeVaryingInterpolationTablePanel(builder, model, dictionaryKey, new String[]{X,Y,Z}); + } + + /* + * Utils + */ + + private static void buildTimeVaryingInterpolationTablePanel(DictionaryPanelBuilder builder, final DictionaryModel model, final String dictionaryKey, final String[] names) { + builder.startChoice(INTERPOLATION_PROFILE_LABEL, new TimeVaryingComboBoxController(model, dictionaryKey)); + + builder.startGroup(DATA_KEY, TABLE_DATA_LABEL); + JButton editButton = new JButton(new AbstractAction("Edit") { + @Override + public void actionPerformed(ActionEvent e) { + new TimeVaryingInterpolationTable(model, dictionaryKey + " " + TABLE_KEY, names).showDialog(); + } + }); + editButton.setName("Edit"); + builder.addComponent("", Componentizer.create().minToPref(editButton).component()); + builder.endGroup(); + + builder.startGroup(FILE_KEY, FROM_FILE_LABEL); + builder.addComponent("", model.bindFile(FILE_NAME_KEY)); + builder.endGroup(); + + builder.endChoice(); + + builder.addComponent(INTERPOLATION_ALGORITHM_LABEL, model.bindSelection(OUT_OF_BOUNDS_KEY, INTERP_ALGO_TYPE_KEYS, INTERP_ALGO_TYPE_LABELS)); + } + + /* + * Time varying fix + */ + + public static void fixTimeVaryingLoad(Dictionary dict, String dictionaryKey) { + String type = dict.lookup(TYPE); + if (type.equals(UNIFORM_FIXED_VALUE_KEY) || type.equals(ROTATING_WALL_VELOCITY_KEY) || type.equals(FLOW_RATE_INLET_VELOCITY_KEY) || type.equals(UNIFORM_TOTAL_PRESSURE_KEY)) { + if (isTableFile(dict, dictionaryKey)) { + if (dict.found(TABLE_FILE_COEFFS_KEY)) { + Dictionary tableFileCoeffs = dict.subDict(TABLE_FILE_COEFFS_KEY); + dict.add(OUT_OF_BOUNDS_KEY, tableFileCoeffs.lookup(OUT_OF_BOUNDS_KEY)); + dict.add(FILE_NAME_KEY, tableFileCoeffs.lookup(FILE_NAME_KEY)); + dict.remove(TABLE_FILE_COEFFS_KEY); + } + } + } + } + + public static void fixTimeVaryingSave(Dictionary dict, String dictionaryKey) { + String type = dict.lookup(TYPE); + if (type.equals(UNIFORM_FIXED_VALUE_KEY) || type.equals(ROTATING_WALL_VELOCITY_KEY) || type.equals(FLOW_RATE_INLET_VELOCITY_KEY) || type.equals(UNIFORM_TOTAL_PRESSURE_KEY)) { + if (isTableFile(dict, dictionaryKey)) { + Dictionary tableFileCoeffs = new Dictionary(TABLE_FILE_COEFFS_KEY); + tableFileCoeffs.add(OUT_OF_BOUNDS_KEY, dict.lookup(OUT_OF_BOUNDS_KEY)); + tableFileCoeffs.add(FILE_NAME_KEY, dict.lookup(FILE_NAME_KEY)); + dict.remove(OUT_OF_BOUNDS_KEY); + dict.remove(FILE_NAME_KEY); + dict.add(tableFileCoeffs); + } else { + dict.remove(FILE_NAME_KEY); + } + } + } + + public static boolean isTableFile(Dictionary dict, String dictionaryKey) { + if (dict == null) { + return false; + } + if (!dict.found(dictionaryKey)) { + return false; + } + if (!dict.isField(dictionaryKey)) { + return false; + } + return dict.lookup(dictionaryKey).equals(TABLE_FILE_KEY); + } + + public static void loadFlowRate(Dictionary U, DictionaryPanelBuilder builder) { + if (U.found(MASS_FLOW_RATE_KEY)) { + if (U.lookup(MASS_FLOW_RATE_KEY).startsWith(TABLE_KEY)) { + fixTimeVaryingLoad(U, MASS_FLOW_RATE_KEY); + builder.selectDictionaryByKey(BoundaryConditionsUtils.getTimeVaryingMassFlowRate(), U); + } else { + builder.selectDictionaryByKey(BoundaryConditionsUtils.getMassFlowRate(), U); + } + } else if (U.found(VOLUMETRIC_FLOW_RATE_KEY)) { + if (U.lookup(VOLUMETRIC_FLOW_RATE_KEY).startsWith(TABLE_KEY)) { + fixTimeVaryingLoad(U, VOLUMETRIC_FLOW_RATE_KEY); + builder.selectDictionaryByKey(BoundaryConditionsUtils.getTimeVaryingVolumetricFlowRate(), U); + } else { + builder.selectDictionaryByKey(BoundaryConditionsUtils.getVolumetricFlowRate(), U); + } + } else if (U.found(FLOW_RATE_KEY)) { + builder.selectDictionaryByKey(BoundaryConditionsUtils.getVariableHeightFlowRate(), U); + } + } + + public static String getMassFlowRate() { + return "massFlowRate"; + } + + public static String getTimeVaryingMassFlowRate() { + return "timeVaryingMassFlowRate"; + } + + public static String getTimeVaryingVolumetricFlowRate() { + return "timeVaryingVolumetricFlowRate"; + } + + public static String getVolumetricFlowRate() { + return "volumetricFlowRate"; + } + + public static String getVariableHeightFlowRate() { + return "variableHeightFlowRate"; + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/utils/ThermalUtils.java b/src/eu/engys/gui/casesetup/boundaryconditions/utils/ThermalUtils.java new file mode 100644 index 0000000..1f33b4d --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/utils/ThermalUtils.java @@ -0,0 +1,64 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.utils; + +import static eu.engys.core.dictionary.Dictionary.VALUE; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; + +public class ThermalUtils extends BoundaryConditionsUtils { + + public static final String INLET_VALUE_KEY = "inletValue"; + public static final String GAMMA_KEY = "gamma"; + public static final String T0_KEY = "T0"; + + public static final String RATIO_OF_SPECIFIC_HEATS_LABEL = "Ratio Of Specific Heats"; + public static final String TOTAL_TEMPERATURE_LABEL = "Total Temperature"; + public static final String TEMPERATURE_VALUE_K_LABEL = "Temperature Value [K]"; + public static final String FIXED_TEMPERATURE_LABEL = "Fixed Temperature"; + + public static void buildFixedTemperaturePanel(DictionaryPanelBuilder builder, DictionaryModel model) { + builder.startDictionary(FIXED_TEMPERATURE_LABEL, model); + builder.addComponent(TEMPERATURE_VALUE_K_LABEL, model.bindUniformDouble(VALUE)); + builder.endDictionary(); + model.setDictionary(model.getDictionary()); + } + + public static void buildInletOutletTemperaturePanel(DictionaryPanelBuilder builder, DictionaryModel model) { + builder.startDictionary(FIXED_TEMPERATURE_LABEL, model); + builder.addComponent(TEMPERATURE_VALUE_K_LABEL, model.bindUniformDouble(INLET_VALUE_KEY)); + builder.endDictionary(); + } + + public static void buildTotalTemperaturePanel(DictionaryPanelBuilder builder, DictionaryModel dict) { + builder.startDictionary(TOTAL_TEMPERATURE_LABEL, dict); + builder.addComponent(RATIO_OF_SPECIFIC_HEATS_LABEL, dict.bindDouble(GAMMA_KEY)); + builder.addComponent(TEMPERATURE_VALUE_K_LABEL, dict.bindUniformDouble(T0_KEY)); + builder.endDictionary(); + } + +} diff --git a/src/eu/engys/gui/casesetup/boundaryconditions/utils/TurbulenceUtils.java b/src/eu/engys/gui/casesetup/boundaryconditions/utils/TurbulenceUtils.java new file mode 100644 index 0000000..600dacd --- /dev/null +++ b/src/eu/engys/gui/casesetup/boundaryconditions/utils/TurbulenceUtils.java @@ -0,0 +1,222 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.boundaryconditions.utils; + +import static eu.engys.util.Symbols.EPSILON_SYMBOL; +import static eu.engys.util.Symbols.K_SYMBOL; +import static eu.engys.util.Symbols.M2_S; +import static eu.engys.util.Symbols.OMEGA_SYMBOL; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; + +public class TurbulenceUtils extends BoundaryConditionsUtils { + + public static final String FIXED_VALUES_LABEL = "Fixed Values"; + public static final String INFLOW_FIXED_VALUES_LABEL = "Inflow Fixed Values"; + public static final String INLET_OUTLET_LABEL = "Inlet Outlet"; + public static final String ZERO_GRADIENT_LABEL = "Zero Gradient"; + public static final String BY_TURB_INTENSITY_AND_MIXING_LENGTH_LABEL = "By Turb. Intensity And Mixing Length"; + + public static final String K_LABEL = "k " + K_SYMBOL;// "Turbulent Kinetik Energy"; + public static final String NU_TILDA_LABEL = "NuTilda " + M2_S; + public static final String EPSILON_LABEL = "Epsilon " + EPSILON_SYMBOL; + public static final String OMEGA_LABEL = "Omega " + OMEGA_SYMBOL; + public static final String KEQUATION_LABEL = K_LABEL; + + private static final String TIMEVARYING_KEY = "timevarying"; + private static final String NONUNIFROM_KEY = "nonunifrom"; + private static final String FIXED_KEY = "fixed"; + private static final String ZERO_KEY = "zero"; + private static final String INOUT_KEY = "inout"; + private static final String MIXING_KEY = "mixing"; + + public static final String TURBULENCE_INTENSITY = "Turbulence Intensity"; + + public static void buildFixedKnownValuesPanel(DictionaryPanelBuilder builder, DictionaryModel dictK, DictionaryModel dictOmega, DictionaryModel dictEpsilon, DictionaryModel dictNutilda) { + builder.startGroup(FIXED_VALUES_LABEL); + builder.startHidable(FIXED_KEY); + + dictOmega.setCompanion(dictK); + builder.startDictionary(OMEGA_LABEL, dictOmega); + builder.addComponent(K_LABEL, dictK.bindUniformDouble("value")); + builder.addComponent(OMEGA_LABEL, dictOmega.bindUniformDouble("value")); + builder.endDictionary(); + + dictEpsilon.setCompanion(dictK); + builder.startDictionary(EPSILON_LABEL, dictEpsilon); + builder.addComponent(K_LABEL, dictK.bindUniformDouble("value")); + builder.addComponent(EPSILON_LABEL, dictEpsilon.bindUniformDouble("value")); + builder.endDictionary(); + + builder.startDictionary(NU_TILDA_LABEL, dictNutilda); + builder.addComponent(NU_TILDA_LABEL, dictNutilda.bindUniformDouble("value")); + builder.endDictionary(); + + builder.startDictionary(KEQUATION_LABEL, dictK); + builder.addComponent(K_LABEL, dictK.bindUniformDouble("value")); + builder.endDictionary(); + + builder.endHidable(); + builder.endGroup(); + } + + public static void buildInletOutletPanel(DictionaryPanelBuilder builder, DictionaryModel dictK, DictionaryModel dictOmega, DictionaryModel dictEpsilon, DictionaryModel dictNutilda) { + builder.startGroup(INFLOW_FIXED_VALUES_LABEL); + builder.startHidable(INOUT_KEY); + + dictOmega.setCompanion(dictK); + builder.startDictionary(OMEGA_LABEL, dictOmega); + builder.addComponent(K_LABEL, dictK.bindUniformDouble("inletValue")); + builder.addComponent(OMEGA_LABEL, dictOmega.bindUniformDouble("inletValue")); + builder.endDictionary(); + + dictEpsilon.setCompanion(dictK); + builder.startDictionary(EPSILON_LABEL, dictEpsilon); + builder.addComponent(K_LABEL, dictK.bindUniformDouble("inletValue")); + builder.addComponent(EPSILON_LABEL, dictEpsilon.bindUniformDouble("inletValue")); + builder.endDictionary(); + + builder.startDictionary(NU_TILDA_LABEL, dictNutilda); + builder.addComponent(NU_TILDA_LABEL, dictNutilda.bindUniformDouble("inletValue")); + builder.endDictionary(); + + builder.startDictionary(KEQUATION_LABEL, dictK); + builder.addComponent(K_LABEL, dictK.bindUniformDouble("inletValue")); + builder.endDictionary(); + + builder.endHidable(); + builder.endGroup(); + } + + public static void buildZeroGradientPanel(DictionaryPanelBuilder builder, DictionaryModel dictK, DictionaryModel dictOmega, DictionaryModel dictEpsilon, DictionaryModel dictNutilda) { + builder.startGroup(ZERO_GRADIENT_LABEL); + builder.startHidable(ZERO_KEY); + + dictOmega.setCompanion(dictK); + builder.startDictionary(OMEGA_LABEL, dictOmega); + builder.endDictionary(); + + dictEpsilon.setCompanion(dictK); + builder.startDictionary(EPSILON_LABEL, dictEpsilon); + builder.endDictionary(); + + builder.startDictionary(NU_TILDA_LABEL, dictNutilda); + builder.endDictionary(); + + builder.startDictionary(KEQUATION_LABEL, dictK); + builder.endDictionary(); + + builder.endHidable(); + builder.endGroup(); + } + + public static void buildTurbulentIntensityAndMixingLengthPanel(DictionaryPanelBuilder builder, DictionaryModel dictK, DictionaryModel dictOmega, DictionaryModel dictEpsilon, DictionaryModel dictNuTilda) { + builder.startGroup(BY_TURB_INTENSITY_AND_MIXING_LENGTH_LABEL); + builder.startHidable(MIXING_KEY); + + dictOmega.setCompanion(dictK); + builder.startDictionary(OMEGA_LABEL, dictOmega); +// builder.addComponent(new JLabel(OMEGA_LABEL), new JLabel("")); + builder.addComponent(TURBULENCE_INTENSITY, dictK.bindDouble("intensity")); + builder.addComponent("Mixing Length [m]", dictOmega.bindDouble("mixingLength")); + builder.endDictionary(); + + dictEpsilon.setCompanion(dictK); + builder.startDictionary(EPSILON_LABEL, dictEpsilon); +// builder.addComponent(new JLabel(EPSILON_LABEL), new JLabel("")); + builder.addComponent(TURBULENCE_INTENSITY, dictK.bindDouble("intensity")); + builder.addComponent("Mixing Length [m]", dictEpsilon.bindDouble("mixingLength")); + builder.endDictionary(); + + if (dictNuTilda != null) { + builder.startDictionary(NU_TILDA_LABEL, dictNuTilda); +// builder.addComponent(new JLabel(NU_TILDA_LABEL), new JLabel("")); + builder.addComponent(TURBULENCE_INTENSITY, dictNuTilda.bindDouble("intensity")); + builder.addComponent("Mixing Length [m]", dictNuTilda.bindDouble("length")); + builder.endDictionary(); + } + + builder.startDictionary(KEQUATION_LABEL, dictK); + builder.endDictionary(); + builder.endHidable(); + builder.endGroup(); + } + + public static void setSpalartAllmaras(DictionaryPanelBuilder builder) { + // Dictionary selectedDict = builder.getSelectedModel().getDictionary(); + builder.setShowing(FIXED_KEY, NU_TILDA_LABEL); + // builder.setShowing(MIXING_KEY, NU_TILDA_LABEL); + builder.setShowing(NONUNIFROM_KEY, NU_TILDA_LABEL); + builder.setShowing(TIMEVARYING_KEY, NU_TILDA_LABEL); + builder.setShowing(INOUT_KEY, NU_TILDA_LABEL); + builder.setShowing(ZERO_KEY, NU_TILDA_LABEL); + + // builder.selectDictionary(selectedDict); + } + + public static void setKEquationEddy(DictionaryPanelBuilder builder) { + // Dictionary selectedDict = builder.getSelectedModel().getDictionary(); + builder.setShowing(FIXED_KEY, KEQUATION_LABEL); + // builder.setShowing(MIXING_KEY, KEQUATION_LABEL); + builder.setShowing(NONUNIFROM_KEY, KEQUATION_LABEL); + builder.setShowing(TIMEVARYING_KEY, KEQUATION_LABEL); + builder.setShowing(INOUT_KEY, KEQUATION_LABEL); + builder.setShowing(ZERO_KEY, KEQUATION_LABEL); + + // builder.selectDictionary(selectedDict); + } + + public static void setKOmega(DictionaryPanelBuilder builder) { + // Dictionary selectedDict = builder.getSelectedModel().getDictionary(); + // Dictionary selectedCompanion = + // builder.getSelectedModel().getCompanion().getDictionary(); + + builder.setShowing(FIXED_KEY, OMEGA_LABEL); + builder.setShowing(MIXING_KEY, OMEGA_LABEL); + builder.setShowing(NONUNIFROM_KEY, OMEGA_LABEL); + builder.setShowing(TIMEVARYING_KEY, OMEGA_LABEL); + builder.setShowing(INOUT_KEY, OMEGA_LABEL); + builder.setShowing(ZERO_KEY, OMEGA_LABEL); + + // builder.selectDictionaries(selectedDict, selectedCompanion); + } + + public static void setKEpsilon(DictionaryPanelBuilder builder) { + // Dictionary selectedDict = builder.getSelectedModel().getDictionary(); + // Dictionary selectedCompanion = + // builder.getSelectedModel().getCompanion().getDictionary(); + + builder.setShowing(FIXED_KEY, EPSILON_LABEL); + builder.setShowing(MIXING_KEY, EPSILON_LABEL); + builder.setShowing(NONUNIFROM_KEY, EPSILON_LABEL); + builder.setShowing(TIMEVARYING_KEY, EPSILON_LABEL); + builder.setShowing(INOUT_KEY, EPSILON_LABEL); + builder.setShowing(ZERO_KEY, EPSILON_LABEL); + + // builder.selectDictionaries(selectedDict, selectedCompanion); + } +} diff --git a/src/eu/engys/gui/casesetup/cellzones/CellZoneComparator.java b/src/eu/engys/gui/casesetup/cellzones/CellZoneComparator.java new file mode 100644 index 0000000..9a2d7a1 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/CellZoneComparator.java @@ -0,0 +1,50 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones; + +import static eu.engys.core.project.zero.cellzones.CellZoneType.HUMIDITY_KEY; +import static eu.engys.core.project.zero.cellzones.CellZoneType.MRF_KEY; +import static eu.engys.core.project.zero.cellzones.CellZoneType.POROUS_KEY; +import static eu.engys.core.project.zero.cellzones.CellZoneType.SLIDING_MESH_KEY; +import static eu.engys.core.project.zero.cellzones.CellZoneType.THERMAL_KEY; + +import java.util.Arrays; +import java.util.Comparator; + +import eu.engys.core.project.zero.cellzones.CellZoneType; + +public class CellZoneComparator implements Comparator { + + public static final String[] ORDERED_KEYS = new String[] { POROUS_KEY, MRF_KEY, SLIDING_MESH_KEY, THERMAL_KEY, HUMIDITY_KEY }; + + @Override + public int compare(CellZoneType type1, CellZoneType type2) { + int indexType1 = Arrays.asList(ORDERED_KEYS).indexOf(type1.getKey()); + int indexType2 = Arrays.asList(ORDERED_KEYS).indexOf(type2.getKey()); + return Integer.compare(indexType1, indexType2); + } + +} diff --git a/src/eu/engys/gui/casesetup/cellzones/CellZonesFactory.java b/src/eu/engys/gui/casesetup/cellzones/CellZonesFactory.java new file mode 100644 index 0000000..e5e3fb6 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/CellZonesFactory.java @@ -0,0 +1,188 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones; + +import static eu.engys.core.project.zero.cellzones.CellZoneType.HUMIDITY_KEY; +import static eu.engys.core.project.zero.cellzones.CellZoneType.MRF_KEY; +import static eu.engys.core.project.zero.cellzones.CellZoneType.POROUS_KEY; +import static eu.engys.core.project.zero.cellzones.CellZoneType.SLIDING_MESH_KEY; +import static eu.engys.core.project.zero.cellzones.CellZoneType.THERMAL_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.ABSOLUTE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.ATTACHED_PATCHES_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.AXIS_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.C0_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.C1_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.CE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.CM_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.D_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.E1_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.E2_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.F_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.NON_ROTATING_PATCHES_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.OMEGA_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.ORIGIN_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.PERIOD_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.PLACE_HOLDER_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.POROUS_DARCY_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.POROUS_POWER_LAW_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.SPECIFIC_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.T0_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.TEMPERATURE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.THERMAL_EXPONENTIAL_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.THERMAL_FIXED_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.THERMAL_SCALAR_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.THETA_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.T_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.VOLUME_MODE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.W_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.t0_KEY; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DimensionedScalar; +import eu.engys.util.DimensionalUnits; + +public class CellZonesFactory { + + /* + * MRF + */ + public static Dictionary mrf = new Dictionary(MRF_KEY) { + { + add(TYPE, MRF_KEY); + add(ORIGIN_KEY, "(0 0 0)"); + add(AXIS_KEY, "(0 0 1)"); + add(OMEGA_KEY, "constant 104.72"); + add(NON_ROTATING_PATCHES_KEY, "()"); + add(ATTACHED_PATCHES_KEY, "()"); + } + }; + + /* + * Porous + */ + public static Dictionary porousDarcyForchheimer = new Dictionary(POROUS_KEY) { + { + add(TYPE, POROUS_DARCY_KEY); + add(E1_KEY, "(1 0 0)"); + add(E2_KEY, "(0 1 0)"); + add(new DimensionedScalar(D_KEY, "(100 1000 1000)", DimensionalUnits._M2)); + add(new DimensionedScalar(F_KEY, "(100 1000 1000)", DimensionalUnits._M)); + } + }; + + public static Dictionary porousPowerLaw = new Dictionary(POROUS_KEY) { + { + add(TYPE, POROUS_POWER_LAW_KEY); + add(C0_KEY, "1e-14"); + add(C1_KEY, "1"); + } + }; + + /* + * Thermal + */ + public static Dictionary thermalFixedTemperature = new Dictionary(THERMAL_KEY) { + { + add(TYPE, THERMAL_FIXED_KEY); + add(TEMPERATURE_KEY, "constant 350"); + } + }; + + public static Dictionary thermalFixedTemperature_OS = new Dictionary(THERMAL_KEY) { + { + add(TYPE, THERMAL_FIXED_KEY); + add(T_KEY, "350"); + } + }; + + public static Dictionary thermalExponential = new Dictionary(THERMAL_KEY) { + { + add(TYPE, THERMAL_EXPONENTIAL_KEY); + add(CM_KEY, "0.291"); + add(CE_KEY, "1.369"); + add(T0_KEY, "350"); + } + }; + + public static Dictionary thermalScalarSemiImplicit = new Dictionary(THERMAL_KEY) { + { + add(TYPE, THERMAL_SCALAR_KEY); + add(VOLUME_MODE_KEY, ABSOLUTE_KEY); + add(PLACE_HOLDER_KEY, "(65 0)"); + } + }; + + /* + * Humidity + */ + + public static Dictionary humidity = new Dictionary(HUMIDITY_KEY) { + { + add(TYPE, HUMIDITY_KEY); + add(VOLUME_MODE_KEY, ABSOLUTE_KEY); + add(W_KEY, "(100 0)"); + } + }; + + /* + * Rotating + */ + public static Dictionary slidingMesh = new Dictionary(SLIDING_MESH_KEY) { + { + add(ORIGIN_KEY, "(0 0 0)"); + add(AXIS_KEY, "(0 0 1)"); + add(OMEGA_KEY, "1"); + + } + }; + + public static Dictionary coupledSlidingMesh_steady = new Dictionary(SLIDING_MESH_KEY) { + { + add(ORIGIN_KEY, "(0 0 0)"); + add(AXIS_KEY, "(0 0 1)"); + add(THETA_KEY, "60"); + add(PERIOD_KEY, "150"); + } + }; + + public static Dictionary coupledSlidingMesh_transient = new Dictionary(SLIDING_MESH_KEY) { + { + add(ORIGIN_KEY, "(0 0 0)"); + add(AXIS_KEY, "(0 0 1)"); + add(OMEGA_KEY, "-308.92"); + add(t0_KEY, "2"); + } + }; + + // For tests purposes only + public static Dictionary thermalScalarSemiImplicit_Specific = new Dictionary(THERMAL_KEY) { + { + add(TYPE, THERMAL_SCALAR_KEY); + add(VOLUME_MODE_KEY, SPECIFIC_KEY); + add(PLACE_HOLDER_KEY, "(1 2)"); + } + }; + +} diff --git a/src/eu/engys/gui/casesetup/cellzones/CellZonesPanel.java b/src/eu/engys/gui/casesetup/cellzones/CellZonesPanel.java new file mode 100644 index 0000000..d182ca2 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/CellZonesPanel.java @@ -0,0 +1,224 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones; + +import static eu.engys.gui.casesetup.cellzones.SourceTypeSelectionPanel.UPDATE_SELECTION; +import static eu.engys.gui.casesetup.cellzones.SourceTypeSelectionPanel.ZONE_TYPE_ACTIVE; +import static eu.engys.gui.casesetup.cellzones.SourceTypeSelectionPanel.ZONE_TYPE_INACTIVE; +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; +import javax.swing.JComponent; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.cellzones.CellZoneType; +import eu.engys.gui.AbstractGUIPanel; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.util.Util; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.StringField; + +public class CellZonesPanel extends AbstractGUIPanel { + + public static final String CELL_ZONES = "Cell Zones"; + public static final String CELL_ZONE_NAME_LABEL = "CellZone Name"; + public static final String CELL_ZONE_TYPE_LABEL = "CellZone Type"; + + private CellZonesTreeNodeManager treeNodeManager; + private List types; + + private StringField zoneNameField; + private SourcePanelContainer centerPanel; + private SourceTypeSelectionPanel zoneTypePanel; + +// private PropertyChangeListener zoneNameListener; + + @Inject + public CellZonesPanel(Model model, Set cellZoneTypes, Set modules) { + super(CELL_ZONES, model); + this.treeNodeManager = new CellZonesTreeNodeManager(model, this); + this.types = new LinkedList<>(); + types.addAll(cellZoneTypes); + types.addAll(ModulesUtil.getCellZoneTypes(modules)); + Collections.sort(types, new CellZoneComparator()); + model.addObserver(treeNodeManager); + } + + protected JComponent layoutComponents() { + centerPanel = new SourcePanelContainer(types); + + PanelBuilder typeBuilder = new PanelBuilder(); + this.zoneNameField = initNameField(); + this.zoneTypePanel = initTypePanel(); + typeBuilder.addComponent(CELL_ZONE_NAME_LABEL, zoneNameField); + typeBuilder.addComponent(CELL_ZONE_TYPE_LABEL, zoneTypePanel); + + PanelBuilder panelBuilder = new PanelBuilder(); + panelBuilder.addComponent(typeBuilder.removeMargins().getPanel()); + panelBuilder.addComponent(centerPanel); + + return panelBuilder.removeMargins().getPanel(); + } + + private StringField initNameField() { + final StringField zoneNameField = stringField(); +// zoneNameListener = new PropertyChangeListener() { +// @Override +// public void propertyChange(PropertyChangeEvent evt) { +// CellZone[] cellzones = treeNodeManager.getSelectedValues(); +// if (cellzones.length == 1 && cellzones[0] != null) { +// cellzones[0].setName(zoneNameField.getText()); +// treeNodeManager.refreshNode(cellzones[0]); +// } +// } +// }; +// zoneNameField.addPropertyChangeListener(zoneNameListener); + zoneNameField.setEnabled(false); + return zoneNameField; + } + + private SourceTypeSelectionPanel initTypePanel() { + SourceTypeSelectionPanel panel = new SourceTypeSelectionPanel(model, types); + panel.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(ZONE_TYPE_ACTIVE)) { + CellZone[] selection = treeNodeManager.getSelectedValues(); + CellZoneType type = (CellZoneType) evt.getNewValue(); + if (Util.isVarArgsNotNullAndOfSize(1, selection)) { + showPanel(type, selection[0]); + } + } else if (evt.getPropertyName().equals(ZONE_TYPE_INACTIVE)) { + CellZone[] selection = treeNodeManager.getSelectedValues(); + CellZoneType type = (CellZoneType) evt.getNewValue(); + if (Util.isVarArgsNotNullAndOfSize(1, selection)) { + hidePanel(type, selection[0]); + } + } else if (evt.getPropertyName().equals(UPDATE_SELECTION)) { + updateSelection(treeNodeManager.getSelectedValues()); + } + } + + private void showPanel(CellZoneType type, CellZone cellZone) { + String typeKey = type.getKey(); + cellZone.getTypes().add(typeKey); + if (!cellZone.hasDictionary(typeKey)) { + cellZone.setDictionary(typeKey, type.getDefaultDictionary()); + } + centerPanel.showPanel(type, cellZone.getDictionary(typeKey)); + } + + private void hidePanel(CellZoneType type, CellZone cellZone) { + cellZone.getTypes().remove(type.getKey()); + centerPanel.hidePanel(type); + } + + }); + return panel; + } + + public void updateSelection(CellZone[] selection) { +// zoneNameField.removePropertyChangeListener(zoneNameListener); + if (Util.isVarArgsNotNullAndOfSize(1, selection)) { + zoneNameField.setValue(selection[0].getName()); + zoneNameField.setEnabled(false); + zoneTypePanel.handleSelectionOnTree(selection[0]); + centerPanel.handleSelectionOnTree(selection[0]); + } else { + StringBuilder sb = new StringBuilder(); + for (CellZone cellZone : selection) { + sb.append(cellZone.getName() + " "); + } + zoneNameField.setValue(sb.toString()); + zoneNameField.setEnabled(false); + zoneTypePanel.handleSelectionOnTree(null); + centerPanel.handleSelectionOnTree(null); + } +// zoneNameField.addPropertyChangeListener(zoneNameListener); + } + + @Override + public void load() { + for (CellZoneType type : types) { + type.updateStatusByState(); + } + } + + @Override + public void stateChanged() { + for (CellZoneType type : types) { + type.updateStatusByState(); + } + fixCellZonesTypes(); + } + + private void fixCellZonesTypes() { + for (CellZone zone : model.getCellZones()) { + for (CellZoneType type : types) { + if (!type.isEnabled()) { + zone.getTypes().remove(type.getKey()); + } + } + centerPanel.saveDictionaryToCellZone(zone); + } + } + + // When change selection + public void saveCellZones(CellZone[] values) { + if (Util.isVarArgsNotNull(values)) { + for (CellZone zone : values) { + zoneTypePanel.saveTypesToCellZone(zone); + centerPanel.saveDictionaryToCellZone(zone); + } + } + } + + @Override + public void clear() { + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) new CellZone[0]); + } + + @Override + public void save() { + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) treeNodeManager.getSelectedValues()); + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } + +} diff --git a/src/eu/engys/gui/casesetup/cellzones/CellZonesTreeNodeManager.java b/src/eu/engys/gui/casesetup/cellzones/CellZonesTreeNodeManager.java new file mode 100644 index 0000000..195a9b4 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/CellZonesTreeNodeManager.java @@ -0,0 +1,270 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones; + +import java.awt.Component; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; + +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreePath; + +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.cellzones.CellZones; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.SelectCellZonesEvent; +import eu.engys.gui.tree.AbstractSelectionHandler; +import eu.engys.gui.tree.DefaultTreeNodeManager; +import eu.engys.gui.tree.SelectionHandler; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.TreeUtil; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class CellZonesTreeNodeManager extends DefaultTreeNodeManager { + + private Map zonesMap; + private SelectionHandler selectionHandler; + + public CellZonesTreeNodeManager(Model model, CellZonesPanel cellZonesPanel) { + super(model, cellZonesPanel); + this.selectionHandler = new CellZonesSelectionHandler(cellZonesPanel); + this.zonesMap = new HashMap<>(); + } + + @Override + public void update(Observable o, final Object arg) { + if (arg instanceof CellZones) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + selectionHandler.disable(); + loadTree(); + selectVisibleItems(); + expandTree(); + selectionHandler.enable(); + } + }); + } + } + + private void loadTree() { + clear(); + for (CellZone zone : model.getCellZones()) { + addCellZone(root, zone); + } + treeChanged(root); + } + + private void selectVisibleItems() { + // for(DefaultMutableTreeNode node : nodeMap.values()) + // getTree().getCheckManager().selectNode(node); + } + + private void expandTree() { + getTree().expandNode(getRoot()); + } + + private void addCellZone(DefaultMutableTreeNode parent, CellZone cellZone) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(cellZone); + parent.add(node); + nodeMap.put(cellZone, node); + zonesMap.put(node, cellZone); + } + + public CellZone[] getSelectedValues() { + if (getTree() != null) { + TreePath[] selectionPaths = getTree().getSelectedDescendantOf(getRoot()); + CellZone[] cellzones = new CellZone[selectionPaths.length]; + for (int i = 0; i < selectionPaths.length; i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPaths[i].getLastPathComponent(); + CellZone zone = zonesMap.get(node); + cellzones[i] = zone; + } + return cellzones; + } + return new CellZone[0]; + } + + // public void setSelectedValue(String name) { + // System.out.println("CellZonesTreeNodeManager.setSelectedValue() name: "+name); + // DefaultMutableTreeNode selectedNode = nodeMap.get(name); + // if (getTree() != null) { + // TreePath treePath; + // if (name != null && selectedNode != null) { + // treePath = new TreePath(getModel().getPathToRoot(selectedNode)); + // } else { + // treePath = new TreePath(getModel().getPathToRoot(getRoot())); + // } + // getTree().getSelectionModel().setSelectionPath(treePath); + // getTree().clearSelection(); + // } + // } + + public void clear() { + // clear node before selection handler! + clearNode(root); + selectionHandler.clear(); + nodeMap.clear(); + zonesMap.clear(); + } + + public DefaultMutableTreeNode getRoot() { + return root; + } + + @Override + public Class getRendererClass() { + return CellZone.class; + } + + public DefaultTreeCellRenderer getRenderer() { + return new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObject = node.getUserObject(); + + if (userObject instanceof CellZone) { + CellZone patch = (CellZone) userObject; + setText(patch.getName()); + } + setIcon(null); + return this; + } + }; + } + + @Override + public SelectionHandler getSelectionHandler() { + return selectionHandler; + } + + private final class CellZonesSelectionHandler extends AbstractSelectionHandler { + + private CellZonesPanel panel; + private CellZone[] currentSelection; + + public CellZonesSelectionHandler(CellZonesPanel panel) { + this.panel = panel; + } + + @Override + public void handleSelection(boolean fire3DEvent, Object... selection) { + if (currentSelection != null && currentSelection.length > 0) { + panel.saveCellZones(currentSelection); + } + if (TreeUtil.isConsistent(selection, CellZone.class)) { + this.currentSelection = Arrays.copyOf(selection, selection.length, CellZone[].class); + } else { + this.currentSelection = new CellZone[0]; + } + panel.updateSelection(currentSelection); + if (fire3DEvent) { + EventManager.triggerEvent(this, new SelectCellZonesEvent(currentSelection)); + } + } + + @Override + public void handleVisibility(VisibleItem item) { + } + + @Override + public void process3DSelectionEvent(Picker picker, Actor actor, boolean keep) { + if (getTree() != null && actor.getVisibleItem() instanceof VisibleItem) { + DefaultMutableTreeNode selectedNode = nodeMap.get(actor.getVisibleItem()); + if (selectedNode != null) { + getTree().setSelectedNode(selectedNode); + } + } + } + + @Override + public void process3DVisibilityEvent(boolean selected) { + if (getTree() != null) { + for (DefaultMutableTreeNode node : nodeMap.values()) { + // if (selected) { + // getTree().getCheckManager().selectNode(node); + // } else { + getTree().getCheckManager().deselectNode(node); + // } + } + } + } + + @Override + public void clear() { + currentSelection = null; + } + } + + // private final class PopUpMenuListener extends MouseAdapter { + // private JPopupMenu popUp; + // private RemoveSurfaceAction removeAction; + // + // public PopUpMenuListener() { + // // removeAction = new RemoveSurfaceAction(); + // + // popUp = new JPopupMenu(); + // // popUp.add(removeAction); + // } + // + // @Override + // public void mouseReleased(MouseEvent e) { + // // Surface[] selectedValues = treeNodeManager.getSelectedValues(); + // // if (SwingUtilities.isRightMouseButton(e) && selectedValues.length + // // > 0) { + // // removeAction.setEnabled(selectedValues[0].getType() != + // // Type.REGION); + // // popUp.show(treeNodeManager, e.getX(), e.getY()); + // // } + // } + // } + + // private final class VisibilityListener implements TableModelListener { + // @Override + // public void tableChanged(TableModelEvent e) { + // if (e.getType() == TableModelEvent.UPDATE && e.getColumn() == 0) { + // if (e.getSource() instanceof AbstractTableModel) { + // AbstractTableModel tm = (AbstractTableModel) e.getSource(); + // int row = e.getFirstRow(); + // boolean b = Boolean.parseBoolean(tm.getValueAt(row, + // GeometryTreePanel.VISIBLE_INDEX).toString()); + // Surface surface = (Surface) tm.getValueAt(row, + // GeometryTreePanel.SURFACE_INDEX); + // EventManager.triggerEvent(this, new VisibleSurfaceEvent(surface, b)); + // } + // } + // } + // } +} diff --git a/src/eu/engys/gui/casesetup/cellzones/SourcePanelContainer.java b/src/eu/engys/gui/casesetup/cellzones/SourcePanelContainer.java new file mode 100644 index 0000000..8cbb55c --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/SourcePanelContainer.java @@ -0,0 +1,114 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones; + +import java.awt.BorderLayout; +import java.util.List; + +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.cellzones.CellZonePanel; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.cellzones.CellZoneType; +import eu.engys.util.ui.builder.PanelBuilder; + +public class SourcePanelContainer extends JPanel { + + private PanelBuilder builder; + private List types; + + public SourcePanelContainer(List types) { + super(new BorderLayout()); + this.types = types; + this.builder = new PanelBuilder(); + layoutComponents(); + } + + private void layoutComponents() { + for (CellZoneType type : types) { + CellZonePanel typePanel = type.getPanel(); + typePanel.layoutPanel(); + + builder.startHidable(type.getKey()); + + builder.startGroup("empty"); + builder.endGroup(); + + builder.startGroup(type.getLabel()); + builder.addComponent(typePanel.getPanel()); + builder.endGroup(); + + builder.endHidable(); + } + add(builder.removeMargins().getPanel()); + } + + public void handleSelectionOnTree(CellZone cellZone) { + if (cellZone != null) { + for (CellZoneType type : types) { + if (cellZone.hasType(type.getKey()) && type.isEnabled()) { + showPanel(type, cellZone.getDictionary(type.getKey())); + } else { + hidePanel(type); + } + } + } else { + hideAllPanels(); + } + } + + public void showPanel(CellZoneType type, Dictionary cellZoneDictionary) { + type.getPanel().loadFromDictionary(cellZoneDictionary); + builder.setShowing(type.getKey(), type.getLabel()); + } + + public void hidePanel(CellZoneType type) { + builder.setShowing(type.getKey(), "empty"); + } + + private void hideAllPanels() { + for (CellZoneType type : types) { + hidePanel(type); + } + } + + public void saveDictionaryToCellZone(CellZone zone) { + for (CellZoneType type : types) { + String typeKey = type.getKey(); + if (type.isEnabled()) { + if (zone.getTypes().contains(typeKey)) { + Dictionary dict = type.getPanel().saveToDictionary(); + zone.setDictionary(typeKey, dict); + } else { + zone.removeDictionary(typeKey); + } + } else { + zone.removeDictionary(typeKey); + } + } + } +} diff --git a/src/eu/engys/gui/casesetup/cellzones/SourceTypeSelectionPanel.java b/src/eu/engys/gui/casesetup/cellzones/SourceTypeSelectionPanel.java new file mode 100644 index 0000000..dc01682 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/SourceTypeSelectionPanel.java @@ -0,0 +1,135 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.JCheckBox; +import javax.swing.JPanel; + +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.cellzones.CellZoneType; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.builder.PanelBuilder; + +public class SourceTypeSelectionPanel extends JPanel { + + public static final String ZONE_TYPE_ACTIVE = "zoneTypeActive"; + public static final String ZONE_TYPE_INACTIVE = "zoneTypeInactive"; + public static final String UPDATE_SELECTION = "updateSelection"; + + private Map checkBoxMap = new HashMap<>(); + private PanelBuilder builder; + private ActionListener checkBoxListener; + + public SourceTypeSelectionPanel(Model m, List types) { + super(new BorderLayout()); + + builder = new PanelBuilder(); + + checkBoxListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + JCheckBox checkBox = (JCheckBox) e.getSource(); + boolean selected = checkBox.isSelected(); + CellZoneType type = (CellZoneType) checkBox.getClientProperty("type"); + firePropertyChange(selected ? ZONE_TYPE_ACTIVE : ZONE_TYPE_INACTIVE, null, type); + } + }; + + for (CellZoneType zoneType : types) { + JCheckBox checkBox = ComponentsFactory.checkField(zoneType.getLabel()); + checkBox.putClientProperty("type", zoneType); + checkBox.addActionListener(checkBoxListener); + + checkBox.setEnabled(false); + checkBox.setName(zoneType.getLabel()); + checkBoxMap.put(zoneType, checkBox); + builder.addComponent(checkBox); + } + add(builder.removeMargins().getPanel()); + } + + public void handleSelectionOnTree(CellZone cellZone) { + removeListeners(); + if (cellZone != null) { + selectCheckBoxes(cellZone); + } else { + unselectAndDisableCheckBoxes(); + } + addListeners(); + } + + public void saveTypesToCellZone(CellZone zone) { + for (CellZoneType type : checkBoxMap.keySet()) { + JCheckBox checkBox = checkBoxMap.get(type); + if (checkBox.isSelected()) { + zone.getTypes().add(type.getKey()); + } else { + zone.getTypes().remove(type.getKey()); + } + } + } + + private void selectCheckBoxes(CellZone cellZone) { + for (CellZoneType type : checkBoxMap.keySet()) { + JCheckBox checkBox = checkBoxMap.get(type); + checkBox.setEnabled(type.isEnabled()); + if (cellZone.getTypes().contains(type.getKey()) && type.isEnabled()) { + checkBox.setSelected(true); + } else { + checkBox.setSelected(false); + } + } + } + + private void unselectAndDisableCheckBoxes() { + for (CellZoneType type : checkBoxMap.keySet()) { + JCheckBox checkBox = checkBoxMap.get(type); + checkBox.setSelected(false); + checkBox.setEnabled(false); + } + } + + private void addListeners() { + for (JCheckBox check : checkBoxMap.values()) { + check.addActionListener(checkBoxListener); + } + } + + private void removeListeners() { + for (JCheckBox check : checkBoxMap.values()) { + check.removeActionListener(checkBoxListener); + } + } +} diff --git a/src/eu/engys/gui/casesetup/cellzones/StandardCellZonesBuilder.java b/src/eu/engys/gui/casesetup/cellzones/StandardCellZonesBuilder.java new file mode 100644 index 0000000..dfb7017 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/StandardCellZonesBuilder.java @@ -0,0 +1,328 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.core.project.system.SnappyHexMeshDict.CELL_ZONE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.ABSOLUTE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.ACTIVE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.AXES_ROTATION_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.AXIS_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.C0_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.C1_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.CARTESIAN_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.COEFFS_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.COORDINATE_ROTATION_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.COORDINATE_SYSTEM_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.DARCY_FORCHHEIMER_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.D_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.E1_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.E2_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.EXPLICIT_POROSITY_SOURCE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.F_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.INJECTION_RATE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.MRF_SOURCE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.OMEGA_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.ORIGIN_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.POROUS_DARCY_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.POROUS_POWER_LAW_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.POWER_LAW_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.SCALAR_EXPLICIT_SET_VALUE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.SELECTION_MODE_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.THERMAL_FIXED_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.T_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.VOLUME_MODE_KEY; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.core.project.system.FvOptions; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.cellzones.CellZoneType; +import eu.engys.core.project.zero.cellzones.CellZones; +import eu.engys.core.project.zero.cellzones.CellZonesBuilder; + +public class StandardCellZonesBuilder implements CellZonesBuilder { + + private static final Logger logger = LoggerFactory.getLogger(StandardCellZonesBuilder.class); + + @Override + public void loadMRFDictionary(Model model) { + loadMRFDictionary(model.getCellZones(), model.getProject().getSystemFolder().getFvOptions()); + } + + @Override + public void loadMRFDictionary(CellZones cellZones, FvOptions fvOptions) { + if (fvOptions != null) { + for (CellZone cellZone : cellZones) { + String zoneName = cellZone.getName(); + List zonesDict = fvOptions.getDictionaries(); + for (Dictionary zoneDict : zonesDict) { + if (zoneDict.found(CELL_ZONE_KEY) && zoneDict.lookup(CELL_ZONE_KEY).equals(zoneName)) { + if (zoneDict.found(TYPE) && zoneDict.lookup(TYPE).equals(MRF_SOURCE_KEY)) { + Dictionary encodedDictionary = new Dictionary(""); + encodedDictionary.add(TYPE, CellZoneType.MRF_KEY); + if (zoneDict.isDictionary(MRF_SOURCE_KEY + COEFFS_KEY)) { + Dictionary coeffs = zoneDict.subDict(MRF_SOURCE_KEY + COEFFS_KEY); + encodedDictionary.add(ORIGIN_KEY, coeffs.lookup(ORIGIN_KEY)); + encodedDictionary.add(AXIS_KEY, coeffs.lookup(AXIS_KEY)); + encodedDictionary.add(OMEGA_KEY, coeffs.lookup(OMEGA_KEY)); + } + + cellZone.setDictionary(CellZoneType.MRF_KEY, encodedDictionary); + cellZone.getTypes().add(CellZoneType.MRF_KEY); + } + } + } + } + } + } + + @Override + public void saveMRFDictionary(Model model) { + saveMRFDictionary(model.getCellZones(), model.getProject().getSystemFolder().getFvOptions()); + } + + @Override + public void saveMRFDictionary(CellZones cellZones, FvOptions fvOptions) { + if (fvOptions != null) { + for (CellZone cellZone : cellZones) { + String zoneName = cellZone.getName(); + + if (cellZone.hasType(CellZoneType.MRF_KEY)) { + Dictionary encodedDictionary = cellZone.getDictionary(CellZoneType.MRF_KEY); + + Dictionary toBeDecoded = new Dictionary(zoneName + "_" + CellZoneType.MRF_KEY); + toBeDecoded.add(TYPE, MRF_SOURCE_KEY); + toBeDecoded.add(ACTIVE_KEY, "true"); + toBeDecoded.add(SELECTION_MODE_KEY, CELL_ZONE_KEY); + toBeDecoded.add(CELL_ZONE_KEY, zoneName); + + Dictionary MRFSourceCoeffs = new Dictionary(MRF_SOURCE_KEY + COEFFS_KEY); + MRFSourceCoeffs.add(ORIGIN_KEY, encodedDictionary.lookup(ORIGIN_KEY)); + MRFSourceCoeffs.add(AXIS_KEY, encodedDictionary.lookup(AXIS_KEY)); + MRFSourceCoeffs.add(OMEGA_KEY, encodedDictionary.lookup(OMEGA_KEY)); + + toBeDecoded.add(MRFSourceCoeffs); + + fvOptions.add(toBeDecoded); + } else { + logger.debug(zoneName + " NOT A MRF Zone " + cellZone.getTypes()); + } + } + } + } + + @Override + public void loadPorousDictionary(Model model) { + loadPorousDictionary(model.getCellZones(), model.getProject().getSystemFolder().getFvOptions()); + } + + @Override + public void loadPorousDictionary(CellZones cellZones, FvOptions fvOptions) { + if (fvOptions != null) { + for (CellZone cellZone : cellZones) { + String zoneName = cellZone.getName(); + List zonesDict = fvOptions.getDictionaries(); + for (Dictionary zoneDict : zonesDict) { + if (zoneDict.found(CELL_ZONE_KEY) && zoneDict.lookup(CELL_ZONE_KEY).equals(zoneName)) { + if (zoneDict.lookup(TYPE).equals(EXPLICIT_POROSITY_SOURCE_KEY)) { + Dictionary encodedDictionary = new Dictionary(""); + if (zoneDict.isDictionary(EXPLICIT_POROSITY_SOURCE_KEY + COEFFS_KEY)) { + Dictionary coeffDict = zoneDict.subDict(EXPLICIT_POROSITY_SOURCE_KEY + COEFFS_KEY); + String type = coeffDict.lookup(TYPE); + + if (type.equals(DARCY_FORCHHEIMER_KEY)) { + encodedDictionary.add(TYPE, POROUS_DARCY_KEY); + + Dictionary darcyDict = coeffDict.subDict(DARCY_FORCHHEIMER_KEY + COEFFS_KEY); + encodedDictionary.add(darcyDict.lookupScalar(D_KEY)); + encodedDictionary.add(darcyDict.lookupScalar(F_KEY)); + if (darcyDict.isDictionary(COORDINATE_SYSTEM_KEY)) { + Dictionary coordSys = darcyDict.subDict(COORDINATE_SYSTEM_KEY); + if (coordSys.isDictionary(COORDINATE_ROTATION_KEY)) { + Dictionary rotation = coordSys.subDict(COORDINATE_ROTATION_KEY); + encodedDictionary.add(E1_KEY, rotation.lookup(E1_KEY)); + encodedDictionary.add(E2_KEY, rotation.lookup(E2_KEY)); + } + } + } else if (type.equals(POWER_LAW_KEY)) { + encodedDictionary.add(TYPE, POROUS_POWER_LAW_KEY); + Dictionary powerLawDict = coeffDict.subDict(POWER_LAW_KEY + COEFFS_KEY); + encodedDictionary.add(C0_KEY, powerLawDict.lookup(C0_KEY)); + encodedDictionary.add(C1_KEY, powerLawDict.lookup(C1_KEY)); + } else { + System.err.println("Unknown type"); + } + } + + cellZone.getTypes().add(CellZoneType.POROUS_KEY); + cellZone.setDictionary(CellZoneType.POROUS_KEY, encodedDictionary); + } + } + } + } + } + } + + @Override + public void savePorousDictionary(Model model) { + savePorousDictionary(model.getCellZones(), model.getProject().getSystemFolder().getFvOptions()); + } + + @Override + public void savePorousDictionary(CellZones cellZones, FvOptions fvOptions) { + if (fvOptions != null) { + for (CellZone cellZone : cellZones) { + String zoneName = cellZone.getName(); + if (cellZone.hasType(CellZoneType.POROUS_KEY)) { + Dictionary encodedDictionary = cellZone.getDictionary(CellZoneType.POROUS_KEY); + String typeString = encodedDictionary.lookup(TYPE); + + Dictionary toBeDecoded = new Dictionary(zoneName + "_" + CellZoneType.POROUS_KEY); + toBeDecoded.add(TYPE, EXPLICIT_POROSITY_SOURCE_KEY); + toBeDecoded.add(ACTIVE_KEY, "true"); + toBeDecoded.add(SELECTION_MODE_KEY, CELL_ZONE_KEY); + toBeDecoded.add(CELL_ZONE_KEY, zoneName); + + Dictionary porousCoeffs = new Dictionary(EXPLICIT_POROSITY_SOURCE_KEY + COEFFS_KEY); + toBeDecoded.add(porousCoeffs); + + if (typeString != null && typeString.equals(POROUS_DARCY_KEY)) { + porousCoeffs.add(TYPE, DARCY_FORCHHEIMER_KEY); + + Dictionary darcyDict = new Dictionary(DARCY_FORCHHEIMER_KEY + COEFFS_KEY); + if (encodedDictionary.found(D_KEY)) + darcyDict.add(encodedDictionary.lookupScalar(D_KEY)); + if (encodedDictionary.found(F_KEY)) + darcyDict.add(encodedDictionary.lookupScalar(F_KEY)); + + Dictionary coordSys = new Dictionary(COORDINATE_SYSTEM_KEY); + coordSys.add(TYPE, CARTESIAN_KEY); + coordSys.add(ORIGIN_KEY, "(0 0 0)"); + + Dictionary rotation = new Dictionary(COORDINATE_ROTATION_KEY); + rotation.add(TYPE, AXES_ROTATION_KEY); + rotation.add(E1_KEY, encodedDictionary.lookup(E1_KEY)); + rotation.add(E2_KEY, encodedDictionary.lookup(E2_KEY)); + coordSys.add(rotation); + + darcyDict.add(coordSys); + + porousCoeffs.add(darcyDict); + } else if (typeString != null && typeString.equals(POROUS_POWER_LAW_KEY)) { + porousCoeffs.add(TYPE, POWER_LAW_KEY); + + Dictionary powerLawDict = new Dictionary(POWER_LAW_KEY + COEFFS_KEY); + powerLawDict.add(C0_KEY, encodedDictionary.lookup(C0_KEY)); + powerLawDict.add(C1_KEY, encodedDictionary.lookup(C1_KEY)); + porousCoeffs.add(powerLawDict); + } + + fvOptions.add(toBeDecoded); + } else { + logger.debug(zoneName + " NOT A Porous Zone " + cellZone.getTypes()); + } + } + } + } + + @Override + public void loadThermalDictionary(Model model) { + loadThermalDictionary(model.getCellZones(), model.getProject().getSystemFolder().getFvOptions(), model.getState()); + } + + @Override + public void loadThermalDictionary(CellZones cellZones, FvOptions fvOptions, State state) { + if (fvOptions != null) { + for (CellZone cellZone : cellZones) { + String zoneName = cellZone.getName(); + List zonesDict = fvOptions.getDictionaries(); + for (Dictionary zoneDict : zonesDict) { + if (zoneDict.found(CELL_ZONE_KEY) && zoneDict.lookup(CELL_ZONE_KEY).equals(zoneName)) { + String type = zoneDict.lookup(TYPE); + if (type != null && (type.equals(SCALAR_EXPLICIT_SET_VALUE_KEY))) { + Dictionary encodedDictionary = new Dictionary(""); + if (type.equals(SCALAR_EXPLICIT_SET_VALUE_KEY)) { + if (zoneDict.isDictionary(SCALAR_EXPLICIT_SET_VALUE_KEY + COEFFS_KEY)) { + Dictionary coeffDict = zoneDict.subDict(SCALAR_EXPLICIT_SET_VALUE_KEY + COEFFS_KEY); + Dictionary injectionDict = coeffDict.subDict(INJECTION_RATE_KEY); + + encodedDictionary.add(TYPE, THERMAL_FIXED_KEY); + encodedDictionary.add(T_KEY, injectionDict.lookup(T_KEY)); + } + } + cellZone.getTypes().add(CellZoneType.THERMAL_KEY); + cellZone.setDictionary(CellZoneType.THERMAL_KEY, encodedDictionary); + } + } + } + } + } + } + + @Override + public void saveThermalDictionary(Model model) { + saveThermalDictionary(model.getCellZones(), model.getProject().getSystemFolder().getFvOptions(), model.getState()); + } + + @Override + public void saveThermalDictionary(CellZones cellZones, FvOptions fvOptions, State state) { + if (fvOptions != null) { + for (CellZone cellZone : cellZones) { + String zoneName = cellZone.getName(); + if (cellZone.hasType(CellZoneType.THERMAL_KEY)) { + Dictionary encodedDictionary = cellZone.getDictionary(CellZoneType.THERMAL_KEY); + + Dictionary toBeDecoded = new Dictionary(zoneName + "_" + CellZoneType.THERMAL_KEY); + toBeDecoded.add(TYPE, SCALAR_EXPLICIT_SET_VALUE_KEY); + toBeDecoded.add(ACTIVE_KEY, "true"); + toBeDecoded.add(SELECTION_MODE_KEY, CELL_ZONE_KEY); + toBeDecoded.add(CELL_ZONE_KEY, zoneName); + + Dictionary coeffsDict = new Dictionary(SCALAR_EXPLICIT_SET_VALUE_KEY + COEFFS_KEY); + coeffsDict.add(VOLUME_MODE_KEY, ABSOLUTE_KEY); + + Dictionary injectionDict = new Dictionary(INJECTION_RATE_KEY); + injectionDict.add(T_KEY, encodedDictionary.lookup(T_KEY)); + coeffsDict.add(injectionDict); + + toBeDecoded.add(coeffsDict); + + fvOptions.add(toBeDecoded); + } else { + logger.debug(zoneName + " NOT A Thermal Zone " + cellZone.getTypes()); + } + } + } + } + +} diff --git a/src/eu/engys/gui/casesetup/cellzones/mrf/StandardCellZoneMRFPanel.java b/src/eu/engys/gui/casesetup/cellzones/mrf/StandardCellZoneMRFPanel.java new file mode 100644 index 0000000..45b2e77 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/mrf/StandardCellZoneMRFPanel.java @@ -0,0 +1,90 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.cellzones.mrf; + +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.AXIS_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.OMEGA_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.ORIGIN_KEY; +import static eu.engys.gui.casesetup.cellzones.CellZonesFactory.mrf; +import static eu.engys.gui.casesetup.cellzones.mrf.StandardMRF.MRF_LABEL; + +import javax.inject.Inject; +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.modules.cellzones.CellZonePanel; +import eu.engys.core.project.zero.cellzones.CellZoneType; +import eu.engys.util.ui.builder.PanelBuilder; + +public class StandardCellZoneMRFPanel implements CellZonePanel { + + private PanelBuilder builder = new PanelBuilder(); + private DictionaryModel mrfModel; + + @Inject + public StandardCellZoneMRFPanel() { + } + + @Override + public void layoutPanel() { + mrfModel = new DictionaryModel(new Dictionary(mrf)); + builder.addComponent(ORIGIN_LABEL, mrfModel.bindPoint(ORIGIN_KEY)); + builder.addComponent(AXIS_LABEL, mrfModel.bindPoint(AXIS_KEY)); + builder.addComponent(OMEGA_RAD_S_LABEL, mrfModel.bindConstantDouble(OMEGA_KEY)); + mrfModel.refresh(); + + } + + @Override + public JComponent getPanel() { + JPanel panel = builder.getPanel(); + panel.setBorder(BorderFactory.createTitledBorder(MRF_LABEL)); + panel.setName(MRF_LABEL); + return panel; + } + + @Override + public void stateChanged() { + } + + @Override + public void loadFromDictionary(Dictionary cellZoneDictionary) { + Dictionary d = new Dictionary(CellZoneType.MRF_KEY); + d.merge(cellZoneDictionary); + mrfModel.setDictionary(cellZoneDictionary); + + } + + @Override + public Dictionary saveToDictionary() { + return mrfModel.getDictionary(); + } + +} diff --git a/src/eu/engys/gui/casesetup/cellzones/mrf/StandardMRF.java b/src/eu/engys/gui/casesetup/cellzones/mrf/StandardMRF.java new file mode 100644 index 0000000..8d30d67 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/mrf/StandardMRF.java @@ -0,0 +1,92 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones.mrf; + +import static eu.engys.gui.casesetup.cellzones.CellZonesFactory.mrf; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.cellzones.CellZonePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.cellzones.CellZoneType; + +public class StandardMRF implements CellZoneType { + + public static final String MRF_LABEL = "MRF"; + + private CellZonePanel panel; + + @Inject + public StandardMRF(Model model) { + this.panel = new StandardCellZoneMRFPanel(); + } + + @Override + public String getKey() { + return CellZoneType.MRF_KEY; + } + + @Override + public String getLabel() { + return MRF_LABEL; + } + + @Override + public void updateStatusByState() { + panel.stateChanged(); + } + + @Override + public Dictionary getDefaultDictionary() { + return new Dictionary(mrf); + } + + @Override + public CellZonePanel getPanel() { + return panel; + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public void setEnabled(boolean enabled) { + } + + @Override + public String toString() { + return getKey(); + } + + @Override + public int compareTo(CellZoneType type) { + return getLabel().compareTo(type.getLabel()); + } + +} diff --git a/src/eu/engys/gui/casesetup/cellzones/porous/StandardCellZonePorousPanel.java b/src/eu/engys/gui/casesetup/cellzones/porous/StandardCellZonePorousPanel.java new file mode 100644 index 0000000..be500d9 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/porous/StandardCellZonePorousPanel.java @@ -0,0 +1,105 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones.porous; + +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.C0_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.C1_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.D_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.E1_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.E2_KEY; +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.F_KEY; +import static eu.engys.gui.casesetup.cellzones.CellZonesFactory.porousDarcyForchheimer; +import static eu.engys.gui.casesetup.cellzones.CellZonesFactory.porousPowerLaw; +import static eu.engys.gui.casesetup.cellzones.porous.StandardPorous.POROUS_LABEL; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.modules.cellzones.CellZonePanel; +import eu.engys.core.project.zero.cellzones.CellZoneType; +import eu.engys.util.DimensionalUnits; + +public class StandardCellZonePorousPanel implements CellZonePanel { + + private DictionaryPanelBuilder builder; + + @Inject + public StandardCellZonePorousPanel() { + } + + @Override + public void layoutPanel() { + DictionaryModel porousDarcyModel = new DictionaryModel(new Dictionary(porousDarcyForchheimer)); + DictionaryModel porousPowerLawModel = new DictionaryModel(new Dictionary(porousPowerLaw)); + + builder = new DictionaryPanelBuilder(); + builder.startChoice(MODEL_LABEL); + + builder.startDictionary(DARCY_FORCHHEIMER, porousDarcyModel); + builder.addComponent(E1_LABEL, porousDarcyModel.bindPoint(E1_KEY)); + builder.addComponent(E2_LABEL, porousDarcyModel.bindPoint(E2_KEY)); + builder.addComponent(VISCOUS_LOSS_LABEL, porousDarcyModel.bindDimensionedPoint(D_KEY, DimensionalUnits._M2)); + builder.addComponent(INERTIAL_LOSS_LABEL, porousDarcyModel.bindDimensionedPoint(F_KEY, DimensionalUnits._M)); + builder.endDictionary(); + + builder.startDictionary(POWER_LAW, porousPowerLawModel); + builder.addComponent(C0_LABEL, porousPowerLawModel.bindDouble(C0_KEY)); + builder.addComponent(C1_LABEL, porousPowerLawModel.bindDouble(C1_KEY)); + builder.endDictionary(); + + builder.endChoice(); + } + + @Override + public JComponent getPanel() { + JPanel panel = builder.getPanel(); + panel.setBorder(BorderFactory.createTitledBorder(POROUS_LABEL)); + panel.setName(POROUS_LABEL); + return panel; + } + + @Override + public void stateChanged() { + } + + @Override + public void loadFromDictionary(Dictionary cellZoneDictionary) { + Dictionary d = new Dictionary(CellZoneType.POROUS_KEY); + d.merge(cellZoneDictionary); + builder.selectDictionary(d); + } + + @Override + public Dictionary saveToDictionary() { + return builder.getSelectedModel().getDictionary(); + } +} diff --git a/src/eu/engys/gui/casesetup/cellzones/porous/StandardPorous.java b/src/eu/engys/gui/casesetup/cellzones/porous/StandardPorous.java new file mode 100644 index 0000000..2b72676 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/porous/StandardPorous.java @@ -0,0 +1,92 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones.porous; + +import static eu.engys.gui.casesetup.cellzones.CellZonesFactory.porousDarcyForchheimer; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.cellzones.CellZonePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.cellzones.CellZoneType; + +public class StandardPorous implements CellZoneType { + + public static final String POROUS_LABEL = "Porous Medium"; + + private CellZonePanel panel; + + @Inject + public StandardPorous(Model model) { + this.panel = new StandardCellZonePorousPanel(); + } + + @Override + public String getKey() { + return CellZoneType.POROUS_KEY; + } + + @Override + public String getLabel() { + return POROUS_LABEL; + } + + @Override + public void updateStatusByState() { + panel.stateChanged(); + } + + @Override + public Dictionary getDefaultDictionary() { + return new Dictionary(porousDarcyForchheimer); + } + + @Override + public CellZonePanel getPanel() { + return panel; + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public void setEnabled(boolean enabled) { + } + + @Override + public String toString() { + return getKey(); + } + + @Override + public int compareTo(CellZoneType type) { + return getLabel().compareTo(type.getLabel()); + } + +} diff --git a/src/eu/engys/gui/casesetup/cellzones/thermal/StandardCellZoneThermalPanel.java b/src/eu/engys/gui/casesetup/cellzones/thermal/StandardCellZoneThermalPanel.java new file mode 100644 index 0000000..3e490c9 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/thermal/StandardCellZoneThermalPanel.java @@ -0,0 +1,92 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones.thermal; + +import static eu.engys.core.project.zero.cellzones.CellZonesUtils.T_KEY; +import static eu.engys.gui.casesetup.cellzones.CellZonesFactory.thermalFixedTemperature_OS; +import static eu.engys.gui.casesetup.cellzones.thermal.StandardThermal.THERMAL_LABEL; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.modules.cellzones.CellZonePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.cellzones.CellZoneType; + +public class StandardCellZoneThermalPanel implements CellZonePanel { + + private DictionaryPanelBuilder builder; + + @Inject + public StandardCellZoneThermalPanel(Model model) { + } + + @Override + public void layoutPanel() { + DictionaryModel fixedModel = new DictionaryModel(new Dictionary(thermalFixedTemperature_OS)); + + builder = new DictionaryPanelBuilder(); + builder.startChoice(MODEL_LABEL); + + builder.startDictionary(FIXED_TEMPERATURE_LABEL, fixedModel); + builder.addComponent(FIXED_TEMPERATURE_K_LABEL, fixedModel.bindConstantDouble(T_KEY)); + builder.endDictionary(); + + builder.endChoice(); + + } + + @Override + public JComponent getPanel() { + JPanel panel = builder.getPanel(); + panel.setBorder(BorderFactory.createTitledBorder(THERMAL_LABEL)); + panel.setName(THERMAL_LABEL); + return panel; + } + + @Override + public void stateChanged() { + } + + @Override + public void loadFromDictionary(Dictionary cellZoneDictionary) { + Dictionary d = new Dictionary(CellZoneType.THERMAL_KEY); + d.merge(cellZoneDictionary); + builder.selectDictionary(d); + } + + @Override + public Dictionary saveToDictionary() { + return builder.getSelectedModel().getDictionary(); + } + +} diff --git a/src/eu/engys/gui/casesetup/cellzones/thermal/StandardThermal.java b/src/eu/engys/gui/casesetup/cellzones/thermal/StandardThermal.java new file mode 100644 index 0000000..8e67353 --- /dev/null +++ b/src/eu/engys/gui/casesetup/cellzones/thermal/StandardThermal.java @@ -0,0 +1,100 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.cellzones.thermal; + +import static eu.engys.gui.casesetup.cellzones.CellZonesFactory.thermalFixedTemperature_OS; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.cellzones.CellZonePanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.cellzones.CellZoneType; + +public class StandardThermal implements CellZoneType { + + public static final String THERMAL_LABEL = "Thermal Source"; + + private Model model; + private boolean enabled; + + private CellZonePanel panel; + + @Inject + public StandardThermal(Model model) { + this.model = model; + this.panel = new StandardCellZoneThermalPanel(model); + this.enabled = false; + } + + @Override + public String getKey() { + return CellZoneType.THERMAL_KEY; + } + + @Override + public String getLabel() { + return THERMAL_LABEL; + } + + @Override + public void updateStatusByState() { + boolean isEnergy = model.getState().isEnergy(); + setEnabled(isEnergy); + panel.stateChanged(); + } + + @Override + public boolean isEnabled() { + return enabled; + } + + @Override + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @Override + public Dictionary getDefaultDictionary() { + return new Dictionary(thermalFixedTemperature_OS); + } + + @Override + public CellZonePanel getPanel() { + return panel; + } + + @Override + public String toString() { + return getKey(); + } + + @Override + public int compareTo(CellZoneType type) { + return getLabel().compareTo(type.getLabel()); + } + +} diff --git a/src/eu/engys/gui/casesetup/fields/AbstractFieldsInitialisationPanel.java b/src/eu/engys/gui/casesetup/fields/AbstractFieldsInitialisationPanel.java new file mode 100644 index 0000000..26e8a66 --- /dev/null +++ b/src/eu/engys/gui/casesetup/fields/AbstractFieldsInitialisationPanel.java @@ -0,0 +1,365 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.fields; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.core.dictionary.Dictionary.VALUE; +import static eu.engys.core.project.zero.fields.Fields.ALPHA_1; +import static eu.engys.core.project.zero.fields.Fields.AOA; +import static eu.engys.core.project.zero.fields.Fields.CO2; +import static eu.engys.core.project.zero.fields.Fields.EPSILON; +import static eu.engys.core.project.zero.fields.Fields.K; +import static eu.engys.core.project.zero.fields.Fields.MU_SGS; +import static eu.engys.core.project.zero.fields.Fields.NU_TILDA; +import static eu.engys.core.project.zero.fields.Fields.OMEGA; +import static eu.engys.core.project.zero.fields.Fields.P; +import static eu.engys.core.project.zero.fields.Fields.P_RGH; +import static eu.engys.core.project.zero.fields.Fields.SMOKE; +import static eu.engys.core.project.zero.fields.Fields.T; +import static eu.engys.core.project.zero.fields.Fields.U; +import static eu.engys.core.project.zero.fields.Fields.W; +import static eu.engys.core.project.zero.fields.Initialisations.CELL_SET_KEY; +import static eu.engys.core.project.zero.fields.Initialisations.DEFAULT_KEY; +import static eu.engys.core.project.zero.fields.Initialisations.FIXED_VALUE_KEY; +import static eu.engys.util.Symbols.EPSILON_SYMBOL; +import static eu.engys.util.Symbols.K_SYMBOL; +import static eu.engys.util.Symbols.M2_S; +import static eu.engys.util.Symbols.M2_S2; +import static eu.engys.util.Symbols.MU_MEASURE; +import static eu.engys.util.Symbols.M_S; +import static eu.engys.util.Symbols.OMEGA_SYMBOL; +import static eu.engys.util.Symbols.PASCAL; + +import java.awt.event.ActionEvent; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryBuilder; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.builder.JComboBoxController; +import eu.engys.util.ui.builder.PanelBuilder; + +public abstract class AbstractFieldsInitialisationPanel extends DefaultGUIPanel { + + public static final String FIELDS_INITIALISATION = "Fields Initialisation"; + + public static final String DEFAULT_LABEL = "Default"; + public static final String FIXED_VALUE_LABEL = "Fixed Value"; + public static final String CELL_SET_LABEL = "CellSet"; + public static final String EDIT_LABEL = "Edit"; + + private Map unityMeasures = new HashMap<>(); + protected Map fieldBuilderMap = new HashMap<>(); + protected Map builders = new HashMap<>(); + + private PanelBuilder mainBuilder; + + public AbstractFieldsInitialisationPanel(Model model) { + super(FIELDS_INITIALISATION, model); + } + + @Override + protected JComponent layoutComponents() { + mainBuilder = new PanelBuilder(); + + JScrollPane mainScrollPane = new JScrollPane(mainBuilder.removeMargins().getPanel()); + mainScrollPane.setBorder(BorderFactory.createEmptyBorder()); + + builders.put(DEFAULT_KEY, defaultBuilder); + builders.put(FIXED_VALUE_KEY, fixedValueBuilder); + builders.put(CELL_SET_KEY, cellSetBuilder); + + return mainScrollPane; + } + + public interface Builder { + void build(DictionaryPanelBuilder builder, Field field); + } + + private final Builder defaultBuilder = new Builder() { + @Override + public void build(DictionaryPanelBuilder builder, Field field) { + DictionaryModel dictModel = new DictionaryModel(DictionaryBuilder.newDictionary("initialisation").field(TYPE, DEFAULT_KEY).done()) { + public String getKey() { + return DEFAULT_KEY; + } + }; + builder.startDictionary(DEFAULT_LABEL, dictModel); + builder.endGroup(); + } + }; + + private final Builder fixedValueBuilder = new Builder() { + @Override + public void build(DictionaryPanelBuilder builder, Field field) { + if (field.getFieldType().isScalar()) { + DictionaryModel dictScalarModel = new DictionaryModel(DictionaryBuilder.newDictionary("initialisation").field(TYPE, FIXED_VALUE_KEY).field(VALUE, "uniform 0").done()) { + public String getKey() { + return FIXED_VALUE_KEY; + } + }; + builder.startDictionary(FIXED_VALUE_LABEL, dictScalarModel); + builder.addComponent("Value", dictScalarModel.bindUniformDouble(VALUE)); + builder.endDictionary(); + } else { + DictionaryModel dictVectorModel = new DictionaryModel(DictionaryBuilder.newDictionary("initialisation").field(TYPE, FIXED_VALUE_KEY).field(VALUE, "uniform (0 0 0)").done()) { + public String getKey() { + return FIXED_VALUE_KEY; + } + }; + builder.startDictionary(FIXED_VALUE_LABEL, dictVectorModel); + builder.addComponent("Value", dictVectorModel.bindUniformPoint(VALUE)); + builder.endDictionary(); + } + } + }; + + private final Builder cellSetBuilder = new Builder() { + @Override + public void build(DictionaryPanelBuilder builder, final Field field) { + final DictionaryModel dictModel = new DictionaryModel(getCellSetDefaultDict()) { + public String getKey() { + return CELL_SET_KEY; + } + }; + + builder.startDictionary(CELL_SET_LABEL, dictModel); + builder.addComponent("Default Value", dictModel.bindUniformDouble("defaultValue")); + + JButton editButton = getEditButton(field, dictModel); + builder.addRight(editButton); + builder.endDictionary(); + } + + private JButton getEditButton(final Field field, final DictionaryModel dictModel) { + final CellSetDialog cellSetDialog = new CellSetDialog(model, dictModel, field.getName(), "setSources", AbstractFieldsInitialisationPanel.this); + final Action action = new AbstractAction(EDIT_LABEL, EDIT_ICON) { + @Override + public void actionPerformed(ActionEvent e) { + cellSetDialog.showDialog(); + } + }; + + cellSetDialog.getDialog().addComponentListener(new ComponentAdapter() { + + @Override + public void componentShown(ComponentEvent e) { + super.componentShown(e); + action.setEnabled(false); + } + + @Override + public void componentHidden(ComponentEvent e) { + super.componentHidden(e); + action.setEnabled(true); + } + }); + + JButton editButton = new JButton(action); + editButton.setName(EDIT_LABEL); + return editButton; + } + + private Dictionary getCellSetDefaultDict() { + DictionaryBuilder boxBuilder = DictionaryBuilder.newDictionary("boxToCell"); + boxBuilder.field("box", "(0 0 0) (2.0 2.0 1.0 )"); + boxBuilder.field("value", "0.0"); + + DictionaryBuilder builder = DictionaryBuilder.newDictionary("initialisation"); + builder.field(TYPE, CELL_SET_KEY); + builder.field("defaultValue", "uniform 0.0"); + builder.list("setSources", boxBuilder.done()); + + return builder.done(); + } + + }; + + @Override + public void load() { + rebuildPanel(); + } + + @Override + public void save() { + for (Field f : fieldBuilderMap.keySet()) { + DictionaryPanelBuilder b = fieldBuilderMap.get(f); + Dictionary dictionary = b.getSelectedModel().getDictionary(); + f.setInitialisation(dictionary); + } + } + + @Override + public void stateChanged() { + rebuildLater(); + } + + @Override + public void materialsChanged() { + rebuildLater(); + } + + @Override + public void fieldsChanged() { + rebuildLater(); + } + + private void rebuildLater() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + rebuildPanel(); + } + }); + } + + protected void rebuildPanel() { + fieldBuilderMap.clear(); + mainBuilder.clear(); + + JButton initialiseButton = new JButton(ActionManager.getInstance().get("initialise.fields")); + initialiseButton.setName("fields.initialise.button"); + mainBuilder.addRight(initialiseButton); + + Fields fields = model.getFields(); + unityMeasures(fields, model.getState().isCompressible()); + + for (Field field : fields.orderedFields()) { + buildFieldPanel(field); + } + initialiseButton.setEnabled(fields.size() > 0); + + revalidate(); + repaint(); + } + + protected JComboBoxController buildFieldPanel(Field field) { + String name = field.getName(); + String labelText = unityMeasure(name); + DictionaryPanelBuilder builder = new DictionaryPanelBuilder(); + builder.addSeparator(labelText); + builder.indent(); + builder.prefix(name + "."); + JComboBoxController combo = (JComboBoxController) builder.startChoice("Type"); + String[] initialisationMethods = field.getInitialisationMethods(); + + for (String method : initialisationMethods) { + if (builders.containsKey(method)) { + builders.get(method).build(builder, field); + } + } + + builder.endChoice(); + builder.addSeparator(""); + builder.outdent(); + builder.prefix(""); + + builder.selectDictionary(field.getInitialisation()); + + JPanel builderPanel = builder.getPanel(); + builderPanel.setName(name); + builderPanel.setBorder(BorderFactory.createTitledBorder("")); + + mainBuilder.addComponent(builderPanel); + + fieldBuilderMap.put(field, builder); + + return combo; + } + + private String unityMeasure(String name) { + return name + (unityMeasures.containsKey(name) ? " " + unityMeasures.get(name) : ""); + } + + private void unityMeasures(Fields fields, boolean compressible) { + unityMeasures = new HashMap(); + if (fields.containsKey(U)) + unityMeasures.put(U, M_S); + if (fields.containsKey(P)) + unityMeasures.put(P, compressible ? PASCAL : M2_S2); + if (fields.containsKey(P_RGH)) + unityMeasures.put(P_RGH, compressible ? PASCAL : M2_S2); + if (fields.containsKey(K)) + unityMeasures.put(K, K_SYMBOL); + if (fields.containsKey(OMEGA)) + unityMeasures.put(OMEGA, OMEGA_SYMBOL); + if (fields.containsKey(EPSILON)) + unityMeasures.put(EPSILON, EPSILON_SYMBOL); + if (fields.containsKey(NU_TILDA)) + unityMeasures.put(NU_TILDA, M2_S); + + // if (fields.containsKey("nut")) unityMeasures.put(get("nut")); + // if (fields.containsKey("mut")) unityMeasures.put(get("mut")); + // if (fields.containsKey("nuSgs")) unityMeasures.put(get("nuSgs")); + if (fields.containsKey(MU_SGS)) + unityMeasures.put(MU_SGS, MU_MEASURE); + // if (fields.containsKey("D")) unityMeasures.put(get("D")); + + if (fields.containsKey(T)) + unityMeasures.put(T, "[K]"); + if (fields.containsKey(W)) + unityMeasures.put(W, ""); + if (fields.containsKey(ALPHA_1)) + unityMeasures.put(ALPHA_1, "[phase 1]"); + if (fields.containsKey(AOA)) + unityMeasures.put(AOA, ""); + if (fields.containsKey(CO2)) + unityMeasures.put(CO2, ""); + if (fields.containsKey(SMOKE)) + unityMeasures.put(SMOKE, ""); + // if (fields.containsKey("rho")) unityMeasures.put(get("rho")); + // if (fields.containsKey("alphat")) unityMeasures.put(get("alphat")); + if (fields.containsKey("Intensity")) + unityMeasures.put("Intensity", ""); + } + + /** + * Resources + */ + + protected static final Icon EDIT_ICON = ResourcesUtil.getIcon("script.edit.icon"); + +} diff --git a/src/eu/engys/gui/casesetup/fields/CellSetDialog.java b/src/eu/engys/gui/casesetup/fields/CellSetDialog.java new file mode 100644 index 0000000..ff9b862 --- /dev/null +++ b/src/eu/engys/gui/casesetup/fields/CellSetDialog.java @@ -0,0 +1,259 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.fields; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dialog.ModalityType; +import java.awt.FlowLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.ListField; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.AddSurfaceEvent; +import eu.engys.gui.events.view3D.RemoveSurfaceEvent; +import eu.engys.util.ui.UiUtil; + +public class CellSetDialog extends JPanel { + + public static final String CELLSET_PANEL_NAME = "cellset.panel"; + public static final String CELLSET_REM_NAME = "cellset.rem"; + public static final String CELLSET_ADD_NAME = "cellset.add"; + + private Map rowsMap = new HashMap<>(); + private JDialog dialog; + private JPanel rowsPanel; + private JScrollPane scrollPane; + private DictionaryModel dictionaryModel; + private final String fieldName; + private final Model model; + private final String listName; + private Component parentComponent; + private JButton okButton; + + public CellSetDialog(Model model, DictionaryModel dictionaryModel, String fieldName, String listName, Component parentComponent) { + super(new BorderLayout()); + this.dictionaryModel = dictionaryModel; + this.fieldName = fieldName; + this.model = model; + this.parentComponent = parentComponent; + this.listName = listName; + setName(CELLSET_PANEL_NAME); + layoutComponents(); + } + + private void layoutComponents() { + JPanel addRemovePanel = new JPanel(new FlowLayout()); + addRemovePanel.setOpaque(false); + JButton addButton = new JButton(new AddRowAction()); + addButton.setName(CELLSET_ADD_NAME); + JButton remButton = new JButton(new RemRowAction()); + remButton.setName(CELLSET_REM_NAME); + addRemovePanel.add(addButton); + addRemovePanel.add(remButton); + + JPanel okPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + okButton = new JButton(new AbstractAction("OK") { + @Override + public void actionPerformed(ActionEvent e) { + handleDialogClose(); + } + + }); + okButton.setName("OK"); + okPanel.add(okButton); + + rowsPanel = new JPanel(new GridBagLayout()); + JPanel centerPanel = new JPanel(new BorderLayout()); + centerPanel.add(rowsPanel, BorderLayout.NORTH); + centerPanel.add(new JLabel(), BorderLayout.CENTER); + + add(addRemovePanel, BorderLayout.NORTH); + scrollPane = new JScrollPane(centerPanel); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + add(scrollPane, BorderLayout.CENTER); + add(okPanel, BorderLayout.SOUTH); + layoutDialog(); + } + + public JDialog getDialog() { + return dialog; + } + + private void layoutDialog() { + Window parent = parentComponent == null ? UiUtil.getActiveWindow() : SwingUtilities.getWindowAncestor(parentComponent); + String title = fieldName.equals(Fields.ALPHA_1) ? fieldName + " [phase 1]" : fieldName; + dialog = new JDialog(parent, title, ModalityType.MODELESS); + dialog.setName("cellset.dialog"); + dialog.addWindowListener(new WindowAdapter() { + + @Override + public void windowClosing(WindowEvent e) { + handleDialogClose(); + } + }); + + dialog.add(this); + dialog.setSize(600, 400); + dialog.setLocationRelativeTo(null); + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.getRootPane().setDefaultButton(okButton); + } + + public void showDialog() { + load(); + dialog.setVisible(true); + } + + public void load() { + Dictionary initialisation = dictionaryModel.getDictionary(); + if (initialisation != null && initialisation.isList(listName)) { + ListField sources = initialisation.getList(listName); + for (int i = 0; i < sources.getListElements().size(); i++) { + Dictionary source = (Dictionary) sources.getListElements().get(i); + addRow(new CellSetRow(model, fieldName, source, i)); + } + } + } + + private void addRow(CellSetRow row) { + Integer index = rowsMap.size(); + rowsMap.put(index, row); + rowsPanel.add(row, new GridBagConstraints(0, index, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 10, 5, 10), 0, 0)); + rowsPanel.revalidate(); + EventManager.triggerEvent(this, new AddSurfaceEvent(row.getSurface())); + } + + private void handleDialogClose() { + save(); + clear(); + dialog.setVisible(false); + } + + public void save() { + ListField regions = new ListField(listName); + for (Dictionary dict : getDictionaries()) { + regions.add(dict); + } + Dictionary initialisation = dictionaryModel.getDictionary(); + initialisation.remove(listName); + initialisation.add(new ListField(regions)); + } + + public void clear() { + for (CellSetRow row : rowsMap.values()) { + row.clear(); + } + EventManager.triggerEvent(this, new RemoveSurfaceEvent(getSurfaces().toArray(new Surface[0]))); + rowsPanel.removeAll(); + rowsMap.clear(); + } + + private List getSurfaces() { + List surfaces = new ArrayList<>(); + for (CellSetRow row : rowsMap.values()) { + surfaces.add(row.getSurface()); + } + return surfaces; + } + + private List getDictionaries() { + List dicts = new ArrayList<>(); + for (CellSetRow row : rowsMap.values()) { + dicts.add(row.getDictionary()); + } + return dicts; + } + + private void removeRow() { + CellSetRow row = rowsMap.get(rowsMap.size() - 1); + rowsPanel.remove(row); + rowsPanel.revalidate(); + rowsMap.remove(rowsMap.size() - 1); + EventManager.triggerEvent(this, new RemoveSurfaceEvent(row.getSurface())); + } + + private class AddRowAction extends AbstractAction { + + public AddRowAction() { + super("+"); + } + + @Override + public void actionPerformed(ActionEvent e) { + addRow(new CellSetRow(model, fieldName, new Dictionary("boxToCell"), rowsMap.size())); + } + + } + + private class RemRowAction extends AbstractAction { + + public RemRowAction() { + super("-"); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (rowsMap.size() > 1) { + removeRow(); + } + } + } + + // Test purpose only + public void setInitialisation(Dictionary initialisation) { + this.dictionaryModel = new DictionaryModel(initialisation); + } + + // Test purpose only + public Dictionary getInitialisation() { + return dictionaryModel.getDictionary(); + } +} diff --git a/src/eu/engys/gui/casesetup/fields/CellSetRow.java b/src/eu/engys/gui/casesetup/fields/CellSetRow.java new file mode 100644 index 0000000..c96448e --- /dev/null +++ b/src/eu/engys/gui/casesetup/fields/CellSetRow.java @@ -0,0 +1,515 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.fields; + +import static eu.engys.core.project.geometry.Surface.CENTRE_KEY; +import static eu.engys.core.project.geometry.Surface.INNER_RADIUS_KEY; +import static eu.engys.core.project.geometry.Surface.MAX_KEY; +import static eu.engys.core.project.geometry.Surface.MIN_KEY; +import static eu.engys.core.project.geometry.Surface.OUTER_RADIUS_KEY; +import static eu.engys.core.project.geometry.Surface.POINT1_KEY; +import static eu.engys.core.project.geometry.Surface.POINT2_KEY; +import static eu.engys.core.project.geometry.Surface.RADIUS_KEY; +import static eu.engys.core.project.system.SetFieldsDict.BOX_TO_CELL_KEY; +import static eu.engys.core.project.system.SetFieldsDict.CYLINDER_TO_CELL_KEY; +import static eu.engys.core.project.system.SetFieldsDict.RING_TO_CELL_KEY; +import static eu.engys.core.project.system.SetFieldsDict.SPHERE_TO_CELL_KEY; +import static eu.engys.gui.casesetup.boundaryconditions.utils.BoundaryConditionsUtils.VALUE_KEY; +import static eu.engys.gui.mesh.panels.GeometriesPanelBuilder.CENTRE_LABEL; +import static eu.engys.gui.mesh.panels.GeometriesPanelBuilder.INNER_RADIUS_LABEL; +import static eu.engys.gui.mesh.panels.GeometriesPanelBuilder.MAX_LABEL; +import static eu.engys.gui.mesh.panels.GeometriesPanelBuilder.MIN_LABEL; +import static eu.engys.gui.mesh.panels.GeometriesPanelBuilder.OUTER_RADIUS_LABEL; +import static eu.engys.gui.mesh.panels.GeometriesPanelBuilder.POINT_1_LABEL; +import static eu.engys.gui.mesh.panels.GeometriesPanelBuilder.POINT_2_LABEL; +import static eu.engys.gui.mesh.panels.GeometriesPanelBuilder.RADIUS_LABEL; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.BorderFactory; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FieldChangeListener; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.Box; +import eu.engys.core.project.geometry.surface.Cylinder; +import eu.engys.core.project.geometry.surface.Ring; +import eu.engys.core.project.geometry.surface.Sphere; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.AddSurfaceEvent; +import eu.engys.gui.events.view3D.ChangeSurfaceEvent; +import eu.engys.gui.events.view3D.RemoveSurfaceEvent; +import eu.engys.gui.view3D.BoxEventButton; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; + +public class CellSetRow extends JPanel { + + private static final Logger logger = LoggerFactory.getLogger(CellSetRow.class); + + public static final String BOX = "Box"; + public static final String SPHERE = "Sphere"; + public static final String CYLINDER = "Cylinder"; + public static final String RING = "Ring"; + + public static final String CELLSET_NAME = "cellset"; + public static final String CELLSET_ROW_NAME = "cellset.row"; + public static final String CELLSET_VALUE_NAME = "cellset.value"; + public static final String CELLSET_SLIDER_NAME = "cellset.slider"; + + private DictionaryModel boxModel = new DictionaryModel(getDefaultBoxModelDictionary()); + private DictionaryModel sphereModel = new DictionaryModel(getDefaultSphereModelDictionary()); + private DictionaryModel cylinderModel = new DictionaryModel(getDefaultCylinderModelDictionary()); + private DictionaryModel ringModel = new DictionaryModel(getDefaultRingModelDictionary()); + private FieldChangeListener listener; + private JPanel coordinatesPanel; + private Dictionary loadedDictionary; + private Surface surface; + private Integer index; + private JComboBox choice; + private DoubleField valueField; + private SliderChangeListener valueSliderListener; + private TextFieldChangeListener valueFieldListener; + + private BoxEventButton showBoxButton; + + private Model model; + private String fieldName; + + public CellSetRow(Model model, String fieldName, Dictionary dictionary, Integer index) { + super(new BorderLayout()); + this.model = model; + this.fieldName = fieldName; + this.loadedDictionary = dictionary; + this.index = index; + this.listener = new ValueFieldChangeListener(); + setName(CELLSET_ROW_NAME + "." + index); + layoutComponents(); + load(); + } + + private void layoutComponents() { + setBorder(BorderFactory.createTitledBorder(BOX)); + setOpaque(false); + coordinatesPanel = createCoordinatersPanel(); + choice = create3DCombo(); + JPanel valuePanel = createValuePanel(); + + add(choice, BorderLayout.NORTH); + add(coordinatesPanel, BorderLayout.CENTER); + add(valuePanel, BorderLayout.SOUTH); + } + + private JPanel createValuePanel() { + valueField = ComponentsFactory.doubleField(0.0, 0.0, 1.0); + valueField.setName(CELLSET_VALUE_NAME + "." + index); + JSlider valueSlider = createSlider(); + valueSlider.addChangeListener(valueSliderListener = new SliderChangeListener(valueField)); + valueField.addPropertyChangeListener(valueFieldListener = new TextFieldChangeListener(valueSlider)); + + JPanel valuePanel = new JPanel(new GridBagLayout()); + valuePanel.setOpaque(false); + valuePanel.add(valueSlider, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + valuePanel.add(valueField, new GridBagConstraints(2, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(12, 5, 0, 0), 0, 0)); + + valuePanel.add(label(getLeftLabel()), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + valuePanel.add(label(getRightLabel()), new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + valuePanel.add(label(""), new GridBagConstraints(2, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + return valuePanel; + } + + private void load() { + if (!loadedDictionary.isEmpty()) { + Dictionary newDict = new Dictionary(""); + if (loadedDictionary.found("box")) { + String boxValue = loadedDictionary.lookup("box"); + String min = boxValue.substring(0, boxValue.indexOf(")") + 1).trim(); + String max = boxValue.replace(min, "").trim(); + newDict.add(MIN_KEY, min); + newDict.add(MAX_KEY, max); + choice.setSelectedItem(BOX); + boxModel.setDictionary(newDict); + surface.setGeometryDictionary(boxModel.getDictionary()); + } else if (loadedDictionary.found(CENTRE_KEY) && loadedDictionary.found(RADIUS_KEY)) {// sphere + newDict.add(CENTRE_KEY, loadedDictionary.lookup(CENTRE_KEY)); + newDict.add(RADIUS_KEY, loadedDictionary.lookup(RADIUS_KEY)); + choice.setSelectedItem(SPHERE); + sphereModel.setDictionary(newDict); + surface.setGeometryDictionary(sphereModel.getDictionary()); + } else if (loadedDictionary.found(POINT1_KEY) && loadedDictionary.found(RADIUS_KEY)) {// cylinder + newDict.add(RADIUS_KEY, loadedDictionary.lookup(RADIUS_KEY)); + newDict.add(POINT1_KEY, loadedDictionary.lookup(POINT1_KEY)); + newDict.add(POINT2_KEY, loadedDictionary.lookup(POINT2_KEY)); + choice.setSelectedItem(CYLINDER); + cylinderModel.setDictionary(newDict); + surface.setGeometryDictionary(cylinderModel.getDictionary()); + } else if (loadedDictionary.found(INNER_RADIUS_KEY) && loadedDictionary.found(OUTER_RADIUS_KEY)) {// ring + newDict.add(POINT1_KEY, loadedDictionary.lookup(POINT1_KEY)); + newDict.add(POINT2_KEY, loadedDictionary.lookup(POINT2_KEY)); + newDict.add(INNER_RADIUS_KEY, loadedDictionary.lookup(INNER_RADIUS_KEY)); + newDict.add(OUTER_RADIUS_KEY, loadedDictionary.lookup(OUTER_RADIUS_KEY)); + choice.setSelectedItem(RING); + ringModel.setDictionary(newDict); + surface.setGeometryDictionary(ringModel.getDictionary()); + } + + if (loadedDictionary.found(VALUE_KEY)) { + String value = loadedDictionary.lookup(VALUE_KEY); + valueField.setDoubleValue(Double.parseDouble(value)); + } + } else { + addNewBox(); + } + } + + private void addNewBox() { + surface = model.getGeometry().getFactory().newSurface(Box.class, "Box_" + index); + boxModel.setDictionary(surface.getGeometryDictionary()); + } + + private JSlider createSlider() { + JSlider valueSlider = new JSlider(JSlider.HORIZONTAL, 0, fieldName.equals(Fields.ALPHA_1) ? 1 : 100, 0); + valueSlider.setName(CELLSET_SLIDER_NAME + "." + index); + valueSlider.setMajorTickSpacing(10); + valueSlider.setPaintTicks(true); + valueSlider.setPaintTrack(true); + valueSlider.setPaintLabels(false); + return valueSlider; + } + + private JComboBox create3DCombo() { + choice = new JComboBox(new String[] { BOX, SPHERE, CYLINDER, RING }); + choice.setName(CELLSET_NAME + "." + index); + choice.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + CardLayout layout = (CardLayout) coordinatesPanel.getLayout(); + Surface existingSurface = surface; + if (existingSurface != null) { + EventManager.triggerEvent(this, new RemoveSurfaceEvent(surface)); + } + if (choice.getSelectedIndex() == 0) { + layout.show(coordinatesPanel, BOX); + setBorder(BorderFactory.createTitledBorder(BOX)); + surface = model.getGeometry().getFactory().newSurface(Box.class, BOX + "_" + index); + boxModel.setDictionary(surface.getGeometryDictionary()); + } else if (choice.getSelectedIndex() == 1) { + layout.show(coordinatesPanel, SPHERE); + setBorder(BorderFactory.createTitledBorder(SPHERE)); + surface = model.getGeometry().getFactory().newSurface(Sphere.class, SPHERE + "_" + index); + sphereModel.setDictionary(surface.getGeometryDictionary()); + } else if (choice.getSelectedIndex() == 2) { + layout.show(coordinatesPanel, CYLINDER); + setBorder(BorderFactory.createTitledBorder(CYLINDER)); + surface = model.getGeometry().getFactory().newSurface(Cylinder.class, CYLINDER + "_" + index); + cylinderModel.setDictionary(surface.getGeometryDictionary()); + } else if (choice.getSelectedIndex() == 3) { + layout.show(coordinatesPanel, RING); + setBorder(BorderFactory.createTitledBorder(RING)); + surface = model.getGeometry().getFactory().newSurface(Ring.class, RING + "_" + index); + ringModel.setDictionary(surface.getGeometryDictionary()); + } + if (existingSurface != null) { + EventManager.triggerEvent(this, new AddSurfaceEvent(surface)); + } + } + }); + return choice; + } + + private JPanel createCoordinatersPanel() { + CardLayout c = new CardLayout(); + JPanel p = new JPanel(c); + p.setOpaque(false); + p.add(getBoxPanel(), BOX); + p.add(getSpherePanel(), SPHERE); + p.add(getCylinderPanel(), CYLINDER); + p.add(getRingPanel(), RING); + c.show(p, BOX); + return p; + } + + private JPanel getBoxPanel() { + PanelBuilder boxBuilder = new PanelBuilder(); + DoubleField[] boxMin = boxModel.bindPoint(MIN_KEY, listener); + DoubleField[] boxMax = boxModel.bindPoint(MAX_KEY, listener); + + showBoxButton = new BoxEventButton(boxMin, boxMax); + + boxBuilder.addComponent(MIN_LABEL, boxMin[0], boxMin[1], boxMin[2], showBoxButton); + boxBuilder.addComponentAndSpan(MAX_LABEL, boxMax); + + return boxBuilder.getPanel(); + } + + private JPanel getSpherePanel() { + PanelBuilder sphereBuilder = new PanelBuilder(); + sphereBuilder.addComponent(CENTRE_LABEL, sphereModel.bindPoint(CENTRE_KEY, listener)); + sphereBuilder.addComponent(RADIUS_LABEL, sphereModel.bindDouble(RADIUS_KEY, listener)); + return sphereBuilder.getPanel(); + + } + + private JPanel getCylinderPanel() { + PanelBuilder cylinderBuilder = new PanelBuilder(); + cylinderBuilder.addComponent(POINT_1_LABEL, cylinderModel.bindPoint(POINT1_KEY, listener)); + cylinderBuilder.addComponent(POINT_2_LABEL, cylinderModel.bindPoint(POINT2_KEY, listener)); + cylinderBuilder.addComponent(RADIUS_LABEL, cylinderModel.bindDouble(RADIUS_KEY, listener)); + return cylinderBuilder.getPanel(); + } + + private JPanel getRingPanel() { + PanelBuilder ringBuilder = new PanelBuilder(); + ringBuilder.addComponent(POINT_1_LABEL, ringModel.bindPoint(POINT1_KEY, listener)); + ringBuilder.addComponent(POINT_2_LABEL, ringModel.bindPoint(POINT2_KEY, listener)); + ringBuilder.addComponent(INNER_RADIUS_LABEL, ringModel.bindDouble(INNER_RADIUS_KEY, listener)); + ringBuilder.addComponent(OUTER_RADIUS_LABEL, ringModel.bindDouble(OUTER_RADIUS_KEY, listener)); + return ringBuilder.getPanel(); + } + + public Surface getSurface() { + return surface; + } + + public Dictionary getDictionary() { + switch (choice.getItemAt(choice.getSelectedIndex())) { + case BOX: { + Dictionary boxToCell = new Dictionary(BOX_TO_CELL_KEY); + String min = boxModel.getDictionary().lookup(MIN_KEY); + String max = boxModel.getDictionary().lookup(MAX_KEY); + boxToCell.add("box", min + " " + max); + boxToCell.add(VALUE_KEY, String.valueOf(valueField.getDoubleValue())); + return boxToCell; + } + case SPHERE: { + Dictionary sphereToCell = new Dictionary(SPHERE_TO_CELL_KEY); + String centre = sphereModel.getDictionary().lookup(CENTRE_KEY); + String radius = sphereModel.getDictionary().lookup(RADIUS_KEY); + sphereToCell.add(CENTRE_KEY, centre); + sphereToCell.add(RADIUS_KEY, radius); + sphereToCell.add(VALUE_KEY, String.valueOf(valueField.getDoubleValue())); + return sphereToCell; + } + case CYLINDER: { + Dictionary cylinderToCell = new Dictionary(CYLINDER_TO_CELL_KEY); + String p1 = cylinderModel.getDictionary().lookup(POINT1_KEY); + String p2 = cylinderModel.getDictionary().lookup(POINT2_KEY); + String radius = cylinderModel.getDictionary().lookup(RADIUS_KEY); + cylinderToCell.add(POINT1_KEY, p1); + cylinderToCell.add(POINT2_KEY, p2); + cylinderToCell.add(RADIUS_KEY, radius); + cylinderToCell.add(VALUE_KEY, String.valueOf(valueField.getDoubleValue())); + return cylinderToCell; + } + case RING: { + Dictionary ringToCell = new Dictionary(RING_TO_CELL_KEY); + String p1 = ringModel.getDictionary().lookup(POINT1_KEY); + String p2 = ringModel.getDictionary().lookup(POINT2_KEY); + String iRadius = ringModel.getDictionary().lookup(INNER_RADIUS_KEY); + String oRadius = ringModel.getDictionary().lookup(OUTER_RADIUS_KEY); + ringToCell.add(POINT1_KEY, p1); + ringToCell.add(POINT2_KEY, p2); + ringToCell.add(INNER_RADIUS_KEY, iRadius); + ringToCell.add(OUTER_RADIUS_KEY, oRadius); + ringToCell.add(VALUE_KEY, String.valueOf(valueField.getDoubleValue())); + return ringToCell; + } + default: + return null; + } + } + + private class TextFieldChangeListener implements PropertyChangeListener { + + private JSlider slider; + + public TextFieldChangeListener(JSlider slider) { + this.slider = slider; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + slider.removeChangeListener(valueSliderListener); + DoubleField field = (DoubleField) evt.getSource(); + slider.setValue((int) (field.getDoubleValue() * 100)); + slider.addChangeListener(valueSliderListener); + } + } + }; + + private class SliderChangeListener implements ChangeListener { + + private DoubleField field; + + public SliderChangeListener(DoubleField field) { + this.field = field; + } + + @Override + public void stateChanged(ChangeEvent e) { + field.removePropertyChangeListener(valueFieldListener); + JSlider slider = (JSlider) e.getSource(); + double value = slider.getValue(); + field.setDoubleValue(value / slider.getMaximum()); + field.addPropertyChangeListener(valueFieldListener); + } + }; + + private class ValueFieldChangeListener implements FieldChangeListener { + + boolean adjusting = false; + + @Override + public void actionPerformed(ActionEvent e) { + } + + @Override + public void setAdjusting(boolean b) { + this.adjusting = b; + } + + @Override + public boolean isAdjusting() { + return adjusting; + } + + @Override + public void fieldChanged() { + if (!isAdjusting()) { + if (surface.getType().isBox()) + surface.setGeometryDictionary(boxModel.getDictionary()); + else if (surface.getType().isSphere()) + surface.setGeometryDictionary(sphereModel.getDictionary()); + else if (surface.getType().isCylinder()) + surface.setGeometryDictionary(cylinderModel.getDictionary()); + else if (surface.getType().isRing()) + surface.setGeometryDictionary(ringModel.getDictionary()); + else + logger.error("Unknow surface type"); + + EventManager.triggerEvent(this, new ChangeSurfaceEvent(surface, false)); + } + } + }; + + private Dictionary getDefaultBoxModelDictionary() { + Dictionary dictionary = new Dictionary(BOX_TO_CELL_KEY); + dictionary.add(MIN_KEY, "(0.0 0.0 0.0)"); + dictionary.add(MAX_KEY, "(2.0 2.0 1.0)"); + return dictionary; + } + + private Dictionary getDefaultSphereModelDictionary() { + Dictionary dictionary = new Dictionary(SPHERE_TO_CELL_KEY); + dictionary.add(CENTRE_KEY, "(0.0 0.0 0.0 )"); + dictionary.add(RADIUS_KEY, "2.0"); + return dictionary; + } + + private Dictionary getDefaultCylinderModelDictionary() { + Dictionary dictionary = new Dictionary(CYLINDER_TO_CELL_KEY); + dictionary.add(POINT1_KEY, "(0.0 0.0 -1.5 )"); + dictionary.add(POINT2_KEY, "(0.0 0.0 1.5 )"); + dictionary.add(RADIUS_KEY, "2.0"); + return dictionary; + } + + private Dictionary getDefaultRingModelDictionary() { + Dictionary dictionary = new Dictionary(RING_TO_CELL_KEY); + dictionary.add(POINT1_KEY, "(0.0 0.0 0 )"); + dictionary.add(POINT2_KEY, "(0.05 0.0 0 )"); + dictionary.add(INNER_RADIUS_KEY, "0.2"); + dictionary.add(OUTER_RADIUS_KEY, "0.5"); + return dictionary; + } + + private String getLeftLabel() { + String label; + if (model.getState().getMultiphaseModel().isMultiphase()) { + if (fieldName.equals(Fields.ALPHA_1)) { + label = model.getMaterials().get(1).getName(); + } else if (fieldName.startsWith(Fields.ALPHA + ".")) { + label = "No " + Fields.PHASE_OS(fieldName); + } else if (fieldName.startsWith(Fields.ALPHA)) { + label = "No " + Fields.PHASE(fieldName); + } else { + label = "No " + fieldName; + } + } else { + label = "No " + fieldName; + } + return label; + } + + private String getRightLabel() { + String label; + if (model.getState().getMultiphaseModel().isMultiphase()) { + if (fieldName.equals(Fields.ALPHA_1)) { + label = model.getMaterials().get(0).getName(); + } else if (fieldName.startsWith(Fields.ALPHA)) { + label = Fields.PHASE(fieldName); + } else { + label = fieldName; + } + } else { + label = fieldName; + } + return label; + } + + private JLabel label(String name) { + return new JLabel(name); + } + + public void clear() { + if (showBoxButton.isSelected()) { + showBoxButton.doClick(); + } + } + +} diff --git a/src/eu/engys/gui/casesetup/fields/SetFieldsDictConverter.java b/src/eu/engys/gui/casesetup/fields/SetFieldsDictConverter.java new file mode 100644 index 0000000..306b6b1 --- /dev/null +++ b/src/eu/engys/gui/casesetup/fields/SetFieldsDictConverter.java @@ -0,0 +1,123 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.fields; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.core.dictionary.Dictionary.VALUE; +import static eu.engys.core.project.system.SetFieldsDict.CELL_SET_KEY; +import static eu.engys.core.project.system.SetFieldsDict.DEFAULT_FIELD_VALUES_KEY; +import static eu.engys.core.project.system.SetFieldsDict.DEFAULT_VALUE_KEY; +import static eu.engys.core.project.system.SetFieldsDict.FIELD_VALUES_KEY; +import static eu.engys.core.project.system.SetFieldsDict.REGIONS_KEY; +import static eu.engys.core.project.system.SetFieldsDict.SET_SOURCES_KEY; +import static eu.engys.core.project.system.SetFieldsDict.VOL_SCALAR_FIELD_VALUE_KEY; +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.system.SetFieldsDict; +import eu.engys.core.project.zero.fields.Field; + +public class SetFieldsDictConverter { + + private Field field; + + public SetFieldsDictConverter(Field field) { + this.field = field; + } + + public Dictionary convertForRead(SetFieldsDict dictToFix) { + Dictionary fixedDict = new Dictionary(dictToFix); + fixHeaderForRead(fixedDict); + fixRegionsForRead(fixedDict); + fixedDict.setName("initialisation"); + return fixedDict; + } + + public SetFieldsDict convertForWrite(Dictionary dictToFix) { + SetFieldsDict fixedDict = new SetFieldsDict(dictToFix); + fixHeaderForWrite(fixedDict); + fixRegionsForWrite(fixedDict); + fixedDict.setName(SetFieldsDict.SET_FIELDS_DICT); + return fixedDict; + } + + private void fixHeaderForRead(Dictionary dictionary) { + if (!dictionary.found(TYPE)) { + dictionary.add(TYPE, CELL_SET_KEY); + } + if (!dictionary.found(DEFAULT_VALUE_KEY) && dictionary.found(DEFAULT_FIELD_VALUES_KEY)) { + String fixedValue = dictionary.lookup(DEFAULT_FIELD_VALUES_KEY).replace("(", "").replace(")", "").replace(VOL_SCALAR_FIELD_VALUE_KEY, "").replace(field.getName(), "").trim(); + dictionary.add(DEFAULT_VALUE_KEY, "uniform " + fixedValue); + dictionary.remove(DEFAULT_FIELD_VALUES_KEY); + } + } + + private void fixRegionsForRead(Dictionary dictionary) { + if (!dictionary.found(SET_SOURCES_KEY) && dictionary.found(REGIONS_KEY)) { + for (DefaultElement element : dictionary.getList(REGIONS_KEY).getListElements()) { + if (element instanceof Dictionary) { + Dictionary dict = (Dictionary) element; + if (!dict.found(VALUE) && dict.found(FIELD_VALUES_KEY)) { + String fixedValue = dict.lookup(FIELD_VALUES_KEY).replace("(", "").replace(")", "").replace(VOL_SCALAR_FIELD_VALUE_KEY, "").replace(field.getName(), "").trim(); + dict.add(VALUE, fixedValue); + dict.remove(FIELD_VALUES_KEY); + } + dictionary.addToList(SET_SOURCES_KEY, dict); + } + } + dictionary.remove(REGIONS_KEY); + } + } + + private void fixHeaderForWrite(Dictionary dictionary) { + if (dictionary.found(TYPE)) { + dictionary.remove(TYPE); + } + if (dictionary.found(DEFAULT_VALUE_KEY)) { + String fixedValue = "( " + VOL_SCALAR_FIELD_VALUE_KEY + " " + field.getName() + " " + dictionary.lookup(DEFAULT_VALUE_KEY).replace("uniform", "").trim() + " )"; + dictionary.add(DEFAULT_FIELD_VALUES_KEY, fixedValue); + dictionary.remove(DEFAULT_VALUE_KEY); + } + } + + private void fixRegionsForWrite(Dictionary dictionary) { + if (dictionary.found(SET_SOURCES_KEY)) { + for (DefaultElement element : dictionary.getList(SET_SOURCES_KEY).getListElements()) { + if (element instanceof Dictionary) { + Dictionary dict = (Dictionary) element; + if (dict.found(VALUE)) { + String value = dict.lookup(VALUE); + dict.add(FIELD_VALUES_KEY, "( " + VOL_SCALAR_FIELD_VALUE_KEY + " " + field.getName() + " " + value + " )"); + dict.remove(VALUE); + } + dictionary.addToList(REGIONS_KEY, dict); + } + } + dictionary.remove(SET_SOURCES_KEY); + } + } + +} diff --git a/src/eu/engys/gui/casesetup/fields/StandardFieldsInitialisationPanel.java b/src/eu/engys/gui/casesetup/fields/StandardFieldsInitialisationPanel.java new file mode 100644 index 0000000..68f0bff --- /dev/null +++ b/src/eu/engys/gui/casesetup/fields/StandardFieldsInitialisationPanel.java @@ -0,0 +1,75 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.fields; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.core.project.zero.fields.Initialisations.CELL_SET_KEY; + +import javax.inject.Inject; + +import eu.engys.core.controller.Controller; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.SetFieldsDict; +import eu.engys.core.project.system.SystemFolder; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; + +public class StandardFieldsInitialisationPanel extends AbstractFieldsInitialisationPanel { + + @Inject + public StandardFieldsInitialisationPanel(Model model, Controller controller) { + super(model); + } + + @Override + public void save() { + for (Field f : fieldBuilderMap.keySet()) { + DictionaryPanelBuilder builder = fieldBuilderMap.get(f); + Dictionary dictionary = builder.getSelectedModel().getDictionary(); + + if (model.getState().getMultiphaseModel().isMultiphase() && f.getName().equals(Fields.ALPHA + "." + model.getMaterials().getFirstMaterialName())) { + if (dictionary.found(TYPE) && dictionary.lookup(TYPE).equals(CELL_SET_KEY)) { + writeSetFieldsDict(dictionary, f); + } else { + writeSetFieldsDict(new SetFieldsDict(), f); + } + } + f.setInitialisation(dictionary); + } + } + + private void writeSetFieldsDict(Dictionary dictionary, Field field) { + SetFieldsDict fixedSetFieldsDict = new SetFieldsDictConverter(field).convertForWrite(dictionary); + SystemFolder systemFolder = model.getProject().getSystemFolder(); + systemFolder.setSetFieldsDict(fixedSetFieldsDict); + DictionaryUtils.writeDictionary(systemFolder.getFileManager().getFile(), fixedSetFieldsDict, monitor); + } + +} diff --git a/src/eu/engys/gui/casesetup/fields/StandardInitialisations.java b/src/eu/engys/gui/casesetup/fields/StandardInitialisations.java new file mode 100644 index 0000000..fe37c98 --- /dev/null +++ b/src/eu/engys/gui/casesetup/fields/StandardInitialisations.java @@ -0,0 +1,162 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.fields; + +import static eu.engys.core.dictionary.Dictionary.TYPE; +import static eu.engys.core.dictionary.Dictionary.VALUE; + +import java.io.File; +import java.util.Set; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryBuilder; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.SetFieldsDict; +import eu.engys.core.project.zero.cellzones.CellZonesBuilder; +import eu.engys.core.project.zero.fields.AbstractInitialisations; +import eu.engys.core.project.zero.fields.ArrayInternalField; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.fields.ScalarInternalField; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.progress.SilentMonitor; + +public class StandardInitialisations extends AbstractInitialisations { + + private static final Logger logger = LoggerFactory.getLogger(StandardInitialisations.class); + private Set modules; + private CellZonesBuilder cellZonesBuilder; + + @Inject + public StandardInitialisations(Model model, CellZonesBuilder cellZonesBuilder, Set modules) { + super(model); + this.cellZonesBuilder = cellZonesBuilder; + this.modules = modules; + } + + @Override + public void loadInitialisation(File zeroDir, Field field, ProgressMonitor monitor) { + readFieldFromFile(field, zeroDir, monitor); + loadInitialisations(field); + } + + // Public for test purpouse only + public void loadInitialisations(Field field) { + if (map.containsKey(field.getName())) { + field.setInitialisation(map.get(field.getName())); + } else { + boolean isScalar = field.getInternalField() instanceof ScalarInternalField; + boolean isArray = field.getInternalField() instanceof ArrayInternalField; + if (isScalar) { + ScalarInternalField internalField = (ScalarInternalField) field.getInternalField(); + double value = internalField.getValue()[0][0]; + field.setInitialisation(DictionaryBuilder.newDictionary("initialisation").field(TYPE, "fixedValue").field(VALUE, String.valueOf(value)).done()); + } else if (isArray) { + ArrayInternalField internalField = (ArrayInternalField) field.getInternalField(); + double valueX = internalField.getValue()[0][0]; + double valueY = internalField.getValue()[0][1]; + double valueZ = internalField.getValue()[0][2]; + String value = "(" + valueX + " " + valueY + " " + valueZ + ")"; + field.setInitialisation(DictionaryBuilder.newDictionary("initialisation").field(TYPE, "fixedValue").field(VALUE, value).done()); + } else { + field.setInitialisation(DictionaryBuilder.newDictionary("initialisation").field(TYPE, "default").done()); + } + } + logger.info("{} initialised to {}", field.getName(), field.getInitialisationType()); + } + + @Override + public void readInitialisationFromFile(Field field) { + if (field.getName().startsWith(Fields.ALPHA)) { + SetFieldsDict setFieldsDict = model.getProject().getSystemFolder().getSetFieldsDict(); + if (setFieldsDict != null && !setFieldsDict.isEmpty()) { + readInitialisationFromSetFieldsDict(setFieldsDict, field); + map.put(field.getName(), field.getInitialisation()); + } + } + } + + private void readInitialisationFromSetFieldsDict(SetFieldsDict setFieldsDict, Field field) { + Dictionary convertedInitialisation = new SetFieldsDictConverter(field).convertForRead(setFieldsDict); + field.setInitialisation(convertedInitialisation); + } + + public void initializeFields() { + for (Field field : model.getFields().values()) { + initializeField(field); + } + model.getProject().getZeroFolder().write(model, cellZonesBuilder, modules, this, new SilentMonitor()); + } + + private void initializeField(Field field) { + String fieldName = field.getName(); + String initMethod = field.getInitialisationType(); + logger.info("Inititalising field: {} as {}", fieldName, initMethod); + + if (initMethod.equals("fixedValue")) { + initializeFixedValue(field); + } else if (initMethod.equals("default")) { + } else { + logger.warn("'{}': Invalid initialisation: set to 'default'", initMethod); + } + } + + private void initializeFixedValue(Field field) { + String value = field.getInitialisation().lookup("value"); + if (value != null && value.startsWith("uniform")) { + field.setInternalField("internalField " + value); + Fields[] parallelFields = model.getFields().getParallelFields(); + if (parallelFields != null) { + for (int i = 0; i < parallelFields.length; i++) { + Field subField = parallelFields[i].get(field.getName()); + subField.setInternalField("internalField " + value); + } + } + } + if (field.getName().equals(Fields.P) || field.getName().equals(Fields.P_RGH)) { + writeValueOnProcBoundary(field); + } + } + + private void writeValueOnProcBoundary(Field field) { + for (Patch patch : model.getPatches()) { + if (patch.getPhisicalType().isProcessor()) { + Dictionary momentum = patch.getBoundaryConditions().getMomentum(); + if (momentum.found(Fields.P)) { + Dictionary p = momentum.subDict(Fields.P); + p.add(Dictionary.VALUE, field.getInitialisation().lookup("value")); + } + } + } + } +} diff --git a/src/eu/engys/gui/casesetup/materials/AbstractIncompressibleMaterialsPanel.java b/src/eu/engys/gui/casesetup/materials/AbstractIncompressibleMaterialsPanel.java new file mode 100644 index 0000000..4d44303 --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/AbstractIncompressibleMaterialsPanel.java @@ -0,0 +1,159 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import static eu.engys.core.project.constant.TransportProperties.CP_KEY; +import static eu.engys.core.project.constant.TransportProperties.LAMBDA_KEY; +import static eu.engys.core.project.constant.TransportProperties.MATERIAL_NAME_KEY; +import static eu.engys.core.project.constant.TransportProperties.MU_KEY; +import static eu.engys.core.project.constant.TransportProperties.NU_KEY; +import static eu.engys.core.project.constant.TransportProperties.PRT_KEY; +import static eu.engys.core.project.constant.TransportProperties.P_REF_KEY; +import static eu.engys.core.project.constant.TransportProperties.RHO_KEY; +import static eu.engys.core.project.constant.TransportProperties.SIGMA_KEY; +import static eu.engys.core.project.constant.TransportProperties.T_REF_KEY; +import static eu.engys.util.Symbols.CP; +import static eu.engys.util.Symbols.DENSITY; +import static eu.engys.util.Symbols.DOT; +import static eu.engys.util.Symbols.MINUS_ONE; +import static eu.engys.util.Symbols.MU_MEASURE; +import static eu.engys.util.Symbols.NU_MEASURE; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DimensionedScalar; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.modules.materials.MaterialsBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.util.DimensionalUnits; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.StringField; + +public abstract class AbstractIncompressibleMaterialsPanel implements IncompressibleMaterialsPanel, PropertyChangeListener { + + public static final String REFERENCE_TEMPERATURE_K_LABEL = "Reference Temperature [K]"; + public static final String REFERENCE_ABSOLUTE_PRESSURE_PA_LABEL = "Reference (absolute) Pressure [Pa]"; + public static final String THERMAL_CONDUCTIVITY_LABEL = "Thermal Conductivity [W/m" + DOT + "K]"; + public static final String TURBULENT_PRANDTL_NUMBER_LABEL = "Turbulent Prandtl Number"; + public static final String SPECIFIC_HEAT_CAPACITY_LABEL = "Specific Heat Capacity " + CP; + public static final String KINEMATIC_VISCOSITY_LABEL = "Kinematic Viscosity " + NU_MEASURE; + public static final String DYNAMIC_VISCOSITY_LABEL = "Dynamic Viscosity " + MU_MEASURE; + public static final String DENSITY_LABEL = "Density " + DENSITY; + public static final String THERMAL_EXPANTION_COEFF_LABEL = "Thermal Expansion Coefficient [K" + MINUS_ONE + "]"; + + protected DictionaryModel incompressibleModel = new DictionaryModel("newMaterial", getEmptyMaterial()); + + private StringField nameField; + private DoubleField rho; + private DoubleField mu; + private DoubleField nu; + + protected PanelBuilder builder; + protected MaterialsBuilder materialsBuilder; + + public AbstractIncompressibleMaterialsPanel() { + this.builder = new PanelBuilder(); + } + + public abstract Dictionary getMaterial(Model model); + + public abstract void setMaterial(Dictionary material); + + @Override + public void setEnabled(boolean enabled) { + builder.setEnabled(enabled); + } + + @Override + public void stateChanged(State state) { + } + + @Override + public StringField getNameField() { + return nameField; + } + + protected void buildIncompressibleMaterialPanel() { + builder.addComponent("Name", nameField = incompressibleModel.bindLabel(MATERIAL_NAME_KEY)); + builder.addComponent(DENSITY_LABEL, rho = incompressibleModel.bindDimensionedDouble(RHO_KEY, DimensionalUnits.KG_M3, 0D, Double.MAX_VALUE)); + builder.addComponent(DYNAMIC_VISCOSITY_LABEL, mu = incompressibleModel.bindDimensionedDouble(MU_KEY, DimensionalUnits.KG_MS, 0D, Double.MAX_VALUE)); + builder.addComponent(KINEMATIC_VISCOSITY_LABEL, nu = incompressibleModel.bindDimensionedDouble(NU_KEY, DimensionalUnits.M2_S, 0D, Double.MAX_VALUE)); + + nameField.setEnabled(false); + + rho.addPropertyChangeListener("value", this); + mu.addPropertyChangeListener("value", this); + nu.addPropertyChangeListener("value", this); + + builder.addComponent(SPECIFIC_HEAT_CAPACITY_LABEL, incompressibleModel.bindDimensionedDouble(CP_KEY, DimensionalUnits.M2_S2K, 0D, Double.MAX_VALUE)); + builder.addComponent(TURBULENT_PRANDTL_NUMBER_LABEL, incompressibleModel.bindDimensionedDouble(PRT_KEY, DimensionalUnits.NONE, 0D, Double.MAX_VALUE)); + builder.addComponent(THERMAL_CONDUCTIVITY_LABEL, incompressibleModel.bindDimensionedDouble(LAMBDA_KEY, DimensionalUnits.KGM_S3K, 0D, Double.MAX_VALUE)); + builder.addComponent(REFERENCE_ABSOLUTE_PRESSURE_PA_LABEL, incompressibleModel.bindDimensionedDouble(P_REF_KEY, DimensionalUnits.KG_MS2, 0D, Double.MAX_VALUE)); + builder.addComponent(REFERENCE_TEMPERATURE_K_LABEL, incompressibleModel.bindDimensionedDouble(T_REF_KEY, DimensionalUnits.K, 0D, Double.MAX_VALUE)); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getSource() == nu) { + double rhoValue = rho.getDoubleValue(); + double nuValue = nu.getDoubleValue(); + + mu.setDoubleValue(nuValue * rhoValue); + } else if (evt.getSource() == rho || evt.getSource() == mu) { + double rhoValue = rho.getDoubleValue(); + double muValue = mu.getDoubleValue(); + + nu.setDoubleValue(rhoValue == 0.0 ? 0.0 : muValue / rhoValue); + } + } + + protected void adjustNuIfNeeded(Dictionary transportProps) { + if (transportProps != null && !transportProps.found(NU_KEY)) { + if (transportProps.found(RHO_KEY) && transportProps.found(MU_KEY)) { + double rho = Double.valueOf(transportProps.lookupScalar(RHO_KEY).doubleValue()); + double mu = Double.valueOf(transportProps.lookupScalar(MU_KEY).doubleValue()); + double nuValue = mu == 0.0 ? 0.0 : mu / rho; + transportProps.add(new DimensionedScalar(NU_KEY, Double.toString(nuValue), DimensionalUnits.M2_S)); + } + } + } + + @Override + public Dictionary saveSigma(Model model, Dictionary sigmaDict) { + Dictionary dict = new Dictionary(SIGMA_KEY); + if (model.getState().getMultiphaseModel().isMultiphase()) { + if (sigmaDict.found(SIGMA_KEY)) { + dict.add(sigmaDict.lookupScalar(SIGMA_KEY)); + } + } + return dict; + } + +} diff --git a/src/eu/engys/gui/casesetup/materials/AbstractMaterialsBuilder.java b/src/eu/engys/gui/casesetup/materials/AbstractMaterialsBuilder.java new file mode 100644 index 0000000..b6189e8 --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/AbstractMaterialsBuilder.java @@ -0,0 +1,113 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.materials; + +import static eu.engys.core.project.constant.ThermophysicalProperties.CP_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.LAMBDA_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MATERIAL_NAME_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MU_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.NU_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PRT_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PR_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.P_REF_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.RHO_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TRANSPORT_MODEL_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.T_REF_KEY; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DimensionedScalar; +import eu.engys.core.dictionary.DimensionedScalar.Dimensions; +import eu.engys.core.modules.materials.MaterialsBuilder; +import eu.engys.core.project.Model; + +public abstract class AbstractMaterialsBuilder implements MaterialsBuilder { + + @Override + public Dictionary saveIncompressible(Model model, Dictionary materialDict) { + String materialName = materialDict.lookup(MATERIAL_NAME_KEY); + + Dictionary transportProperties = new Dictionary(materialName); + transportProperties.add(MATERIAL_NAME_KEY, materialName); + + String transportModel = materialDict.lookup(TRANSPORT_MODEL_KEY); + transportProperties.add(TRANSPORT_MODEL_KEY, transportModel); + + if (materialDict.found(transportModel + "Coeffs")) { + transportProperties.add(materialDict.subDict(transportModel + "Coeffs")); + } + + if (materialDict.found(RHO_KEY)) { + transportProperties.add(materialDict.lookupScalar(RHO_KEY)); + } + + if (materialDict.found(MU_KEY)) { + transportProperties.add(materialDict.lookupScalar(MU_KEY)); + } + + if (materialDict.found(NU_KEY)) { + transportProperties.add(materialDict.lookupScalar(NU_KEY)); + } else if (materialDict.found(RHO_KEY) && materialDict.found(MU_KEY)) { + DimensionedScalar rho = materialDict.lookupScalar(RHO_KEY); + DimensionedScalar mu = materialDict.lookupScalar(MU_KEY); + + double nuValue = mu.doubleValue() / rho.doubleValue(); + Dimensions nuDimensions = mu.getDimensions().divide(rho.getDimensions()); + + DimensionedScalar nu = new DimensionedScalar(NU_KEY, Double.toString(nuValue), nuDimensions); + + transportProperties.add(nu); + } + + if (materialDict.found(CP_KEY)) { + transportProperties.add(materialDict.lookupScalar(CP_KEY)); + } + if (materialDict.found(PRT_KEY)) { + transportProperties.add(materialDict.lookupScalar(PRT_KEY)); + } + if (materialDict.found(PR_KEY)) { + transportProperties.add(materialDict.lookupScalar(PR_KEY)); + } + if (materialDict.found(LAMBDA_KEY)) { + transportProperties.add(materialDict.lookupScalar(LAMBDA_KEY)); + } + + if (materialDict.found(P_REF_KEY)) { + transportProperties.add(materialDict.lookupScalar(P_REF_KEY)); + } + if (materialDict.found(getBetaKey())) { + transportProperties.add(materialDict.lookupScalar(getBetaKey())); + } + if (materialDict.found(T_REF_KEY)) { + transportProperties.add(materialDict.lookupScalar(T_REF_KEY)); + } + + // System.out.println("MaterialsBuilder.saveIncompressible() "+transportProperties); + + return transportProperties; + } + + protected abstract String getBetaKey(); +} diff --git a/src/eu/engys/gui/casesetup/materials/AbstractMaterialsReader.java b/src/eu/engys/gui/casesetup/materials/AbstractMaterialsReader.java new file mode 100644 index 0000000..5177e63 --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/AbstractMaterialsReader.java @@ -0,0 +1,66 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import static eu.engys.core.project.constant.TransportProperties.MATERIAL_NAME_KEY; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.constant.ThermophysicalProperties; +import eu.engys.core.project.constant.TransportProperties; +import eu.engys.core.project.materials.Material; +import eu.engys.core.project.materials.Materials; +import eu.engys.core.project.materials.MaterialsReader; +import eu.engys.util.progress.ProgressMonitor; + +public abstract class AbstractMaterialsReader implements MaterialsReader { + + @Override + public void readSingle_Material(Materials materials, TransportProperties tpp, ProgressMonitor monitor) { + readMaterial(materials, tpp, monitor); + } + + @Override + public void readSingle_Material(Materials materials, ThermophysicalProperties tfp, ProgressMonitor monitor) { + readMaterial(materials, tfp, monitor); + } + + private void readMaterial(Materials materials, Dictionary tfp, ProgressMonitor monitor) { + Dictionary dict = new Dictionary(tfp); + dict.setFoamFile(null); + if (dict.isEmpty()) { + monitor.warning("No material found", 1); + return; + } else { + if (!dict.found(MATERIAL_NAME_KEY)) { + dict.add(MATERIAL_NAME_KEY, "material"); + } + String name = dict.lookup(MATERIAL_NAME_KEY); + dict.setName(name); + materials.add(new Material(name, dict)); + monitor.info(name, 1); + } + } + +} diff --git a/src/eu/engys/gui/casesetup/materials/AbstractMaterialsWriter.java b/src/eu/engys/gui/casesetup/materials/AbstractMaterialsWriter.java new file mode 100644 index 0000000..e816c10 --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/AbstractMaterialsWriter.java @@ -0,0 +1,58 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.constant.ThermophysicalProperties; +import eu.engys.core.project.constant.TransportProperties; +import eu.engys.core.project.materials.Materials; +import eu.engys.core.project.materials.MaterialsWriter; + +public abstract class AbstractMaterialsWriter implements MaterialsWriter { + + private static final Logger logger = LoggerFactory.getLogger(AbstractMaterialsWriter.class); + + @Override + public void writeSingle_IncompressibleMaterial(Materials materials, TransportProperties tpp) { + if (materials.size() == 1) { + tpp.merge(materials.get(0).getDictionary()); + } else { + logger.warn("Multiphase solution choosen but '{}' materials found", materials.size()); + } + } + + @Override + public void writeSingle_CompressibleMaterial(Materials materials, ThermophysicalProperties tfp) { + if (materials.size() == 1) { + tfp.merge(materials.get(0).getDictionary()); + } else { + logger.warn("Multiphase solution choosen but '{}' materials found", materials.size()); + } + } + +} diff --git a/src/eu/engys/gui/casesetup/materials/CompressibleMaterialsPanel.java b/src/eu/engys/gui/casesetup/materials/CompressibleMaterialsPanel.java new file mode 100644 index 0000000..479fd2e --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/CompressibleMaterialsPanel.java @@ -0,0 +1,144 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import static eu.engys.core.project.constant.ThermophysicalProperties.CONSTANT_CP_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.CONST_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.CP_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.ENERGY_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.EQUATION_OF_STATE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HE_PSI_THERMO_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HF_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MIXTURE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MOL_WEIGHT_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MU_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.N_MOLES_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PERFECT_GAS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PR_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PURE_MIXTURE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SENSIBLE_ENTHALPY_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SPECIE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMODYNAMICS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMO_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMO_TYPE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TRANSPORT_KEY; +import static eu.engys.core.project.constant.TransportProperties.MATERIAL_NAME_KEY; +import static eu.engys.util.Symbols.CP; +import static eu.engys.util.Symbols.HF; +import static eu.engys.util.Symbols.MU_MEASURE; + +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.util.ui.textfields.StringField; + +public interface CompressibleMaterialsPanel { + + static final String MOLECULAR_WEIGHT_KG_KMOL_LABEL = "Molecular Weight [kg/kmol]"; + static final String NUMBER_OF_MOLES_LABEL = "Number Of Moles"; + static final String NAME_LABEL = "Name"; + static final String EQUATION_OF_STATE_LABEL = "Equation Of State"; + static final String PERFECT_GAS_LABEL = "Perfect Gas"; + static final String SUTHERLAND_TEMPERATURE_TS_LABEL = "Sutherland Temperature (Ts)"; + static final String SUTHERLAND_COEFFICIENT_AS_LABEL = "Sutherland Coefficient (As)"; + static final String PRANDTL_NUMBER_LABEL = "Prandtl Number"; + static final String DYNAMIC_VISCOSITY_LABEL = "Dynamic Viscosity " + MU_MEASURE; + static final String SUTHERLAND_S_LABEL = "Sutherland's"; + static final String CONSTANT_LABEL = "Constant"; + static final String TRANSPORT_PROPERTIES_LABEL = "Transport Properties"; + static final String THERMODYNAMIC_MODEL_LABEL = "Thermodynamic Model"; + static final String LOW_CP_LABEL = "Low Cp"; + static final String HIGH_CP_LABEL = "High Cp"; + static final String HEAT_OF_FUSION_LABEL = "Heat Of Fusion " + HF; + static final String HEAT_CAPACITY_LABEL = "Heat Capacity " + CP; + static final String JANAF_LABEL = "JANAF"; + static final String CONSTANT_CP_LABEL = "Constant Cp"; + + public static Dictionary defaultDictionary = new Dictionary("newMaterial"){ + { + add(MATERIAL_NAME_KEY, "newMaterial"); + add(new Dictionary(THERMO_TYPE_KEY){ + { + add(TYPE, HE_PSI_THERMO_KEY); + add(MIXTURE_KEY, PURE_MIXTURE_KEY); + add(TRANSPORT_KEY, CONST_KEY); + add(THERMO_KEY, CONSTANT_CP_KEY); + add(EQUATION_OF_STATE_KEY, PERFECT_GAS_KEY); + add(SPECIE_KEY, SPECIE_KEY); + add(ENERGY_KEY, SENSIBLE_ENTHALPY_KEY); + } + }); + add(new Dictionary(MIXTURE_KEY){ + { + add(new Dictionary(EQUATION_OF_STATE_KEY)); + add(new Dictionary(TRANSPORT_KEY){ + { + add(MU_KEY, "0.0"); + add(PR_KEY, "0.0"); + } + }); + add(new Dictionary(THERMODYNAMICS_KEY){ + { + add(CP_KEY, "0.0"); + add(HF_KEY, "0.0"); + } + }); + add(new Dictionary(SPECIE_KEY){ + { + add(N_MOLES_KEY, "0"); + add(MOL_WEIGHT_KEY, "0.0"); + } + }); + } + }); + } + }; + + Dictionary getEmptyMaterial(); + + Dictionary getMaterial(Model model); + + void setMaterial(Dictionary material); + + JPanel getPanel(); + + void setEnabled(boolean enabled); + + void buildThermodynamicModelPanel(); + + void buildTransportPropertiesPanel(); + + void buildEquationOfStatePanel(); + + void buildThermophysicalModelPanel(); + + void stateChanged(State state); + + StringField getNameField(); + +} diff --git a/src/eu/engys/gui/casesetup/materials/IncompressibleMaterialsPanel.java b/src/eu/engys/gui/casesetup/materials/IncompressibleMaterialsPanel.java new file mode 100644 index 0000000..eec96ea --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/IncompressibleMaterialsPanel.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.util.ui.textfields.StringField; + +public interface IncompressibleMaterialsPanel { + + Dictionary getEmptyMaterial(); + + Dictionary getMaterial(Model model); + + void setMaterial(Dictionary material); + + JPanel getPanel(); + + void setEnabled(boolean enabled); + + void stateChanged(State state); + + Dictionary saveSigma(Model model, Dictionary sigmaDict); + + StringField getNameField(); + + +} diff --git a/src/eu/engys/gui/casesetup/materials/MaterialsTreeNodeManager.java b/src/eu/engys/gui/casesetup/materials/MaterialsTreeNodeManager.java new file mode 100644 index 0000000..a4c65a6 --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/MaterialsTreeNodeManager.java @@ -0,0 +1,212 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import java.awt.Component; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; + +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreePath; + +import eu.engys.core.project.Model; +import eu.engys.core.project.materials.Material; +import eu.engys.core.project.materials.Materials; +import eu.engys.gui.casesetup.materials.panels.MaterialsPanel; +import eu.engys.gui.tree.AbstractSelectionHandler; +import eu.engys.gui.tree.DefaultTreeNodeManager; +import eu.engys.gui.tree.SelectionHandler; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.TreeUtil; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class MaterialsTreeNodeManager extends DefaultTreeNodeManager { + + private Map materialsMap; + private SelectionHandler selectionHandler; + + public MaterialsTreeNodeManager(Model model, MaterialsPanel materialsPanel) { + super(model, materialsPanel); + this.selectionHandler = new MaterialsSelectionHandler(materialsPanel); + this.materialsMap = new HashMap<>(); + } + + @Override + public void update(Observable o, final Object arg) { + if (arg instanceof Materials) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + loadTree(); + expandTree(); + } + }); + } + } + + private void loadTree() { + clear(); + for (Material material : model.getMaterials()) { + addMaterial(material); + } + treeChanged(root); + } + + private void expandTree() { + if (getTree() != null) { + getTree().expandNode(getRoot()); + } + } + + private void addMaterial(Material material) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(material); + root.add(node); + nodeMap.put(material, node); + materialsMap.put(node, material); + } + + public Material[] getSelectedValues() { + if (getTree() != null) { + TreePath[] selectionPaths = getTree().getSelectionPaths(); + if (selectionPaths != null) { + Material[] materials = new Material[selectionPaths.length]; + for (int i = 0; i < selectionPaths.length; i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPaths[i].getLastPathComponent(); + Material material = materialsMap.get(node); + materials[i] = material; + } + return materials; + } + return new Material[0]; + } + return new Material[0]; + } + + public void setSelectedValue(Material material) { + if (getTree() != null) { + DefaultMutableTreeNode selectedNode = nodeMap.get(material); + if (selectedNode != null) { + getTree().setSelectedNode(selectedNode); + } else { + getTree().setSelectedNode(getRoot()); + } + } + } + + public void clear() { + // clear node before selection handler! + clearNode(root); + selectionHandler.clear(); + nodeMap.clear(); + materialsMap.clear(); + } + + public DefaultMutableTreeNode getRoot() { + return root; + } + + @Override + public Class getRendererClass() { + return Material.class; + } + + @Override + public DefaultTreeCellRenderer getRenderer() { + return new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObject = node.getUserObject(); + + if (userObject instanceof Material) { + Material material = (Material) userObject; + if (model.getMaterials().size() > 1) { + String phase = "[phase" + (model.getMaterials().indexOf(material) + 1) + "]"; + setText("" + material.getName() + " " + "" + phase + ""); + } else { + setText(material.getName()); + } + } + setIcon(null); + return this; + } + }; + } + + @Override + public SelectionHandler getSelectionHandler() { + return selectionHandler; + } + + private final class MaterialsSelectionHandler extends AbstractSelectionHandler { + + private MaterialsPanel panel; + private Material[] currentSelection; + + public MaterialsSelectionHandler(MaterialsPanel panel) { + this.panel = panel; + } + + @Override + public void handleSelection(boolean fire3DEvent, Object... selection) { + if (currentSelection != null && currentSelection.length > 0) { + panel.saveMaterials(currentSelection); + } + if (TreeUtil.isConsistent(selection, Material.class)) { + this.currentSelection = Arrays.copyOf(selection, selection.length, Material[].class); + } else { + this.currentSelection = new Material[0]; + } + panel.updateSelection(currentSelection); + panel.updateButtons(currentSelection.length > 0); + } + + @Override + public void handleVisibility(VisibleItem item) { + } + + @Override + public void process3DSelectionEvent(Picker picker, Actor actor, boolean keep) { + } + + @Override + public void process3DVisibilityEvent(boolean selected) { + } + + @Override + public void clear() { + currentSelection = null; + } + } + +} diff --git a/src/eu/engys/gui/casesetup/materials/StandardCompressibleMaterialsPanel.java b/src/eu/engys/gui/casesetup/materials/StandardCompressibleMaterialsPanel.java new file mode 100644 index 0000000..95ca98d --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/StandardCompressibleMaterialsPanel.java @@ -0,0 +1,196 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.materials; + +import static eu.engys.core.project.constant.ThermophysicalProperties.AS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.A_KEYS; +import static eu.engys.core.project.constant.ThermophysicalProperties.CONSTANT_CP_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.CONST_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.CP_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.EQUATION_OF_STATE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HF_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HIGH_CP_COEFFS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.JANAF_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.LOW_CP_COEFFS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MATERIAL_NAME_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MOL_WEIGHT_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MU_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.N_MOLES_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PERFECT_GAS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PR_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SUTHERLAND_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TCOMMON_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMO_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THIGH_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TLOW_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TRANSPORT_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TS_KEY; +import static eu.engys.util.ui.ComponentsFactory.labelArrayField; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.inject.Inject; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.modules.materials.MaterialsBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.util.ui.builder.JComboBoxController; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.StringField; + +public class StandardCompressibleMaterialsPanel implements CompressibleMaterialsPanel { + + private DictionaryModel compressibleModel = new DictionaryModel(new Dictionary("")); + + private JComboBoxController transport; + private JComboBoxController thermo; + private MaterialsBuilder materialsBuilder; + + private PanelBuilder builder; + private StringField nameField; + + @Inject + public StandardCompressibleMaterialsPanel() { + this.builder = new PanelBuilder(); + this.materialsBuilder = new StandardMaterialsBuilder(); + buildCompressibleMaterialPanel(); + } + + @Override + public Dictionary getEmptyMaterial() { + return new Dictionary(defaultDictionary); + } + + @Override + public StringField getNameField() { + return nameField; + } + + @Override + public JPanel getPanel() { + return builder.getPanel(); + } + + @Override + public void setEnabled(boolean enabled) { + builder.setEnabled(enabled); + } + + @Override + public void stateChanged(State state) { + } + + private void buildCompressibleMaterialPanel() { + buildThermophysicalModelPanel(); + buildTransportPropertiesPanel(); + buildThermodynamicModelPanel(); + buildEquationOfStatePanel(); + + /* JANAF works only for SUTHERLAND */ + transport.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (transport.getSelectedIndex() == 0) { + thermo.addDisabledItem(JANAF_LABEL); + thermo.setSelectedItem(CONSTANT_CP_LABEL); + } else { + thermo.clearDisabledIndexes(); + } + } + }); + transport.setSelectedItem(CONSTANT_LABEL); + } + + @Override + public void buildThermophysicalModelPanel() { + builder.addComponent(NAME_LABEL, nameField = compressibleModel.bindLabel(MATERIAL_NAME_KEY)); + builder.addComponent(NUMBER_OF_MOLES_LABEL, compressibleModel.bindIntegerPositive(N_MOLES_KEY)); + builder.addComponent(MOLECULAR_WEIGHT_KG_KMOL_LABEL, compressibleModel.bindDoublePositive(MOL_WEIGHT_KEY)); + nameField.setEnabled(false); + } + + @Override + public void buildTransportPropertiesPanel() { + transport = (JComboBoxController) builder.startChoice(TRANSPORT_PROPERTIES_LABEL, compressibleModel.bindComboBoxController(TRANSPORT_KEY)); + + builder.startGroup(CONST_KEY, CONSTANT_LABEL); + builder.addComponent(DYNAMIC_VISCOSITY_LABEL, compressibleModel.bindDoublePositive(MU_KEY)); + builder.addComponent(PRANDTL_NUMBER_LABEL, compressibleModel.bindDoublePositive(PR_KEY)); + builder.endGroup(); + + builder.startGroup(SUTHERLAND_KEY, SUTHERLAND_S_LABEL); + builder.addComponent(SUTHERLAND_COEFFICIENT_AS_LABEL, compressibleModel.bindDoublePositive(AS_KEY)); + builder.addComponent(SUTHERLAND_TEMPERATURE_TS_LABEL, compressibleModel.bindDoublePositive(TS_KEY)); + builder.endGroup(); + + builder.endChoice(); + } + + @Override + public void buildThermodynamicModelPanel() { + thermo = (JComboBoxController) builder.startChoice(THERMODYNAMIC_MODEL_LABEL, compressibleModel.bindComboBoxController(THERMO_KEY)); + + builder.startGroup(CONSTANT_CP_KEY, CONSTANT_CP_LABEL); + builder.addComponent(HEAT_CAPACITY_LABEL, compressibleModel.bindDoublePositive(CP_KEY)); + builder.addComponent(HEAT_OF_FUSION_LABEL, compressibleModel.bindDoublePositive(HF_KEY)); + builder.endGroup(); + + builder.startGroup(JANAF_KEY, JANAF_LABEL); + builder.addComponent(TLOW_KEY, compressibleModel.bindDoublePositive(TLOW_KEY)); + builder.addComponent(THIGH_KEY, compressibleModel.bindDoublePositive(THIGH_KEY)); + builder.addComponent(TCOMMON_KEY, compressibleModel.bindDoublePositive(TCOMMON_KEY)); + builder.addComponent(labelArrayField(A_KEYS)); + builder.addComponent(HIGH_CP_LABEL, compressibleModel.bindArray(HIGH_CP_COEFFS_KEY, 7)); + builder.addComponent(labelArrayField(A_KEYS)); + builder.addComponent(LOW_CP_LABEL, compressibleModel.bindArray(LOW_CP_COEFFS_KEY, 7)); + builder.endGroup(); + + builder.endChoice(); + } + + @Override + public void buildEquationOfStatePanel() { + String[] EOS_KEYS = { PERFECT_GAS_KEY };// , "ICOPolynomial" }; + String[] EOS_LABELS = { PERFECT_GAS_LABEL };// , "Polymomial f(T)" }; + builder.addComponent(EQUATION_OF_STATE_LABEL, compressibleModel.bindChoice(EQUATION_OF_STATE_KEY, EOS_KEYS, EOS_LABELS)).setEnabled(false); + } + + @Override + public Dictionary getMaterial(Model model) { + return materialsBuilder.saveCompressible(model, compressibleModel.getDictionary()); + } + + @Override + public void setMaterial(Dictionary material) { + compressibleModel.setDictionary(materialsBuilder.toGUIFormat(material)); + } + +} diff --git a/src/eu/engys/gui/casesetup/materials/StandardIncompressibleMaterialsPanel.java b/src/eu/engys/gui/casesetup/materials/StandardIncompressibleMaterialsPanel.java new file mode 100644 index 0000000..b0b467f --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/StandardIncompressibleMaterialsPanel.java @@ -0,0 +1,110 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import static eu.engys.core.project.constant.TransportProperties.BETA_OS_KEY; +import static eu.engys.core.project.constant.TransportProperties.CP_KEY; +import static eu.engys.core.project.constant.TransportProperties.LAMBDA_KEY; +import static eu.engys.core.project.constant.TransportProperties.MATERIAL_NAME_KEY; +import static eu.engys.core.project.constant.TransportProperties.MU_KEY; +import static eu.engys.core.project.constant.TransportProperties.NEWTONIAN_COEFFS_KEY; +import static eu.engys.core.project.constant.TransportProperties.NEWTONIAN_KEY; +import static eu.engys.core.project.constant.TransportProperties.NU_KEY; +import static eu.engys.core.project.constant.TransportProperties.PRT_KEY; +import static eu.engys.core.project.constant.TransportProperties.PR_KEY; +import static eu.engys.core.project.constant.TransportProperties.P_REF_KEY; +import static eu.engys.core.project.constant.TransportProperties.RHO_KEY; +import static eu.engys.core.project.constant.TransportProperties.TRANSPORT_MODEL_KEY; +import static eu.engys.core.project.constant.TransportProperties.T_REF_KEY; + +import javax.swing.JPanel; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DimensionedScalar; +import eu.engys.core.project.Model; +import eu.engys.util.DimensionalUnits; + +public class StandardIncompressibleMaterialsPanel extends AbstractIncompressibleMaterialsPanel { + + public static final String LAMINAR_PRANDTL_NUMBER_LABEL = "Laminar Prandtl Number"; + + @Inject + public StandardIncompressibleMaterialsPanel() { + super(); + this.materialsBuilder = new StandardMaterialsBuilder(); + buildIncompressibleMaterialPanel(); + } + + @Override + public Dictionary getMaterial(Model model) { + return materialsBuilder.saveIncompressible(model, incompressibleModel.getDictionary()); + } + + @Override + public void setMaterial(Dictionary material) { + adjustNuIfNeeded(material); + incompressibleModel.setDictionary(new Dictionary(material.getName(), material)); + } + + @Override + protected void buildIncompressibleMaterialPanel() { + super.buildIncompressibleMaterialPanel(); + builder.addComponent(THERMAL_EXPANTION_COEFF_LABEL, incompressibleModel.bindDimensionedDouble(BETA_OS_KEY, DimensionalUnits._K, 0D, Double.MAX_VALUE)); + builder.addComponent(LAMINAR_PRANDTL_NUMBER_LABEL, incompressibleModel.bindDimensionedDouble(PR_KEY, DimensionalUnits.NONE, 0D, Double.MAX_VALUE)); + } + + @Override + public JPanel getPanel() { + return builder.removeMargins().getPanel(); + } + + @Override + public Dictionary getEmptyMaterial() { + return new Dictionary(defaultDictionary); + } + + public static Dictionary defaultDictionary = new Dictionary("newMaterial") { + { + add(MATERIAL_NAME_KEY, "newMaterial"); + add(TRANSPORT_MODEL_KEY, NEWTONIAN_KEY); + add(new Dictionary(NEWTONIAN_COEFFS_KEY)); + add(new DimensionedScalar(RHO_KEY, "0.0", DimensionalUnits.KG_M3)); + add(new DimensionedScalar(RHO_KEY, "0.0", DimensionalUnits.KG_M3)); + add(new DimensionedScalar(MU_KEY, "0.0", DimensionalUnits.KG_MS)); + add(new DimensionedScalar(NU_KEY, "0.0", DimensionalUnits.M2_S)); + add(new DimensionedScalar(CP_KEY, "0.0", DimensionalUnits.M2_S2K)); + add(new DimensionedScalar(PRT_KEY, "0.0", DimensionalUnits.NONE)); + add(new DimensionedScalar(LAMBDA_KEY, "0.0", DimensionalUnits.KGM_S3K)); + add(new DimensionedScalar(P_REF_KEY, "0.0", DimensionalUnits.KG_MS2)); + add(new DimensionedScalar(T_REF_KEY, "0.0", DimensionalUnits.K)); + add(new DimensionedScalar(BETA_OS_KEY, "0.0", DimensionalUnits._K)); + add(new DimensionedScalar(PR_KEY, "0.0", DimensionalUnits.NONE)); + } + }; + +} diff --git a/src/eu/engys/gui/casesetup/materials/StandardMaterialsBuilder.java b/src/eu/engys/gui/casesetup/materials/StandardMaterialsBuilder.java new file mode 100644 index 0000000..ed57f5c --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/StandardMaterialsBuilder.java @@ -0,0 +1,222 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import static eu.engys.core.project.constant.ThermophysicalProperties.AS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.BETA_OS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.CONSTANT_CP_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.CONST_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.DEFAULT_MATERIAL_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.ENERGY_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.EQUATION_OF_STATE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HE_PSI_THERMO_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HE_RHO_THERMO_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HF_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.HIGH_CP_COEFFS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.JANAF_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.LOW_CP_COEFFS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MATERIAL_NAME_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MIXTURE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MOL_WEIGHT_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.MU_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.N_MOLES_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PR_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.PURE_MIXTURE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SENSIBLE_ENTHALPY_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SENSIBLE_INTERNAL_ENERGY_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SPECIE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.SUTHERLAND_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TCOMMON_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMODYNAMICS_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMO_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMO_MODEL_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THERMO_TYPE_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.THIGH_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TLOW_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TRANSPORT_KEY; +import static eu.engys.core.project.constant.ThermophysicalProperties.TS_KEY; +import static eu.engys.core.project.constant.TransportProperties.CP0_KEY; +import static eu.engys.core.project.constant.TransportProperties.CP_KEY; +import static eu.engys.core.project.constant.TransportProperties.RHO_CP0_KEY; +import static eu.engys.core.project.constant.TransportProperties.RHO_KEY; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; + +public class StandardMaterialsBuilder extends AbstractMaterialsBuilder { + + @Override + protected String getBetaKey() { + return BETA_OS_KEY; + } + + @Override + public Dictionary saveIncompressible(Model model, Dictionary materialDict) { + Dictionary transportProperties = super.saveIncompressible(model, materialDict); + if (materialDict.found(CP_KEY)) { + transportProperties.add(CP0_KEY, materialDict.lookupScalar(CP_KEY).getValue()); + } + if (materialDict.found(RHO_KEY)) { + transportProperties.add(RHO_CP0_KEY, materialDict.lookupScalar(RHO_KEY).getValue()); + } + return transportProperties; + } + + @Override + public Dictionary saveCompressible(Model model, Dictionary materialGUIDict) { + String type = model != null ? (model.getState().isBuoyant() ? HE_RHO_THERMO_KEY : HE_PSI_THERMO_KEY) : materialGUIDict.lookup(THERMO_MODEL_KEY); + String energy = model != null && model.getState().isHighMach() && model.getState().getSolverFamily().isPimple() ? SENSIBLE_INTERNAL_ENERGY_KEY : SENSIBLE_ENTHALPY_KEY; + String thermo = materialGUIDict.found(THERMO_KEY) ? materialGUIDict.lookup(THERMO_KEY) : ""; + String transport = materialGUIDict.found(TRANSPORT_KEY) ? materialGUIDict.lookup(TRANSPORT_KEY) : ""; + + Dictionary thermoDict = new Dictionary(THERMO_TYPE_KEY); + thermoDict.add(Dictionary.TYPE, type); + thermoDict.add(MIXTURE_KEY, PURE_MIXTURE_KEY); + thermoDict.add(TRANSPORT_KEY, transport.equals(CONST_KEY) ? CONST_KEY : SUTHERLAND_KEY); + thermoDict.add(THERMO_KEY, materialGUIDict.lookup(THERMO_KEY)); + thermoDict.add(EQUATION_OF_STATE_KEY, materialGUIDict.lookup(EQUATION_OF_STATE_KEY)); + thermoDict.add(SPECIE_KEY, SPECIE_KEY); + thermoDict.add(ENERGY_KEY, energy); + + /* SPECIES */ + Dictionary specieDict = new Dictionary(SPECIE_KEY); + specieDict.add(N_MOLES_KEY, materialGUIDict.lookup(N_MOLES_KEY)); + specieDict.add(MOL_WEIGHT_KEY, materialGUIDict.lookup(MOL_WEIGHT_KEY)); + + /* THERMODYNAMICS */ + Dictionary thermodynamicsDict = new Dictionary(THERMODYNAMICS_KEY); + if (thermo.equals(CONSTANT_CP_KEY)) { + thermodynamicsDict.add(CP_KEY, materialGUIDict.lookup(CP_KEY)); + thermodynamicsDict.add(HF_KEY, materialGUIDict.lookup(HF_KEY)); + } else if (thermo.equals(JANAF_KEY)) { + thermodynamicsDict.add(TLOW_KEY, materialGUIDict.lookup(TLOW_KEY)); + thermodynamicsDict.add(THIGH_KEY, materialGUIDict.lookup(THIGH_KEY)); + thermodynamicsDict.add(TCOMMON_KEY, materialGUIDict.lookup(TCOMMON_KEY)); + thermodynamicsDict.add(HIGH_CP_COEFFS_KEY, materialGUIDict.lookup(HIGH_CP_COEFFS_KEY)); + thermodynamicsDict.add(LOW_CP_COEFFS_KEY, materialGUIDict.lookup(LOW_CP_COEFFS_KEY)); + } + + /* TRANSPORT */ + Dictionary transportDict = new Dictionary(TRANSPORT_KEY); + if (transport.equals(CONST_KEY)) { + transportDict.add(MU_KEY, materialGUIDict.lookup(MU_KEY)); + transportDict.add(PR_KEY, materialGUIDict.lookup(PR_KEY)); + } else if (transport.equals(SUTHERLAND_KEY)) { + transportDict.add(AS_KEY, materialGUIDict.lookup(AS_KEY)); + transportDict.add(TS_KEY, materialGUIDict.lookup(TS_KEY)); + } + + Dictionary mixtureDict = new Dictionary(MIXTURE_KEY); + mixtureDict.add(specieDict); + mixtureDict.add(thermodynamicsDict); + mixtureDict.add(transportDict); + + String materialName = materialGUIDict.lookup(MATERIAL_NAME_KEY); + Dictionary thermophysicalProperties = new Dictionary(materialName); + thermophysicalProperties.add(MATERIAL_NAME_KEY, materialName); + thermophysicalProperties.add(thermoDict); + thermophysicalProperties.add(mixtureDict); + + // System.out.println("MaterialsBuilder.saveCompressible() "+thermophysicalProperties); + return thermophysicalProperties; + } + + @Override + public Dictionary loadCompressible(Model model) { + Dictionary thermophysicalProperties = model.getProject().getConstantFolder().getThermophysicalProperties(); + // System.out.println("MaterialsBuilder.decodeCompressible()"+thermophysicalProperties); + + Dictionary d = new Dictionary(""); + if (thermophysicalProperties.found(THERMO_TYPE_KEY)) { + Dictionary thermoType = thermophysicalProperties.subDict(THERMO_TYPE_KEY); + + d.add(THERMO_MODEL_KEY, thermoType.lookup(Dictionary.TYPE)); + d.add(TRANSPORT_KEY, thermoType.lookup(TRANSPORT_KEY)); + d.add(THERMO_KEY, thermoType.lookup(THERMO_KEY)); + d.add(EQUATION_OF_STATE_KEY, thermoType.lookup(EQUATION_OF_STATE_KEY)); + + if (thermophysicalProperties.found(MATERIAL_NAME_KEY)) + d.add(MATERIAL_NAME_KEY, thermophysicalProperties.lookup(MATERIAL_NAME_KEY)); + else + d.add(MATERIAL_NAME_KEY, DEFAULT_MATERIAL_KEY); + + if (thermophysicalProperties.found(MIXTURE_KEY)) { + Dictionary mixture = thermophysicalProperties.subDict(MIXTURE_KEY); + + /* SPECIES */ + Dictionary speciesDict = mixture.subDict(SPECIE_KEY); + d.merge(speciesDict); + + /* THERMODYNAMICS */ + Dictionary thermodynamicsDict = mixture.subDict(THERMODYNAMICS_KEY); + d.merge(thermodynamicsDict); + + /* TRANSPORT */ + Dictionary transportDict = mixture.subDict(TRANSPORT_KEY); + d.merge(transportDict); + } + } + + return d; + } + + @Override + public Dictionary toGUIFormat(Dictionary thermophysicalProperties) { + // System.out.println("MaterialsBuilder.decodeCompressible()"+thermophysicalProperties); + Dictionary d = new Dictionary(""); + + if (thermophysicalProperties.found(THERMO_TYPE_KEY)) { + Dictionary thermoType = thermophysicalProperties.subDict(THERMO_TYPE_KEY); + + d.add(THERMO_MODEL_KEY, thermoType.lookup(Dictionary.TYPE)); + d.add(TRANSPORT_KEY, thermoType.lookup(TRANSPORT_KEY)); + d.add(THERMO_KEY, thermoType.lookup(THERMO_KEY)); + d.add(EQUATION_OF_STATE_KEY, thermoType.lookup(EQUATION_OF_STATE_KEY)); + + } + if (thermophysicalProperties.found(MATERIAL_NAME_KEY)) + d.add(MATERIAL_NAME_KEY, thermophysicalProperties.lookup(MATERIAL_NAME_KEY)); + else + d.add(MATERIAL_NAME_KEY, thermophysicalProperties.getName()); + + if (thermophysicalProperties.found(MIXTURE_KEY)) { + Dictionary mixture = thermophysicalProperties.subDict(MIXTURE_KEY); + + /* SPECIES */ + if (mixture.found(SPECIE_KEY)) + d.merge(mixture.subDict(SPECIE_KEY)); + + /* THERMODYNAMICS */ + if (mixture.found(THERMODYNAMICS_KEY)) + d.merge(mixture.subDict(THERMODYNAMICS_KEY)); + + /* TRANSPORT */ + if (mixture.found(TRANSPORT_KEY)) + d.merge(mixture.subDict(TRANSPORT_KEY)); + } + + return d; + } +} diff --git a/src/eu/engys/gui/casesetup/materials/StandardMaterialsReader.java b/src/eu/engys/gui/casesetup/materials/StandardMaterialsReader.java new file mode 100644 index 0000000..693dc0c --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/StandardMaterialsReader.java @@ -0,0 +1,87 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StandardMaterialsReader extends AbstractMaterialsReader { + + private static final Logger logger = LoggerFactory.getLogger(StandardMaterialsReader.class); + + @Inject + public StandardMaterialsReader() { + } + +// @Override +// public void readMultiphase_IncompressibleMaterials(Materials materials, Dictionary transportProperties) { +// if (transportProperties.found("phases")) { +// String[] phases = transportProperties.lookupArray("phases"); +// if (phases.length == 2) { +// +// Dictionary dict1 = new Dictionary(transportProperties.subDict(phases[0])); +// if (!dict1.isEmpty()) { +// if (!dict1.found("materialName")) { +// dict1.add("materialName", "material1"); +// } +// String name1 = dict1.lookup("materialName"); +// dict1.setName(name1); +// materials.add(new Material(name1, dict1)); +// } +// +// Dictionary dict2 = new Dictionary(transportProperties.subDict(phases[1])); +// if (!dict2.isEmpty()) { +// if (!dict2.found("materialName")) { +// dict2.add("materialName", "material2"); +// } +// String name2 = dict2.lookup("materialName"); +// dict2.setName(name2); +// materials.add(new Material(name2, dict2)); +// } +// +// if (transportProperties.found("sigma")) { +// String sigmaValue = transportProperties.lookup("sigma"); +// materials.get(0).getDictionary().add("sigma", sigmaValue); +// materials.get(1).getDictionary().add("sigma", sigmaValue); +// } else if (dict1.found("sigma")) { +// String sigmaValue = dict1.lookup("sigma"); +// materials.get(1).getDictionary().add("sigma", sigmaValue); +// } else if (dict2.found("sigma")) { +// String sigmaValue = dict2.lookup("sigma"); +// materials.get(0).getDictionary().add("sigma", sigmaValue); +// } +// } else { +// logger.warn("Multiphase case but wrong phases number found in transportProperties: " + phases.length); +// } +// +// } else { +// logger.warn("Multiphase case but no phases found in transportProperties"); +// } +// } + +} diff --git a/src/eu/engys/gui/casesetup/materials/StandardMaterialsWriter.java b/src/eu/engys/gui/casesetup/materials/StandardMaterialsWriter.java new file mode 100644 index 0000000..673d1c2 --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/StandardMaterialsWriter.java @@ -0,0 +1,69 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.materials; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StandardMaterialsWriter extends AbstractMaterialsWriter { + + private static final Logger logger = LoggerFactory.getLogger(AbstractMaterialsWriter.class); + +// @Override +// public void writeMultiphase_IncompressibleMaterials(Materials materials, Dictionary tpp) { +// if (materials.size() == 2) { +// Material mat1 = materials.get(0); +// Material mat2 = materials.get(1); +// +// String mat1Name = mat1.getName(); +// String mat2Name = mat2.getName(); +// +// tpp.add(PHASES_KEY, "(" + mat1Name + " " + mat2Name + ")"); +// +// Dictionary dict1 = new Dictionary(mat1.getDictionary()); +// dict1.remove(SIGMA_KEY); +// dict1.setName(mat1Name); +// tpp.add(dict1); +// +// Dictionary dict2 = new Dictionary(mat2.getDictionary()); +// dict2.remove(SIGMA_KEY); +// dict2.setName(mat2Name); +// tpp.add(dict2); +// +// String sigmaValue = "0.0"; +// if (mat1.getDictionary().found(SIGMA_KEY)) { +// sigmaValue = mat1.getDictionary().lookup(SIGMA_KEY); +// } else if (mat2.getDictionary().found(SIGMA_KEY)) { +// sigmaValue = mat2.getDictionary().lookup(SIGMA_KEY); +// } +// tpp.add(new DimensionedScalar(SIGMA_KEY, sigmaValue, "[1 0 -2 0 0 0 0 ]")); +// +// } else { +// logger.warn("Multiphase solution choosen but '{}' materials found", materials.size()); +// } +// } + +} diff --git a/src/eu/engys/gui/casesetup/materials/panels/MaterialParametersPanel.java b/src/eu/engys/gui/casesetup/materials/panels/MaterialParametersPanel.java new file mode 100644 index 0000000..dce648b --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/panels/MaterialParametersPanel.java @@ -0,0 +1,131 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.materials.panels; + +import java.awt.CardLayout; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.gui.casesetup.materials.CompressibleMaterialsPanel; +import eu.engys.gui.casesetup.materials.IncompressibleMaterialsPanel; +import eu.engys.util.ui.textfields.StringField; + +public class MaterialParametersPanel extends JPanel { + + private static final String INCOMPRESSIBLE = "Incompressible"; + private static final String COMPRESSIBLE = "Compressible"; + private static final String NONE = "None"; + + private CompressibleMaterialsPanel compressiblePanel; + private IncompressibleMaterialsPanel incompressiblePanel; + + private String selected = NONE; + + public MaterialParametersPanel(CompressibleMaterialsPanel compressiblePanel, IncompressibleMaterialsPanel incompressiblePanel) { + super(new CardLayout()); + setName("Material Parameters"); + + this.compressiblePanel = compressiblePanel; + this.incompressiblePanel = incompressiblePanel; + + JPanel compPanel = compressiblePanel.getPanel(); + JPanel incompPanel = incompressiblePanel.getPanel(); + + compPanel.setName("Compressible Panel"); + incompPanel.setName("Incompressible Panel"); + incompPanel.setBorder(BorderFactory.createTitledBorder("Material Parameters")); + + add(compPanel, COMPRESSIBLE); + add(incompPanel, INCOMPRESSIBLE); + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + compressiblePanel.setEnabled(enabled); + incompressiblePanel.setEnabled(enabled); + } + + public void load(Model model) { + if (model.getState().isCompressible()) { + selected = COMPRESSIBLE; + ((CardLayout) getLayout()).show(this, COMPRESSIBLE); + } else if (model.getState().isIncompressible()) { + selected = INCOMPRESSIBLE; + ((CardLayout) getLayout()).show(this, INCOMPRESSIBLE); + } + } + + public void show(State state) { + if (state.isCompressible()) { + selected = COMPRESSIBLE; + compressiblePanel.stateChanged(state); + ((CardLayout) getLayout()).show(this, COMPRESSIBLE); + } else if (state.isIncompressible()) { + selected = INCOMPRESSIBLE; + incompressiblePanel.stateChanged(state); + ((CardLayout) getLayout()).show(this, INCOMPRESSIBLE); + } + } + + public Dictionary getEmptyMaterial(Model model) { + if (model.getState().isCompressible()) { + return compressiblePanel.getEmptyMaterial(); + } else { + return incompressiblePanel.getEmptyMaterial(); + } + } + + public Dictionary getMaterial(Model model) { + if (model.getState().isCompressible()) { + return compressiblePanel.getMaterial(model); + } else { + return incompressiblePanel.getMaterial(model); + } + } + + public StringField getNameField(Model model) { + if (model.getState().isCompressible()) { + return compressiblePanel.getNameField(); + } else { + return incompressiblePanel.getNameField(); + } + } + + public void setMaterial(Dictionary material) { + if (selected.equals(COMPRESSIBLE)) { + compressiblePanel.setMaterial(material); + } else { + incompressiblePanel.setMaterial(material); + } + } + +} diff --git a/src/eu/engys/gui/casesetup/materials/panels/MaterialsDatabasePanel.java b/src/eu/engys/gui/casesetup/materials/panels/MaterialsDatabasePanel.java new file mode 100644 index 0000000..063ab1d --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/panels/MaterialsDatabasePanel.java @@ -0,0 +1,444 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.materials.panels; + +import static eu.engys.core.project.constant.ThermophysicalProperties.MATERIAL_NAME_KEY; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.project.Model; +import eu.engys.gui.casesetup.materials.CompressibleMaterialsPanel; +import eu.engys.gui.casesetup.materials.IncompressibleMaterialsPanel; +import eu.engys.util.PrefUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class MaterialsDatabasePanel extends JPanel { + + public static final String NEW_LABEL = "New"; + public static final String COPY_LABEL = "Copy"; + public static final String REMOVE_LABEL = "Remove"; + + public static final String NEW_TOOLTIP = "Create New Material"; + public static final String COPY_TOOLTIP = "Copy Currently Selected Material"; + public static final String REMOVE_TOOLTIP = "Remove Currently Selected Material"; + + public static final String COPY_OF_SUFFIX = "_copy"; + + private final Action newMaterial = new NewMaterialAction(); + private final Action copyMaterial = new CopyMaterialAction(); + private final Action removeMaterial = new RemoveMaterialAction(); + + private MaterialParametersPanel parametersPanel; + + private DefaultMaterialsListListener materialListener; + private UserMaterialsListListener userListener; + + private DefaultListModel materialsListModel; + private DefaultListModel userListModel; + + private JList defaultMaterialsList; + private JList userMaterialsList; + + private Model model; + private Map userMaterials = new HashMap(); + + @Inject + public MaterialsDatabasePanel(final Model model, CompressibleMaterialsPanel compressiblePanel, IncompressibleMaterialsPanel incompressiblePanel) { + super(new BorderLayout()); + this.model = model; + + materialListener = new DefaultMaterialsListListener(); + userListener = new UserMaterialsListListener(); + + materialsListModel = new DefaultListModel(); + userListModel = new DefaultListModel(); + + defaultMaterialsList = new JList(materialsListModel); + defaultMaterialsList.setName("materials.library.list"); + defaultMaterialsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + userMaterialsList = new JList(userListModel); + userMaterialsList.setName("user.library.list"); + userMaterialsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + defaultMaterialsList.addListSelectionListener(materialListener); + userMaterialsList.addListSelectionListener(userListener); + + parametersPanel = new MaterialParametersPanel(compressiblePanel, incompressiblePanel); + parametersPanel.setEnabled(false); + + JSplitPane leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + leftSplitPane.setOneTouchExpandable(false); + leftSplitPane.setTopComponent(configureList(defaultMaterialsList, "Default Library")); + leftSplitPane.setBottomComponent(configureList(userMaterialsList, "User Library")); + + JComponent buttonsPanel = UiUtil.getCommandColumn(getButtons()); + buttonsPanel.setBorder(BorderFactory.createEmptyBorder(UiUtil.TWO_SPACES, UiUtil.TWO_SPACES, 0, UiUtil.TWO_SPACES)); + + JSplitPane mainSplitPane = new JSplitPane(); + mainSplitPane.setDividerLocation(150); + mainSplitPane.setOneTouchExpandable(false); + mainSplitPane.setLeftComponent(leftSplitPane); + JScrollPane comp = new JScrollPane(parametersPanel); + comp.setBorder(BorderFactory.createEmptyBorder()); + mainSplitPane.setRightComponent(comp); + + add(mainSplitPane, BorderLayout.CENTER); + add(buttonsPanel, BorderLayout.EAST); + } + + private List getButtons() { + List buttons = new ArrayList<>(); + JButton newMaterialButton = new JButton(newMaterial); + JButton copyMaterialButton = new JButton(copyMaterial); + JButton removeMaterialButton = new JButton(removeMaterial); + + newMaterialButton.setName(NEW_LABEL); + copyMaterialButton.setName(COPY_LABEL); + removeMaterialButton.setName(REMOVE_LABEL); + + copyMaterial.setEnabled(false); + removeMaterial.setEnabled(false); + + buttons.add(newMaterialButton); + buttons.add(copyMaterialButton); + buttons.add(removeMaterialButton); + return buttons; + } + + private JComponent configureList(JList list, String label) { + JScrollPane scrollPane = new JScrollPane(list); + scrollPane.setBorder(BorderFactory.createTitledBorder(label)); + list.setOpaque(false); + list.setBackground(getBackground().darker().brighter()); + list.setSelectionBackground(getBackground().darker()); + list.setSelectionForeground(Color.WHITE); + list.setCellRenderer(new DefaultListCellRenderer()); + return scrollPane; + } + + public void load() { + updateDefaultMaterialsList(); + + loadUserMaterials(); + updateUserMaterialsList(); + + parametersPanel.show(model.getState()); + } + + private void loadUserMaterials() { + userMaterials.clear(); + + String userMaterialsProperties = PrefUtil.getString(PrefUtil.MATERIALS_USER_LIB + model.getState().getFlow(), null); + if (userMaterialsProperties != null) { + Dictionary userDictionary = DictionaryUtils.readDictionary(userMaterialsProperties); + + if (userDictionary.found("materials")) { + for (Dictionary matDict : userDictionary.subDict("materials").getDictionaries()) { + try { + if (model.getState().isCompressible()) { + if (matDict.found("thermoType")) { + userMaterials.put(matDict.getName(), matDict); + } + } else { + userMaterials.put(matDict.getName(), matDict); + } + + } catch (Exception e) { + System.out.println("INVALID MATERIAL DICTIONARY: " + matDict.getName()); + } + } + } + } + } + + public void saveUserMaterials() { + saveCurrentSelectedUserDefinedMaterial(); + Dictionary userMaterialsProperties = new Dictionary("materials"); + for (Dictionary mat : userMaterials.values()) { + userMaterialsProperties.add(mat); + } + PrefUtil.putString(PrefUtil.MATERIALS_USER_LIB + model.getState().getFlow(), userMaterialsProperties.toString()); + } + + public Dictionary getMaterial() { + return parametersPanel.getMaterial(model); + } + + private void updateUserMaterialsList() { + userMaterialsList.removeListSelectionListener(userListener); + int selection = userMaterialsList.getSelectedIndex(); + userListModel.clear(); + for (String mat : userMaterials.keySet()) { + userListModel.addElement(mat); + } + userMaterialsList.setSelectedIndex(selection); + userMaterialsList.addListSelectionListener(userListener); + } + + private void updateDefaultMaterialsList() { + defaultMaterialsList.removeListSelectionListener(materialListener); + materialsListModel.clear(); + Collection materials = null; + if (model.getState().isCompressible()) { + materials = model.getMaterialsDatabase().getCompressibleMaterials(); + } else { + materials = model.getMaterialsDatabase().getIncompressibleMaterials(); + } + for (Dictionary mat : materials) { + materialsListModel.addElement(mat.lookup(MATERIAL_NAME_KEY)); + } + defaultMaterialsList.addListSelectionListener(materialListener); + } + + private final class DefaultMaterialsListListener implements ListSelectionListener { + @Override + public void valueChanged(ListSelectionEvent e) { + if (!e.getValueIsAdjusting() && e.getSource() == defaultMaterialsList) { + String key = (String) defaultMaterialsList.getSelectedValue(); + if (key == null) + return; + + clearSelectionOnUserMaterialsList(); + + saveCurrentSelectedUserDefinedMaterial(); + + if (model.getState().isCompressible()) { + setMaterialToParametersPanel(new Dictionary(model.getMaterialsDatabase().getCompressibleMaterialsMap().get(key))); + } else { + setMaterialToParametersPanel(new Dictionary(model.getMaterialsDatabase().getIncompressibleMaterialsMap().get(key))); + } + + parametersPanel.getNameField(model).setEnabled(false); + + copyMaterial.setEnabled(true); + removeMaterial.setEnabled(false); + parametersPanel.setEnabled(false); + } + } + } + + private final class UserMaterialsListListener implements ListSelectionListener { + @Override + public void valueChanged(ListSelectionEvent e) { + if (!e.getValueIsAdjusting() && e.getSource() == userMaterialsList) { + String key = (String) userMaterialsList.getSelectedValue(); + if (key == null) + return; + + clearSelectionOnDefaultMaterialsList(); + + saveCurrentSelectedUserDefinedMaterial(); + + Dictionary dict = new Dictionary(userMaterials.get(key)); + setMaterialToParametersPanel(dict); + + parametersPanel.getNameField(model).setEnabled(true); + + copyMaterial.setEnabled(true); + removeMaterial.setEnabled(true); + parametersPanel.setEnabled(true); + } + } + } + + private void saveCurrentSelectedUserDefinedMaterial() { + Dictionary currentMaterial = parametersPanel.getMaterial(model); + if (userMaterials.keySet().contains(currentMaterial.getName())) { + // If name is changed + String oldMaterialName = currentMaterial.getName(); + String newMaterialName = currentMaterial.lookup(MATERIAL_NAME_KEY); + + userMaterials.remove(oldMaterialName); + Dictionary newMaterialDict = new Dictionary(newMaterialName, currentMaterial); + userMaterials.put(newMaterialName, newMaterialDict); + + updateUserMaterialsList(); + } + + } + + private void setMaterialToParametersPanel(Dictionary material) { + parametersPanel.getNameField(model).removePropertyChangeListener(nameChangeListener); + parametersPanel.setMaterial(material); + parametersPanel.getNameField(model).addPropertyChangeListener(nameChangeListener); + } + + /* + * Actions + */ + + private final class NewMaterialAction extends ViewAction { + public NewMaterialAction() { + super(NEW_LABEL, NEW_TOOLTIP); + } + + @Override + public void actionPerformed(ActionEvent e) { + clearSelectionOnAllLists(); + + Dictionary emptyDict = parametersPanel.getEmptyMaterial(model); + + String validMaterialName = getValidMaterialName(emptyDict.getName()); + Dictionary newMaterialDict = new Dictionary(validMaterialName, emptyDict); + newMaterialDict.add(MATERIAL_NAME_KEY, validMaterialName); + + userMaterials.put(validMaterialName, newMaterialDict); + updateUserMaterialsList(); + userMaterialsList.setSelectedValue(validMaterialName, true); + } + } + + private final class CopyMaterialAction extends ViewAction { + + public CopyMaterialAction() { + super(COPY_LABEL, COPY_TOOLTIP); + } + + @Override + public void actionPerformed(ActionEvent e) { + clearSelectionOnAllLists(); + + Dictionary currentlySelectedMaterial = parametersPanel.getMaterial(model); + + String validMaterialName = getValidMaterialName(currentlySelectedMaterial.getName()); + Dictionary copyMaterial = new Dictionary(validMaterialName, currentlySelectedMaterial); + copyMaterial.add(MATERIAL_NAME_KEY, validMaterialName); + + userMaterials.put(validMaterialName, copyMaterial); + updateUserMaterialsList(); + userMaterialsList.setSelectedValue(validMaterialName, true); + } + + } + + private final class RemoveMaterialAction extends ViewAction { + public RemoveMaterialAction() { + super(REMOVE_LABEL, REMOVE_TOOLTIP); + } + + @Override + public void actionPerformed(ActionEvent e) { + String key = (String) userMaterialsList.getSelectedValue(); + if (key == null) + return; + userMaterials.remove(key); + updateUserMaterialsList(); + defaultMaterialsList.setSelectedIndex(0); + } + } + + private void clearSelectionOnAllLists() { + clearSelectionOnDefaultMaterialsList(); + clearSelectionOnUserMaterialsList(); + } + + private void clearSelectionOnDefaultMaterialsList() { + defaultMaterialsList.removeListSelectionListener(userListener); + defaultMaterialsList.clearSelection(); + defaultMaterialsList.addListSelectionListener(userListener); + } + + private void clearSelectionOnUserMaterialsList() { + userMaterialsList.removeListSelectionListener(userListener); + userMaterialsList.clearSelection(); + userMaterialsList.addListSelectionListener(userListener); + } + + private String getValidMaterialName(String materialname) { + Map materials = null; + + if (model.getState().isCompressible()) { + materials = model.getMaterialsDatabase().getCompressibleMaterialsMap(); + } else { + materials = model.getMaterialsDatabase().getIncompressibleMaterialsMap(); + } + + String uniqueMaterialName = materialname; + while (materials.containsKey(uniqueMaterialName)) { + uniqueMaterialName = uniqueMaterialName + COPY_OF_SUFFIX; + } + while (userMaterials.containsKey(uniqueMaterialName)) { + uniqueMaterialName = uniqueMaterialName + COPY_OF_SUFFIX; + } + return uniqueMaterialName; + } + + /* + * Listeners + */ + + PropertyChangeListener nameChangeListener = new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + String oldname = (String) evt.getOldValue(); + if (oldname != null) { + String newName = (String) evt.getNewValue(); + + Dictionary currentMaterial = parametersPanel.getMaterial(model); + + userMaterials.remove(oldname); + Dictionary newMaterialDict = new Dictionary(newName, currentMaterial); + userMaterials.put(newName, newMaterialDict); + + updateUserMaterialsList(); + userMaterialsList.setSelectedValue(newName, true); + } + } + } + }; +} diff --git a/src/eu/engys/gui/casesetup/materials/panels/MaterialsPanel.java b/src/eu/engys/gui/casesetup/materials/panels/MaterialsPanel.java new file mode 100644 index 0000000..3d91ea4 --- /dev/null +++ b/src/eu/engys/gui/casesetup/materials/panels/MaterialsPanel.java @@ -0,0 +1,359 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.materials.panels; + +import static eu.engys.core.project.constant.TransportProperties.MATERIAL_NAME_KEY; +import static eu.engys.gui.casesetup.materials.panels.MaterialsDatabasePanel.COPY_OF_SUFFIX; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.project.Model; +import eu.engys.core.project.materials.Material; +import eu.engys.core.project.materials.Materials; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.StateBuilder; +import eu.engys.gui.AbstractGUIPanel; +import eu.engys.gui.casesetup.materials.CompressibleMaterialsPanel; +import eu.engys.gui.casesetup.materials.IncompressibleMaterialsPanel; +import eu.engys.gui.casesetup.materials.MaterialsTreeNodeManager; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; + +public class MaterialsPanel extends AbstractGUIPanel { + + public static final String MATERIALS = "Materials"; + private static final String MATERIAL_CHANGED_WARNING = "A material has been changed.\nAll fields default settings are going to be reset now.\nContinue?"; + + private JDialog dialog; + + private MaterialParametersPanel parametersPanel; + + private MaterialsTreeNodeManager treeNodeManager; + private Material materialToChange; + + private CardLayout centerPanelLayout; + private JPanel centerPanel; + + private JButton changeMaterialButton; + + private PanelBuilder parametersBuilder; + + private Set modules; + + private CompressibleMaterialsPanel compressiblePanel; + private IncompressibleMaterialsPanel incompressiblePanel; + + private MaterialsDatabasePanel materialsDatabasePanel; + + @Inject + public MaterialsPanel(Model model, MaterialsDatabasePanel materialsDatabasePanel, CompressibleMaterialsPanel compressiblePanel, IncompressibleMaterialsPanel incompressiblePanel, Set modules) { + super(MATERIALS, model); + this.materialsDatabasePanel = materialsDatabasePanel; + this.compressiblePanel = compressiblePanel; + this.incompressiblePanel = incompressiblePanel; + this.modules = modules; + this.treeNodeManager = new MaterialsTreeNodeManager(model, this); + model.addObserver(treeNodeManager); + } + + protected JComponent layoutComponents() { + centerPanelLayout = new CardLayout(); + centerPanel = new JPanel(centerPanelLayout); + centerPanel.add(new JLabel(), "none"); + + parametersPanel = new MaterialParametersPanel(compressiblePanel, incompressiblePanel); + + parametersBuilder = new PanelBuilder(); + parametersBuilder.addComponent(parametersPanel); + + ModulesUtil.configureMaterialsView(modules, parametersBuilder); + + centerPanel.add(parametersBuilder.removeMargins().getPanel(), "material"); + + PanelBuilder mainbuilder = new PanelBuilder(); + mainbuilder.addComponent(createButtonsPanel()); + mainbuilder.addComponent(centerPanel); + + return mainbuilder.removeMargins().getPanel(); + } + + private JComponent createButtonsPanel() { + List actionsList = new ArrayList(); + changeMaterialButton = new JButton(new ChangeMaterialAction()); + changeMaterialButton.setName("Change Material"); + changeMaterialButton.setEnabled(false); + actionsList.add(changeMaterialButton); + + JComponent buttonsPanel = UiUtil.getCommandRow(actionsList); + buttonsPanel.setBorder(BorderFactory.createEmptyBorder()); + return buttonsPanel; + } + + private void buildDialog() { + JButton okButton = new JButton(new OkDialogAction()); + okButton.setName("OK"); + + JButton cancelButton = new JButton(new CancelDialogAction()); + cancelButton.setName("Cancel"); + + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonsPanel.add(okButton); + buttonsPanel.add(cancelButton); + + dialog = new JDialog(UiUtil.getActiveWindow(), "Materials Database", JDialog.DEFAULT_MODALITY_TYPE); + dialog.setName("materials.database.dialog"); + dialog.setSize(700, 500); + dialog.setLocationRelativeTo(null); + dialog.getContentPane().setLayout(new BorderLayout()); + dialog.getContentPane().add(materialsDatabasePanel, BorderLayout.CENTER); + dialog.getContentPane().add(buttonsPanel, BorderLayout.SOUTH); + dialog.getRootPane().setDefaultButton(okButton); + } + + @Override + public void load() { + materialsDatabasePanel.load(); + parametersPanel.load(model); + } + + @Override + public void save() { + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) treeNodeManager.getSelectedValues()); + } + + @Override + public void clear() { + super.clear(); + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) new Material[0]); + } + + @Override + public void stateChanged() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + State state = model.getState(); + + parametersPanel.show(state); + materialsDatabasePanel.load(); + + Materials materials = model.getMaterials(); + if (!materials.isEmpty()) { + for (Material material : materials) { + for (ApplicationModule module : modules) { + if (module.getMaterialsView() != null) { + module.getMaterialsView().updateDefaultMaterial(material); + } + } + updateSelection(material); + saveMaterials(material); + } + } + + } + }); + } + + public void updateSelection(Material... ms) { + if (ms.length == 1) { + Material material = ms[0]; + centerPanelLayout.show(centerPanel, "material"); + parametersPanel.setMaterial(material.getDictionary()); + for (ApplicationModule module : modules) { + if (module.getMaterialsView() != null) + module.getMaterialsView().updateGUIFromModel(material); + } + } else { + centerPanelLayout.show(centerPanel, "none"); + } + + } + + public void saveMaterials(Material... selection) { + if (selection != null && selection.length == 1) { + Material material = selection[0]; + Dictionary d = new Dictionary(parametersPanel.getMaterial(model)); + material.setDictionary(d); + + for (ApplicationModule module : modules) { + if (module.getMaterialsView() != null) { + module.getMaterialsView().updateModelFromGUI(material); + } + } + } + } + + public void updateButtons(boolean enable) { + changeMaterialButton.setEnabled(enable); + } + + private final class ChangeMaterialAction extends AbstractAction { + + public ChangeMaterialAction() { + super("Change Material"); + } + + @Override + public void actionPerformed(ActionEvent e) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (dialog == null) { + buildDialog(); + } + materialToChange = treeNodeManager.getSelectedValues()[0]; + dialog.setVisible(true); + } + }); + } + } + + private final class OkDialogAction extends AbstractAction { + + public OkDialogAction() { + super("OK"); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (model.getState().getMultiphaseModel().isMultiphase()) { + int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), MATERIAL_CHANGED_WARNING, "Material Changed", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); + if (retVal != JOptionPane.OK_OPTION) { + return; + } + + } + materialsDatabasePanel.saveUserMaterials(); + dialog.setVisible(false); + parametersPanel.getNameField(model).setEnabled(false); + changeMaterial(); + } + + private void changeMaterial() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + Material newMaterial = getNewMaterial(); + if (model.getState().getMultiphaseModel().isMultiphase()) { + StateBuilder.changeMaterial(model, modules); + } else { + model.materialsChanged(); + } + treeNodeManager.setSelectedValue(newMaterial); + save(); + } + }); + } + + private Material getNewMaterial() { + int index = -1; + if (materialToChange != null) { + index = model.getMaterials().indexOf(materialToChange); + model.getMaterials().remove(materialToChange); + materialToChange = null; + } + + Dictionary dictionary = materialsDatabasePanel.getMaterial(); + + Material material = null; + + if (modelAlreadyContainsMaterial(dictionary.getName())) { + Dictionary newDict = new Dictionary(dictionary); + String newName = dictionary.getName() + COPY_OF_SUFFIX; + newDict.setName(newName); + newDict.add(MATERIAL_NAME_KEY, newName); + material = new Material(newName, newDict); + dictionary = newDict; + } else { + material = new Material(dictionary.getName(), dictionary); + } + + if (index != -1) { + model.getMaterials().add(index, material); + } else { + model.getMaterials().add(material); + } + parametersPanel.setMaterial(dictionary); + return material; + } + + private boolean modelAlreadyContainsMaterial(String name) { + for (Material mat : model.getMaterials()) { + if (mat.getName().equals(name)) { + return true; + } + } + return false; + } + } + + private final class CancelDialogAction extends AbstractAction implements Runnable { + + public CancelDialogAction() { + super("Cancel"); + } + + @Override + public void actionPerformed(ActionEvent e) { + SwingUtilities.invokeLater(this); + } + + @Override + public void run() { + dialog.setVisible(false); + } + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } + +} diff --git a/src/eu/engys/gui/casesetup/phases/PhasesPanel.java b/src/eu/engys/gui/casesetup/phases/PhasesPanel.java new file mode 100644 index 0000000..cb4da28 --- /dev/null +++ b/src/eu/engys/gui/casesetup/phases/PhasesPanel.java @@ -0,0 +1,93 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.phases; + +import javax.swing.JComponent; + +import eu.engys.core.project.Model; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.builder.PanelBuilder; + +public class PhasesPanel extends DefaultGUIPanel { + + public static final String PHASES = "Phases"; + + private PhasesView phasesView; + + public PhasesPanel(Model model, PhasesView phasesView) { + super(PHASES, model); + this.phasesView = phasesView; + } + + @Override + public String getKey() { + return PHASES + "_" + phasesView.getClass().getCanonicalName(); + } + + @Override + public void load() { + phasesView.load(model); + } + + @Override + public void save() { + phasesView.save(model); + } + + @Override + public void stateChanged() { + rebuildPanel(); + } + + @Override + public void materialsChanged() { + rebuildPanel(); + } + + private void rebuildPanel() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + removeAll(); + layoutPanel(); + load(); + } + }); + } + + @Override + protected JComponent layoutComponents() { + PanelBuilder builder = new PanelBuilder(); + phasesView.layoutComponents(builder); + return builder.removeMargins().getPanel(); + } + + @Override + public int getIndex() { + return 2; + } +} diff --git a/src/eu/engys/gui/casesetup/phases/PhasesView.java b/src/eu/engys/gui/casesetup/phases/PhasesView.java new file mode 100644 index 0000000..7d87080 --- /dev/null +++ b/src/eu/engys/gui/casesetup/phases/PhasesView.java @@ -0,0 +1,39 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.phases; + +import eu.engys.core.project.Model; +import eu.engys.util.ui.builder.PanelBuilder; + +public interface PhasesView { + + void layoutComponents(PanelBuilder parametersBuilder); + + void load(Model model); + + void save(Model model); + +} diff --git a/src/eu/engys/gui/casesetup/run/StandardTable15.java b/src/eu/engys/gui/casesetup/run/StandardTable15.java new file mode 100644 index 0000000..c56a3b8 --- /dev/null +++ b/src/eu/engys/gui/casesetup/run/StandardTable15.java @@ -0,0 +1,123 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.run; + +import java.util.Set; + +import javax.inject.Inject; + +import eu.engys.core.project.state.Solver; +import eu.engys.core.project.state.SolverFamily; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.Table15; + +public class StandardTable15 implements Table15 { + + @Inject + public StandardTable15() { + } + + @Override + public void updateSolverFamilies(State state, Set families) { + if (state.getSolverType().isSegregated()) { + if (state.isLowMach()) { + if (state.isSteady()) { + families.add(SolverFamily.SIMPLE); + } else if (state.isTransient()) { + if (state.isCompressible()) { + families.add(SolverFamily.PIMPLE); + } else if (state.isIncompressible()) { + if (state.isEnergy() || state.getMultiphaseModel().isMultiphase()) { + families.add(SolverFamily.PIMPLE); + } else { + families.add(SolverFamily.PIMPLE); + families.add(SolverFamily.PISO); + } + } else { + // NONE + } + } else { + // NONE + } + } else if (state.isHighMach()) { + families.add(SolverFamily.PIMPLE); + } else { + // NONE + } + } else { + // NONE + } + } + + @Override + public void updateSolver(State state) { + if (state.getSolverType().isSegregated()) { + String solverName = ""; + + if (state.getMultiphaseModel().isMultiphase()) { + /* in modules */ + } else if (state.getSolverFamily().isSimple()) { + if (state.isCompressible()) { + if (state.isBuoyant()) { + solverName = BUOYANT_SIMPLE_FOAM; + } else { + solverName = RHO_SIMPLE_FOAM; + } + } else if (state.isIncompressible()) { + if (state.isEnergy()) { + solverName = BUOYANT_BOUSSINESQ_SIMPLE_FOAM; + } else { + solverName = SIMPLE_FOAM; + } + } + } else if (state.getSolverFamily().isPiso()) { + if (state.isIncompressible()) { + solverName = PISO_FOAM; + } + } else if (state.getSolverFamily().isPimple()) { + if (state.isCompressible()) { + if (state.isBuoyant()) { + solverName = BUOYANT_PIMPLE_FOAM; + } else { + if (state.isHighMach()) { + solverName = SONIC_FOAM; + } else { + solverName = RHO_PIMPLE_FOAM; + } + } + } else if (state.isIncompressible()) { + if (state.isEnergy()) { + solverName = BUOYANT_BOUSSINESQ_PIMPLE_FOAM; + } else { + solverName = PIMPLE_FOAM; + } + } + } + state.setSolver(new Solver(solverName)); + } + } + +} diff --git a/src/eu/engys/gui/casesetup/schemes/AdvectionSchemes.java b/src/eu/engys/gui/casesetup/schemes/AdvectionSchemes.java new file mode 100644 index 0000000..ba13e0d --- /dev/null +++ b/src/eu/engys/gui/casesetup/schemes/AdvectionSchemes.java @@ -0,0 +1,300 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.schemes; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.ListField; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.ControlDict; +import eu.engys.core.project.system.FvSchemes; + +public class AdvectionSchemes { + + private static final Logger logger = LoggerFactory.getLogger(AdvectionSchemes.class); + + static class SchemeTemplate { + private final String key; + private final String label; + private final Dictionary functions; + + public SchemeTemplate(String key, String label, Dictionary functions) { + this.key = key; + this.label = label; + this.functions = functions; + } + + @Override + public String toString() { + return label; + } + + public boolean hasValue1() { + return key.contains("%f"); + } + + public boolean hasValue2() { + return key.contains("%f %f"); + } + + public boolean hasValue3() { + return StringUtils.countMatches(key, "%f") == 3; + } + + public boolean equalsIgnoringValues(String field, String schemeKey) { + String keyWithFieldName = key.replace("%s", gradName(field)); + + String[] schemeKeyTokens = schemeKey.split("\\s+"); + String[] keyWithFieldNameTokens = keyWithFieldName.split("\\s+"); + + if (schemeKeyTokens.length != keyWithFieldNameTokens.length) + return false; + + for (int i = 0; i < schemeKeyTokens.length; i++) { + if (schemeKeyTokens[i].equals(keyWithFieldNameTokens[i])) { + continue; + } else if (keyWithFieldNameTokens[i].equals("%f")) { + continue; + } else { + return false; + } + } + return true; + } + + public List extractValues(String field, String schemeKey) { + String keyWithFieldName = key.replace("%s", gradName(field)); + + String[] schemeKeyTokens = schemeKey.split("\\s+"); + String[] keyWithFieldNameTokens = keyWithFieldName.split("\\s+"); + + List values = new ArrayList(); + for (int i = 0; i < schemeKeyTokens.length; i++) { + if (keyWithFieldNameTokens[i].equals("%f")) { + values.add(Double.parseDouble(schemeKeyTokens[i])); + } + } + return values; + } + + public Dictionary getFunctions() { + return functions; + } + } + + static class Scheme { + private SchemeTemplate template; + private String field; + private double value1; + private double value2; + private double value3; + + public void setField(String field) { + this.field = field; + } + + public String getField() { + return field; + } + + public void setValue1(double value1) { + this.value1 = value1; + } + + public double getValue1() { + return value1; + } + + public void setValue2(double value2) { + this.value2 = value2; + } + + public double getValue2() { + return value2; + } + + public void setValue3(double value3) { + this.value3 = value3; + } + + public double getValue3() { + return value3; + } + + public void setTemplate(SchemeTemplate template) { + this.template = template; + } + + public SchemeTemplate getTemplate() { + return template; + } + } + + private ArrayList scalar = new ArrayList(); + private ArrayList vector = new ArrayList(); + private Model model; + + public AdvectionSchemes(Model model) { + this.model = model; + + Dictionary defaultSchemes = model.getDefaults().getDefaultSchemes(); + if (defaultSchemes != null) { + ListField scalarSchemes = defaultSchemes.getList("scalar"); + ListField vectorSchemes = defaultSchemes.getList("vector"); + + for (DefaultElement el : scalarSchemes.getListElements()) { + if (el instanceof Dictionary) { + Dictionary d = (Dictionary) el; + addScalarScheme(new SchemeTemplate(d.lookup("key"), d.lookup("label"), d.subDict("functions"))); + } + } + + for (DefaultElement el : vectorSchemes.getListElements()) { + if (el instanceof Dictionary) { + Dictionary d = (Dictionary) el; + addVectorScheme(new SchemeTemplate(d.lookup("key"), d.lookup("label"), d.subDict("functions"))); + } + } + } else { + logger.warn("Advection schemes defaults not found!"); + } + } + + public void addScalarScheme(SchemeTemplate scheme) { + scalar.add(scheme); + } + + public void addVectorScheme(SchemeTemplate scheme) { + vector.add(scheme); + } + + public List getScalarSchemes() { + return scalar; + } + + public List getVectorSchemes() { + return vector; + } + + public void writeScheme(Scheme scheme) { + FvSchemes fvSchemes = model.getProject().getSystemFolder().getFvSchemes(); + Dictionary divSchemes = fvSchemes.getDivSchemes(); + String gradName = gradName(scheme.field); + String divName = div(gradName); + String value = ""; + if (divSchemes != null && scheme.getTemplate() != null) { + String keyWithFieldName = scheme.template.key.replace("%s", gradName); + if (scheme.template.hasValue1()) { + if (scheme.template.hasValue3()) { + value = String.format(keyWithFieldName, scheme.value1, scheme.value2, scheme.value3); + } else if (scheme.template.hasValue2()) { + value = String.format(keyWithFieldName, scheme.value1, scheme.value2); + } else { + value = String.format(keyWithFieldName, scheme.value1); + } + } else { + value = keyWithFieldName; + } + divSchemes.add(divName, value); + + if (scheme.getTemplate().functions != null) { + ControlDict controlDict = model.getProject().getSystemFolder().getControlDict(); + controlDict.functionObjectsToDict(); + Dictionary functions = controlDict.subDict("functions"); + if (functions == null) { + functions = new Dictionary("functions"); + controlDict.add(functions); + } + functions.merge(scheme.getTemplate().functions); + controlDict.functionObjectsToList(); + } + } + } + + public Scheme readScheme(String field) { + String schemeKey = readSchemeKeyFor(div(gradName(field))); + SchemeTemplate template = searchTemplate(field, schemeKey); + Scheme scheme = new Scheme(); + if (template != null) { + List values = template.extractValues(field, schemeKey); + scheme.setTemplate(template); + scheme.setField(field); + scheme.setValue1(values.size() > 0 ? values.get(0) : 0); + scheme.setValue2(values.size() > 1 ? values.get(1) : 0); + scheme.setValue3(values.size() > 2 ? values.get(2) : 0); + } else { + logger.error("Template Scheme {} not found for field {}", schemeKey, field); + } + + return scheme; + } + + private String readSchemeKeyFor(String divName) { + FvSchemes fvSchemes = model.getProject().getSystemFolder().getFvSchemes(); + Dictionary divSchemes = fvSchemes.getDivSchemes(); + if(divSchemes != null){ + if(divSchemes.found(divName)){ + return divSchemes.lookup(divName); + } else { + logger.error(String.format("Scheme Key not found for div '%s'", divName)); + return ""; + } + } else { + logger.error("DivSchemes is NULL"); + return ""; + } + } + + private SchemeTemplate searchTemplate(String field, String scheme) { + List templates = field.startsWith("U") ? vector : scalar; + for (SchemeTemplate t : templates) { + if (t.equalsIgnoringValues(field, scheme)) { + return t; + } + } + return null; + } + + private static String div(String gradName) { + return String.format("div(phi,%s)", gradName); + } + + private static String gradName(String field) { + if (field.equals("ILambda")) + return "Ii_h"; + else + return field; + } + +} diff --git a/src/eu/engys/gui/casesetup/schemes/NumericalSchemesPanel.java b/src/eu/engys/gui/casesetup/schemes/NumericalSchemesPanel.java new file mode 100644 index 0000000..d44bb38 --- /dev/null +++ b/src/eu/engys/gui/casesetup/schemes/NumericalSchemesPanel.java @@ -0,0 +1,261 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.schemes; + +import static eu.engys.core.project.zero.fields.Fields.AOA; +import static eu.engys.core.project.zero.fields.Fields.CO2; +import static eu.engys.core.project.zero.fields.Fields.EPSILON; +import static eu.engys.core.project.zero.fields.Fields.ILAMBDA; +import static eu.engys.core.project.zero.fields.Fields.K; +import static eu.engys.core.project.zero.fields.Fields.NU_TILDA; +import static eu.engys.core.project.zero.fields.Fields.OMEGA; +import static eu.engys.core.project.zero.fields.Fields.SMOKE; +import static eu.engys.core.project.zero.fields.Fields.T; +import static eu.engys.core.project.zero.fields.Fields.U; +import static eu.engys.core.project.zero.fields.Fields.W; +import static eu.engys.util.ui.ComponentsFactory.doubleField; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.text.ParseException; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryModel.DictionaryError; +import eu.engys.core.dictionary.model.DictionaryModel.DictionaryListener; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.FvSchemes; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; + +public class NumericalSchemesPanel extends DefaultGUIPanel { + + public static final String NUMERICAL_SCHEMES = "Numerical Schemes"; + public static final String LAPLACIAN_LABEL = "Laplacian"; + public static final String ADVECTION_LABEL = "Advection"; + + public static final String NON_ORTHOGONAL_CORRECTION_LABEL = "Non-orthogonal Correction"; + public static final String GAUSS_LINEAR_LIMITED = "Gauss linear limited"; + public static final String GAUSS_LINEAR_LIMITED_CORRECTED = "Gauss linear limited corrected"; + public static final String GAUSS_LINEAR_UNCORRECTED = "Gauss linear uncorrected"; + public static final String GAUSS_LINEAR_CORRECTED = "Gauss linear corrected"; + + private DictionaryModel laplaceModel; + private DictionaryModel snGradModel; + + private PanelBuilder laplacianBuilder; + private PanelBuilder advectionBuilder; + + private AdvectionSchemes schemes; + + private Map schemePanelsMap = new LinkedHashMap(); + + @Inject + public NumericalSchemesPanel(Model model) { + super(NUMERICAL_SCHEMES, model); + } + + @Override + protected JComponent layoutComponents() { + laplaceModel = new DictionaryModel(new Dictionary("laplacianSchemes")); + snGradModel = new DictionaryModel(new Dictionary("snGradSchemes")); + + DoubleField field = doubleField(0.0, 1.0); + laplacianBuilder = new PanelBuilder(); + laplacianBuilder.addComponent(NON_ORTHOGONAL_CORRECTION_LABEL, field).addPropertyChangeListener(new LaplacianFieldHandler("default", field)); + try { + field.commitEdit(); + } catch (ParseException e) { + e.printStackTrace(); + } + + schemes = new AdvectionSchemes(model); + + advectionBuilder = new PanelBuilder(); + JPanel advectionPanel = advectionBuilder.removeMargins().getPanel(); + advectionPanel.setBorder(BorderFactory.createTitledBorder(ADVECTION_LABEL)); + advectionPanel.setName(ADVECTION_LABEL); + + JPanel laplacianPanel = laplacianBuilder.removeMargins().getPanel(); + laplacianPanel.setBorder(BorderFactory.createTitledBorder(LAPLACIAN_LABEL)); + laplacianPanel.setName(LAPLACIAN_LABEL); + + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(advectionPanel); + builder.addComponent(laplacianPanel); + + return builder.removeMargins().getPanel(); + } + + private void rebuildPanel() { + if (model.getProject() != null) { + FvSchemes fvSchemes = model.getProject().getSystemFolder().getFvSchemes(); + if (fvSchemes != null) { + Dictionary divSchemes = fvSchemes.getDivSchemes(); + Dictionary laplacianSchemes = fvSchemes.getLaplacianSchemes(); + + if (divSchemes != null && laplacianSchemes != null) { + + laplaceModel.setDictionary(laplacianSchemes); + + advectionBuilder.clear(); + schemePanelsMap.clear(); + + buildFieldPanel(advectionBuilder, U); + for (Field field : model.getFields().getMultiphaseUFields()) { + buildFieldPanel(advectionBuilder, field.getName()); + } + + buildFieldPanel(advectionBuilder, K); + buildFieldPanel(advectionBuilder, EPSILON); + buildFieldPanel(advectionBuilder, OMEGA); + buildFieldPanel(advectionBuilder, NU_TILDA); + buildFieldPanel(advectionBuilder, T); + buildFieldPanel(advectionBuilder, W); + buildFieldPanel(advectionBuilder, ILAMBDA); + buildFieldPanel(advectionBuilder, CO2); + buildFieldPanel(advectionBuilder, AOA); + buildFieldPanel(advectionBuilder, SMOKE); + } + } + } + } + + private void buildFieldPanel(PanelBuilder advectionBuilder, String fieldName) { + + Fields fields = getModel().getFields(); + if (fields.containsKey(fieldName)) { + SchemePanel schemePanel = new SchemePanel(schemes, fieldName); + schemePanel.load(); + schemePanelsMap.put(fieldName, schemePanel); + advectionBuilder.addComponent(fieldName, schemePanel.getPanel()); + } + } + + @Override + public void load() { + rebuildPanel(); + } + + @Override + public void save() { + for (SchemePanel panel : schemePanelsMap.values()) { + panel.save(); + } + } + + @Override + public void materialsChanged() { + rebuildLater(); + } + + @Override + public void stateChanged() { + rebuildLater(); + } + + @Override + public void fieldsChanged() { + rebuildLater(); + } + + private void rebuildLater() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + rebuildPanel(); + } + }); + } + + class LaplacianFieldHandler implements PropertyChangeListener, DictionaryListener { + private String key; + private DoubleField field; + + public LaplacianFieldHandler(String key, DoubleField field) { + this.key = key; + this.field = field; + laplaceModel.addDictionaryListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + String laplacianValue; + String snGradValue; + double value = field.getDoubleValue(); + if (value == 0) { + laplacianValue = GAUSS_LINEAR_UNCORRECTED; + snGradValue = "uncorrected"; + } else if (value == 1) { + laplacianValue = GAUSS_LINEAR_CORRECTED; + snGradValue = "corrected"; + } else { + laplacianValue = GAUSS_LINEAR_LIMITED + " " + Double.toString(value); + snGradValue = "limited" + " " + Double.toString(value); + } + laplaceModel.getDictionary().add("default", laplacianValue); + snGradModel.getDictionary().add("default", snGradValue); + } + } + + @Override + public void dictionaryChanged() throws DictionaryError { + if (laplaceModel.getDictionary().found(key)) { + String laplacianValue = laplaceModel.getDictionary().lookup(key); + double value; + if (laplacianValue.equals(GAUSS_LINEAR_UNCORRECTED)) { + value = 0; + } else if (laplacianValue.equals(GAUSS_LINEAR_CORRECTED)) { + value = 1; + } else if (laplacianValue.startsWith(GAUSS_LINEAR_LIMITED_CORRECTED)) { + laplacianValue = laplacianValue.replace(GAUSS_LINEAR_LIMITED_CORRECTED, ""); + value = Double.parseDouble(laplacianValue); + } else if (laplacianValue.startsWith(GAUSS_LINEAR_LIMITED)) { + laplacianValue = laplacianValue.replace(GAUSS_LINEAR_LIMITED, ""); + value = Double.parseDouble(laplacianValue); + } else { + throw new DictionaryError("Unknown Laplacian Scheme: " + laplacianValue); + } + + field.setValue(value); + } + } + } +} diff --git a/src/eu/engys/gui/casesetup/schemes/SchemePanel.java b/src/eu/engys/gui/casesetup/schemes/SchemePanel.java new file mode 100644 index 0000000..7b993e1 --- /dev/null +++ b/src/eu/engys/gui/casesetup/schemes/SchemePanel.java @@ -0,0 +1,136 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.schemes; + +import static eu.engys.util.ui.ComponentsFactory.doubleField; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JComboBox; +import javax.swing.JComponent; + +import net.java.dev.designgridlayout.Componentizer; +import eu.engys.gui.casesetup.schemes.AdvectionSchemes.Scheme; +import eu.engys.gui.casesetup.schemes.AdvectionSchemes.SchemeTemplate; +import eu.engys.util.ui.textfields.DoubleField; + +public class SchemePanel { + + private String fieldName; + private DoubleField value1; + private DoubleField value2; + private DoubleField value3; + private JComboBox choice; + private AdvectionSchemes schemes; + + public SchemePanel(AdvectionSchemes schemes, String fieldName) { + this.schemes = schemes; + this.fieldName = fieldName; + + layoutComponents(); + } + + void load() { + Scheme scheme = schemes.readScheme(fieldName); + choice.setSelectedItem(scheme.getTemplate()); + value1.setDoubleValue(scheme.getValue1()); + value2.setDoubleValue(scheme.getValue2()); + value3.setDoubleValue(scheme.getValue3()); + } + + void save() { + Scheme scheme = new Scheme(); + scheme.setField(fieldName); + scheme.setTemplate(choice.getItemAt(choice.getSelectedIndex())); + scheme.setValue1(value1.getDoubleValue()); + scheme.setValue2(value2.getDoubleValue()); + scheme.setValue3(value3.getDoubleValue()); + schemes.writeScheme(scheme); + } + + private void layoutComponents() { + value1 = doubleField(); + value2 = doubleField(); + value3 = doubleField(); + + value1.setVisible(false); + value2.setVisible(false); + value3.setVisible(false); + + value1.setName(fieldName + ".0"); + value2.setName(fieldName + ".1"); + value3.setName(fieldName + ".2"); + + choice = new JComboBox(); + choice.setName(fieldName); + + if (fieldName.equals("U")) { + for (SchemeTemplate scheme : schemes.getVectorSchemes()) { + choice.addItem(scheme); + } + } else { + for (SchemeTemplate scheme : schemes.getScalarSchemes()) { + choice.addItem(scheme); + } + } + + choice.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + SchemeTemplate scheme = choice.getItemAt(choice.getSelectedIndex()); + if (scheme != null) { + value1.setVisible(scheme.hasValue1()); + value2.setVisible(scheme.hasValue2()); + value3.setVisible(scheme.hasValue3()); + } + } + }); + + // PropertyChangeListener listener = new PropertyChangeListener() { + // @Override + // public void propertyChange(PropertyChangeEvent evt) { + // if (evt.getPropertyName().equals("value")) { + // choice.setSelectedIndex(choice.getSelectedIndex()); + // if (choice.getSelectedIndex() == 5) { + // choice.setEnabled(false); + // } else { + // choice.setEnabled(true); + // } + // } + // } + // }; + + // value1.addPropertyChangeListener(listener); + // value2.addPropertyChangeListener(listener); + // advectionBuilder.addComponent(name, row); + } + + JComponent getPanel() { + return Componentizer.create().minToPref(choice).minAndMore(value1).minAndMore(value2).minAndMore(value3).component(); + } +} diff --git a/src/eu/engys/gui/casesetup/solution/AbstractSolutionModellingPanel.java b/src/eu/engys/gui/casesetup/solution/AbstractSolutionModellingPanel.java new file mode 100644 index 0000000..e8d0fcf --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/AbstractSolutionModellingPanel.java @@ -0,0 +1,419 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.LinkedHashSet; +import java.util.Set; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.modules.solutionmodelling.SolutionModellingPanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.TurbulenceModel; +import eu.engys.core.project.state.BuoyancyBuilder; +import eu.engys.core.project.state.Flow; +import eu.engys.core.project.state.Mach; +import eu.engys.core.project.state.Method; +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.SolverFamily; +import eu.engys.core.project.state.SolverType; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.StateBuilder; +import eu.engys.core.project.state.Table15; +import eu.engys.core.project.state.ThermalState; +import eu.engys.core.project.state.Time; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.gui.casesetup.solution.panels.AbstractThermalPanel; +import eu.engys.gui.casesetup.solution.panels.GPanel; +import eu.engys.gui.casesetup.solution.panels.MultiphasePanel; +import eu.engys.gui.casesetup.solution.panels.SolutionStatePanel; +import eu.engys.gui.casesetup.solution.panels.TurbulencePanel; +import eu.engys.util.ui.ChooserPanel; +import eu.engys.util.ui.UiUtil; + +public abstract class AbstractSolutionModellingPanel extends DefaultGUIPanel implements SolutionModellingPanel { + + private static final Logger logger = LoggerFactory.getLogger(AbstractSolutionModellingPanel.class); + + private static final String STATE_CHANGED_WARNING = "Solution state has been changed.\nAll fields default settings are going to be reset now.\nContinue?"; + + public static final String SOLUTION_MODELLING = "Solution Modelling"; + + protected Set modules; + private Table15 solversTable; + + private SolutionStatePanel solutionStatePanel; + private MultiphasePanel multiphasePanel; + private AbstractThermalPanel thermalPanel; + private GPanel gPanel; + private TurbulencePanel turbulencePanel; + + public AbstractSolutionModellingPanel(Model model, Table15 solversTable, Set modules) { + super(SOLUTION_MODELLING, model); + this.solversTable = solversTable; + this.modules = modules; + } + + @Override + protected JComponent layoutComponents() { + JPanel topPanel = new JPanel(new GridBagLayout()); + + solutionStatePanel = new SolutionStatePanel(modules, isSolutionStatePanelVisible()); + + turbulencePanel = new TurbulencePanel(); + + multiphasePanel = createMultiphasePanel(); + final PropertyChangeListener multiphaseListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("selection")) { + fix(); + } + } + }; + multiphasePanel.setListener(multiphaseListener); + + thermalPanel = createThermalPanel(); + ActionListener thermalListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fix(); + } + }; + thermalPanel.setThermalListener(thermalListener); + + gPanel = new GPanel(); + + PropertyChangeListener solutionStateListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("selection")) { + multiphasePanel.removeListener(); + thermalPanel.removeListeners(); + + fix(); + + thermalPanel.addListeners(); + multiphasePanel.addListener(); + } + } + }; + solutionStatePanel.setListener(solutionStateListener); + + for (ApplicationModule m : modules) { + m.getSolutionView().buildDynamic(getDynamicBuilder()); + } + + for (ApplicationModule m : modules) { + m.getSolutionView().buildScalar(this); + } + + topPanel.add(solutionStatePanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + topPanel.add(turbulencePanel, new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + topPanel.add(multiphasePanel, new GridBagConstraints(0, 2, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + topPanel.add(thermalPanel, new GridBagConstraints(0, 3, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + topPanel.add(gPanel, new GridBagConstraints(0, 4, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + topPanel.add(getDynamicPanel(), new GridBagConstraints(0, 5, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + topPanel.add(getScalarsPanel(), new GridBagConstraints(0, 6, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + topPanel.add(new JLabel(), new GridBagConstraints(0, 7, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + fix(); + + return topPanel; + } + + protected abstract boolean isSolutionStatePanelVisible(); + + @Override + public void load() { + removeListeners(); + updateGUIFromState(); + addListeners(); + } + + @Override + public void save() { + if (stateHasChanged()) { + if (JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), STATE_CHANGED_WARNING, "State Changed", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION) { + _save(); + } else { + load(); + } + } + BuoyancyBuilder.save(model, gPanel.getGValue()); + } + + public void saveAnyway() { + _save(); + BuoyancyBuilder.save(model, gPanel.getGValue()); + } + + private void _save() { + updateStateFromGUI(); + StateBuilder.changeState(model, modules); + } + + private void updateStateFromGUI() { + State state = getStateFromGUI(); + model.setState(state); + } + + private boolean stateHasChanged() { + if (model.getPatches().isEmpty()) + return false; + + State state = model.getState(); + + SolverType solverType = solutionStatePanel.getSolverType(); + Time time = solutionStatePanel.getTime(); + Flow flow = solutionStatePanel.getFlow(); + Method method = solutionStatePanel.getMethod(); + Mach mach = solutionStatePanel.getMach(); + + boolean energy = thermalPanel.isEnergySelected(); + boolean buoyant = thermalPanel.isBuoyancySelected(); + + MultiphaseModel multiphase = this.multiphasePanel.getSelectedModel(); + int phases = this.multiphasePanel.getPhasesNumber(); + + TurbulenceModel turbulenceModel = turbulencePanel.getSelectedTurbulenceModel(); + + if (state.getSolverType() != solverType) { + logger.info("SOLVER TYPE [{} -> {}]", state.getSolverType(), solverType); + return true; + } + if (state.getFlow() != flow) { + logger.info("FLOW [{} -> {}]", state.getFlow(), flow); + return true; + } + if (state.getTime() != time) { + logger.info("TIME [{} -> {}]", state.getTime(), time); + return true; + } + if (state.getMethod() != method) { + logger.info("METHOD [{} -> {}]", state.getMethod(), method); + return true; + } + if (state.getMach() != mach) { + logger.info("MACH [{} -> {}]", state.getMach(), mach); + return true; + } + if (state.isEnergy() != energy) { + logger.info("ENERGY [{} -> {}]", state.isEnergy(), energy); + return true; + } + if (state.isBuoyant() != buoyant) { + logger.info("BUOYANT [{} -> {}]", state.isBuoyant(), buoyant); + return true; + } + if (turbulenceModel != null && !turbulenceModel.equals(state.getTurbulenceModel())) { + logger.info("TURBULENCE [{} -> {}]", state.getTurbulenceModel(), turbulenceModel); + return true; + } + if (state.getMultiphaseModel() != multiphase) { + logger.info("MULTIPHASE [{} -> {}]", state.getMultiphaseModel().getLabel(), multiphase.getLabel()); + return true; + } + if (state.getPhases() != phases) { + logger.info("PHASEs [{} -> {}]", state.getPhases(), phases); + return true; + } + + for (ApplicationModule m : modules) { + if (m.getSolutionView().hasChanged()) { + return true; + } + } + + return false; + } + + private State getStateFromGUI() { + State state = new State(); + + SolverType solverType = solutionStatePanel.getSolverType(); + Time time = solutionStatePanel.getTime(); + Flow flow = solutionStatePanel.getFlow(); + Method method = solutionStatePanel.getMethod(); + Mach mach = solutionStatePanel.getMach(); + + boolean energy = thermalPanel.isEnergySelected(); + boolean buoyant = thermalPanel.isBuoyancySelected(); + + MultiphaseModel multiphase = this.multiphasePanel.getSelectedModel(); + int phases = this.multiphasePanel.getPhasesNumber(); + + TurbulenceModel turbulenceModel = turbulencePanel.getSelectedTurbulenceModel(); + + if (state.getSolverType() != solverType) { + state.setSolverType(solverType); + } + if (state.getFlow() != flow) { + state.setFlow(flow); + } + if (state.getTime() != time) { + state.setTime(time); + } + if (state.getMethod() != method) { + state.setMethod(method); + } + if (state.getMach() != mach) { + state.setMach(mach); + } + if (state.isEnergy() != energy) { + state.setEnergy(energy); + } + if (state.isBuoyant() != buoyant) { + state.setBuoyant(buoyant); + } + if (turbulenceModel != null && !turbulenceModel.equals(state.getTurbulenceModel())) { + state.setTurbulenceModel(turbulenceModel); + } + if (state.getMultiphaseModel() != multiphase) { + state.setMultiphaseModel(multiphase); + } + if (state.getPhases() != phases) { + state.setPhases(phases); + } + + ModulesUtil.updateStateFromGUI(modules); + + // Solver Families + Set solverFamilies = new LinkedHashSet(); + solversTable.updateSolverFamilies(state, solverFamilies); + ModulesUtil.updateSolverFamilies(modules, state, solverFamilies); + + if (solverFamilies.isEmpty()) { + state.setSolverFamily(SolverFamily.NONE); + } else { + state.setSolverFamily(solverFamilies.iterator().next()); + } + + // Solver + solversTable.updateSolver(state); + ModulesUtil.updateSolver(modules, state); + + return state; + } + + private void updateGUIFromState() { + State state = model.getState(); + + solutionStatePanel.updateFromState(state); + solutionStatePanel.fix(new SolutionState(state)); + + multiphasePanel.updateFromState(state); + + thermalPanel.updateEnergyFromState(state); + thermalPanel.updateBuoyancyFromState(state); + gPanel.updateFromState(model, state); + + turbulencePanel.updateFromState(model, state); + + for (ApplicationModule m : modules) { + m.getSolutionView().updateGUIFromState(state); + } + } + + private void fix() { + SolutionState ss = solutionStatePanel.getSolutionState(); + solutionStatePanel.fix(ss); + multiphasePanel.fixSolutionState(ss); + for (ApplicationModule m : modules) { + m.getSolutionView().fixSolutionState(ss); + } + + MultiphaseModel mm = multiphasePanel.getSelectedModel(); + multiphasePanel.fixMultiphase(mm); + for (ApplicationModule m : modules) { + m.getSolutionView().fixMultiphase(mm); + } + + thermalPanel.fixEnergy(ss, mm); + thermalPanel.fixBuoyancy(ss, mm); + + ThermalState ts = thermalPanel.getThermalState(); + gPanel.fix(ss, mm, ts); + for (ApplicationModule m : modules) { + m.getSolutionView().fixThermal(ss, ts); + } + + turbulencePanel.fixSolutionState(model, ss); + } + + private void removeListeners() { + multiphasePanel.removeListener(); + thermalPanel.removeListeners(); + solutionStatePanel.removeListeners(); + } + + private void addListeners() { + multiphasePanel.addListener(); + thermalPanel.addListeners(); + solutionStatePanel.addListeners(); + } + + @Override + public ChooserPanel getSolverTypePanel() { + return solutionStatePanel.getSolverTypePanel(); + } + + @Override + public MultiphasePanel getMultiphasePanel() { + return multiphasePanel; + } + + protected abstract AbstractThermalPanel createThermalPanel(); + + protected abstract MultiphasePanel createMultiphasePanel(); + + protected abstract JComponent getDynamicPanel(); + + protected abstract JComponent getScalarsPanel(); + + // For test purpose only + public void setModules(Set modules) { + this.modules = modules; + } +} diff --git a/src/eu/engys/gui/casesetup/solution/StandardSolutionModellingPanel.java b/src/eu/engys/gui/casesetup/solution/StandardSolutionModellingPanel.java new file mode 100644 index 0000000..09ec993 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/StandardSolutionModellingPanel.java @@ -0,0 +1,109 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution; + +import java.util.Set; + +import javax.inject.Inject; +import javax.swing.JComponent; +import javax.swing.JLabel; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.Table15; +import eu.engys.gui.casesetup.solution.panels.AbstractThermalPanel; +import eu.engys.gui.casesetup.solution.panels.MultiphasePanel; +import eu.engys.util.ui.builder.PanelBuilder; + +public class StandardSolutionModellingPanel extends AbstractSolutionModellingPanel { + + @Inject + public StandardSolutionModellingPanel(Model model, Table15 solversTable, Set modules) { + super(model, solversTable, modules); + } + + @Override + protected MultiphasePanel createMultiphasePanel() { + return new MultiphasePanel(modules) { + public void fixSolutionState(SolutionState ss) { + if (ss.areSolverTypeAndTimeAndFlowAndTurbulenceChoosen()) { + if (ss.isCoupled() || ss.isSteady() || ss.isCompressible()) { + if (isMultiphaseOn()) { + setMultiphaseOff(); + } + multiphaseBuilder.setEnabled(false); + phasesNumber.setIntValue(1); + phasesNumber.setEnabled(false); + } else { + multiphaseBuilder.setEnabled(true); + // MODULES + } + } else { + multiphaseBuilder.setEnabled(false); + phasesNumber.setIntValue(1); + phasesNumber.setEnabled(false); + } + } + }; + } + + @Override + protected boolean isSolutionStatePanelVisible() { + return false; + } + + @Override + protected AbstractThermalPanel createThermalPanel() { + return new StandardThermalPanel(modules); + } + + @Override + public PanelBuilder getDynamicBuilder() { + return new PanelBuilder(); + } + + @Override + public PanelBuilder getScalarsBuilderLeft() { + return new PanelBuilder(); + } + + @Override + public PanelBuilder getScalarsBuilderRight() { + return new PanelBuilder(); + } + + @Override + protected JComponent getDynamicPanel() { + return new JLabel(); + } + + @Override + protected JComponent getScalarsPanel() { + return new JLabel(); + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/StandardThermalPanel.java b/src/eu/engys/gui/casesetup/solution/StandardThermalPanel.java new file mode 100644 index 0000000..e105a9f --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/StandardThermalPanel.java @@ -0,0 +1,72 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution; + +import java.util.Set; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.core.project.state.SolutionState; +import eu.engys.gui.casesetup.solution.panels.AbstractThermalPanel; + +public class StandardThermalPanel extends AbstractThermalPanel { + + public StandardThermalPanel(Set modules) { + super(modules); + } + + @Override + public void fixEnergy(SolutionState ss, MultiphaseModel mm) { + if (ss.areSolverTypeAndTimeAndFlowAndTurbulenceChoosen()) { + energy.setEnabled(true); + boolean isMultiphaseOn = mm.isOn(); + boolean isMultiphaseOff = mm.isOff(); + if (ss.isCompressible()) { + if ((isMultiphaseOn && energy.isSelected()) || (isMultiphaseOff && !energy.isSelected())) { + energy.doClick(); + } + energy.setEnabled(false); + } else if (ss.isIncompressible()) { + if (energy.isSelected() && isMultiphaseOn) { + energy.doClick(); + } + energy.setEnabled(isMultiphaseOff); + } + } else { + energy.setEnabled(false); + } + + if (ss.areSolverTypeAndTimeAndFlowAndTurbulenceChoosen()) { + if (ss.isTransient() && ss.isLES()) { + if (energy.isSelected()) { + energy.doClick(); + } + energy.setEnabled(false); + } + } + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/AbstractThermalPanel.java b/src/eu/engys/gui/casesetup/solution/panels/AbstractThermalPanel.java new file mode 100644 index 0000000..e115e7a --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/AbstractThermalPanel.java @@ -0,0 +1,164 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import java.awt.BorderLayout; +import java.awt.event.ActionListener; +import java.util.Set; + +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JPanel; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.ThermalState; +import eu.engys.util.ui.builder.PanelBuilder; + +public abstract class AbstractThermalPanel extends JPanel { + + public static final String BUOYANCY = "Buoyancy"; + public static final String ENERGY = "Energy"; + public static final String THERMAL = "Thermal"; + + private Set modules; + private ActionListener listener; + protected JCheckBox energy; + private JCheckBox buoyancy; + + public AbstractThermalPanel(Set modules) { + super(new BorderLayout()); + this.modules = modules; + layoutComponents(); + } + + + private void layoutComponents() { + PanelBuilder builder = new PanelBuilder(); + this.energy = (JCheckBox) builder.startCheck(ENERGY); + + this.buoyancy = (JCheckBox) builder.startCheck(BUOYANCY); + buoyancy.setName(BUOYANCY); + builder.endCheck(); + + for (ApplicationModule m : modules) { + m.getSolutionView().buildThermal(builder); + } + + builder.endCheck(false); + + JPanel panel = builder.getPanel(); + panel.setBorder(BorderFactory.createTitledBorder(AbstractThermalPanel.THERMAL)); + add(panel, BorderLayout.CENTER); + } + + public abstract void fixEnergy(SolutionState ss, MultiphaseModel mm); + + public void fixBuoyancy(SolutionState ss, MultiphaseModel mm) { + if (ss.areSolverTypeAndTimeAndFlowAndTurbulenceChoosen()) { + if (ss.isCoupled()) { + if (buoyancy.isSelected()) { + buoyancy.setEnabled(true); + buoyancy.doClick(); + } + buoyancy.setEnabled(false); + } else { + boolean isTransientCompressibleLES = ss.isTransient() && ss.isCompressible() && ss.isLES(); + buoyancy.setEnabled(true); + if (buoyancy.isSelected() && (!energy.isSelected() || isTransientCompressibleLES || ss.isHighMach())) { + buoyancy.doClick(); + } + buoyancy.setEnabled(energy.isSelected() && !isTransientCompressibleLES && ss.isLowMach()); + } + } else { + buoyancy.setEnabled(false); + } + } + + public void updateEnergyFromState(State state) { + boolean energyEnabled = energy.isEnabled(); + energy.setEnabled(true); + if (state.isEnergy()) { + if (!energy.isSelected()) { + energy.doClick(); + } + } else { + if (energy.isSelected()) { + energy.doClick(); + } + } + energy.setEnabled(energyEnabled); + fixEnergy(new SolutionState(state), state.getMultiphaseModel()); + } + + public void updateBuoyancyFromState(State state) { + boolean buoyancyEnabled = buoyancy.isEnabled(); + buoyancy.setEnabled(true); + if (state.isBuoyant()) { + if (!buoyancy.isSelected()) { + buoyancy.doClick(); + } + } else { + if (buoyancy.isSelected()) { + buoyancy.doClick(); + } + } + buoyancy.setEnabled(buoyancyEnabled); + fixBuoyancy(new SolutionState(state), state.getMultiphaseModel()); + } + + public ThermalState getThermalState() { + ThermalState ts = new ThermalState(); + ts.setEnergy(energy.isSelected()); + ts.setBuoyancy(buoyancy.isSelected()); + return ts; + } + + public void removeListeners() { + energy.removeActionListener(listener); + buoyancy.removeActionListener(listener); + } + + public void addListeners() { + energy.addActionListener(listener); + buoyancy.addActionListener(listener); + } + + public void setThermalListener(ActionListener listener) { + this.listener = listener; + } + + public boolean isEnergySelected(){ + return energy.isSelected(); + } + + public boolean isBuoyancySelected(){ + return buoyancy.isSelected(); + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/FlowPanel.java b/src/eu/engys/gui/casesetup/solution/panels/FlowPanel.java new file mode 100644 index 0000000..810d495 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/FlowPanel.java @@ -0,0 +1,71 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import static eu.engys.core.project.state.SolutionState.COMPRESSIBLE; +import static eu.engys.core.project.state.SolutionState.INCOMPRESSIBLE; +import eu.engys.core.project.state.Flow; +import eu.engys.core.project.state.State; +import eu.engys.util.ui.ChooserPanel; + +public class FlowPanel extends ChooserPanel { + + public static final String FLOW = "Flow"; + + public FlowPanel() { + super(FLOW); + addChoice(COMPRESSIBLE); + addChoice(INCOMPRESSIBLE); + } + + public void updateFromState(State state) { + if (state.isCompressible()) + select(COMPRESSIBLE); + else if (state.isIncompressible()) + select(INCOMPRESSIBLE); + else + selectNone(); + + } + + public Flow getFlow() { + String selectedState = getSelectedState(); + if (selectedState.equals(COMPRESSIBLE)) + return Flow.COMPRESSIBLE; + else if (selectedState.equals(INCOMPRESSIBLE)) + return Flow.INCOMPRESSIBLE; + return Flow.NONE; + } + + public boolean isCompressible() { + return getSelectedState().equals(COMPRESSIBLE); + } + + public boolean isIncompressible() { + return getSelectedState().equals(INCOMPRESSIBLE); + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/GPanel.java b/src/eu/engys/gui/casesetup/solution/panels/GPanel.java new file mode 100644 index 0000000..7d4d032 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/GPanel.java @@ -0,0 +1,102 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import static eu.engys.util.ui.ComponentsFactory.doublePointField; + +import java.awt.BorderLayout; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.ThermalState; +import eu.engys.util.Symbols; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; + +public class GPanel extends JPanel { + + public static final String G = "g [m/s" + Symbols.SQUARE + "]"; + public static final String GRAVITY = "Gravity"; + private PanelBuilder builder; + private DoubleField[] gFields; + + public GPanel() { + super(new BorderLayout()); + layoutComponents(); + } + + private void layoutComponents() { + builder = new PanelBuilder(); + gFields = doublePointField(0.0, 0.0, -9.81); + builder.addComponent(GPanel.G, gFields); + JPanel gPanel = builder.getPanel(); + gPanel.setBorder(BorderFactory.createTitledBorder(GPanel.GRAVITY)); + add(gPanel, BorderLayout.CENTER); + } + + public void fix(SolutionState ss, MultiphaseModel mm, ThermalState ts) { + if (ss.areSolverTypeAndTimeAndFlowAndTurbulenceChoosen()) { + if (mm.isOn()) { + builder.setEnabled(true); + } else if (ts.isBuoyancy()) { + builder.setEnabled(true); + } else { + builder.setEnabled(false); + } + } else { + builder.setEnabled(false); + } + } + + public void updateFromState(Model model, State state) { + Dictionary g = model.getProject().getConstantFolder().getG(); + if (g != null && g.found("value")) { + String[] gValues = g.lookupArray("value"); + try { + double x = Double.parseDouble(gValues[0]); + double y = Double.parseDouble(gValues[1]); + double z = Double.parseDouble(gValues[2]); + + gFields[0].setValue(x); + gFields[1].setValue(y); + gFields[2].setValue(z); + } catch (Exception e) { + } + } + fix(new SolutionState(state), state.getMultiphaseModel(), new ThermalState(state)); + } + + public double[] getGValue() { + return new double[] { gFields[0].getDoubleValue(), gFields[1].getDoubleValue(), gFields[2].getDoubleValue() }; + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/MachPanel.java b/src/eu/engys/gui/casesetup/solution/panels/MachPanel.java new file mode 100644 index 0000000..797abd0 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/MachPanel.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import eu.engys.core.project.state.Mach; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.State; +import eu.engys.util.ui.ChooserPanel; + +public class MachPanel extends ChooserPanel { + + public static final String MACH = "Mach"; + + public MachPanel() { + super(MACH); + addChoice(SolutionState.LO_MACH); + addChoice(SolutionState.HI_MACH); + } + + public void updateFromState(State state) { + if (state.isLowMach()) + select(SolutionState.LO_MACH); + else if (state.isHighMach()) + select(SolutionState.HI_MACH); + else + selectNone(); + + } + + public Mach getMach() { + String selectedState = getSelectedState(); + if (selectedState.equals(SolutionState.HI_MACH)) + return Mach.HIGH; + else if (selectedState.equals(SolutionState.LO_MACH)) + return Mach.LOW; + return Mach.NONE; + } + + public boolean isHighMach() { + return getSelectedState().equals(SolutionState.HI_MACH); + } + + public boolean isLowMach() { + return getSelectedState().equals(SolutionState.LO_MACH); + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/MethodPanel.java b/src/eu/engys/gui/casesetup/solution/panels/MethodPanel.java new file mode 100644 index 0000000..116980e --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/MethodPanel.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import eu.engys.core.project.state.Method; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.State; +import eu.engys.util.ui.ChooserPanel; + +public class MethodPanel extends ChooserPanel { + + public static final String TURBULENCE = "Turbulence"; + + public MethodPanel() { + super(TURBULENCE); + addChoice(SolutionState.RANS); + addChoice(SolutionState.LES_DES); + } + + public void updateFromState(State state) { + if (state.isLES()) + select(SolutionState.LES_DES); + else if (state.isRANS()) + select(SolutionState.RANS); + else + selectNone(); + + } + + public Method getMethod() { + String selectedState = getSelectedState(); + if (selectedState.equals(SolutionState.LES_DES)) + return Method.LES; + else if (selectedState.equals(SolutionState.RANS)) + return Method.RANS; + return Method.NONE; + } + + public boolean isLES() { + return getSelectedState().equals(SolutionState.LES_DES); + } + + public boolean isRAS() { + return getSelectedState().equals(SolutionState.RANS); + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/MultiphaseChooserPanel.java b/src/eu/engys/gui/casesetup/solution/panels/MultiphaseChooserPanel.java new file mode 100644 index 0000000..62cde4a --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/MultiphaseChooserPanel.java @@ -0,0 +1,101 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import java.beans.PropertyChangeListener; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.AbstractButton; +import javax.swing.JComponent; + +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.util.ui.ChooserPanel; + +public class MultiphaseChooserPanel { + + private ChooserPanel chooserPanel; + private Map solvers = new HashMap<>(); + + public MultiphaseChooserPanel() { + chooserPanel = new ChooserPanel("", false); + } + + public void addMultiphaseChoice(MultiphaseModel multiphase) { + chooserPanel.addChoice(multiphase.getLabel()); + solvers.put(multiphase.getLabel(), multiphase); + } + + public MultiphaseModel getSelectedMultiphase() { + String selectedState = chooserPanel.getSelectedState(); + return selectedState == ChooserPanel.NONE ? MultiphaseModel.OFF : solvers.get(selectedState); + } + + public void select(MultiphaseModel model) { + chooserPanel.select(model.getLabel()); + } + + public void selectNone() { + chooserPanel.selectNone(); + } + + public void addListener(PropertyChangeListener listener) { + chooserPanel.addPropertyChangeListener(listener); + } + + public void removeListener(PropertyChangeListener listener) { + chooserPanel.removePropertyChangeListener(listener); + } + + public boolean isMultiphaseOff() { + return chooserPanel.getSelectedState().equals(MultiphaseModel.OFF_LABEL); + } + + public void setMultiphaseOff() { + chooserPanel.select(MultiphaseModel.OFF_LABEL); + } + + public JComponent getChooserPanel() { + return chooserPanel; + } + + public void enableChoice(MultiphaseModel mm) { + AbstractButton button = chooserPanel.getButton(mm.getLabel()); + if (!button.isEnabled()) { + button.setEnabled(true); + } + } + + public void disableChoice(MultiphaseModel mm) { + AbstractButton button = chooserPanel.getButton(mm.getLabel()); + if (button.isSelected()) { + select(MultiphaseModel.OFF); + } + if (button.isEnabled()) { + button.setEnabled(false); + } + } +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/MultiphasePanel.java b/src/eu/engys/gui/casesetup/solution/panels/MultiphasePanel.java new file mode 100644 index 0000000..c81c66c --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/MultiphasePanel.java @@ -0,0 +1,159 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import java.awt.BorderLayout; +import java.beans.PropertyChangeListener; +import java.util.Set; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.solutionmodelling.MultiphaseBuilder; +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.State; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.SpinnerField; + +public class MultiphasePanel extends JPanel implements MultiphaseBuilder { + + public static final String PHASES_LABEL = "Phases"; + private static final String MULTIPHASE = "Multiphase"; + + protected SpinnerField phasesNumber; + protected MultiphaseChooserPanel multiphaseChooser; + protected PanelBuilder multiphaseBuilder; + private PropertyChangeListener listener; + + public MultiphasePanel(Set modules) { + super(new BorderLayout()); + + multiphaseChooser = new MultiphaseChooserPanel(); + multiphaseChooser.addMultiphaseChoice(MultiphaseModel.OFF); + + phasesNumber = ComponentsFactory.spinnerField(2, Integer.MAX_VALUE); + phasesNumber.setEnabled(false); + + PanelBuilder phaseBuilderLeft = new PanelBuilder(); + PanelBuilder phaseBuilderRight = new PanelBuilder(); + phaseBuilderLeft.addComponent(multiphaseChooser.getChooserPanel()); + phaseBuilderRight.addComponent(PHASES_LABEL, phasesNumber); + + multiphaseBuilder = new PanelBuilder(); + multiphaseBuilder.addComponent(phaseBuilderLeft.removeMargins().getPanel(), phaseBuilderRight.removeMargins().getPanel()); + multiphaseBuilder.getPanel().setBorder(BorderFactory.createTitledBorder(MULTIPHASE)); + + add(multiphaseBuilder.getPanel()); + + for (ApplicationModule m : modules) { + m.getSolutionView().buildMultiphase(this); + } + } + + public void updateFromState(State state) { + MultiphaseModel multiphaseModel = state.getMultiphaseModel(); + if (multiphaseModel != null) { + multiphaseChooser.select(multiphaseModel); + } else { + multiphaseChooser.selectNone(); + } + if (multiphaseModel.isMultiphase()) { + phasesNumber.setIntValue(Math.max(2, state.getPhases())); + } else { + phasesNumber.setIntValue(1); + } + + fixSolutionState(new SolutionState(state)); + fixMultiphase(getSelectedModel()); + } + + public void fixSolutionState(SolutionState solutionState) { + } + + public void fixMultiphase(MultiphaseModel mm) { + if (mm.isOff()) { + phasesNumber.setIntValue(1); + phasesNumber.setEnabled(false); + } + } + + @Override + public void addMultiphaseChoice(MultiphaseModel mm) { + multiphaseChooser.addMultiphaseChoice(mm); + } + + public MultiphaseChooserPanel getPhasesPanel() { + return multiphaseChooser; + } + + @Override + public SpinnerField getPhasesField() { + return phasesNumber; + } + + public int getPhasesNumber() { + return phasesNumber.getIntValue(); + } + + public MultiphaseModel getSelectedModel() { + return multiphaseChooser.getSelectedMultiphase(); + } + + public void addListener() { + multiphaseChooser.addListener(listener); + } + + public void removeListener() { + multiphaseChooser.removeListener(listener); + } + + public boolean isMultiphaseOn() { + return !isMultiphaseOff(); + } + + public boolean isMultiphaseOff() { + return multiphaseChooser.isMultiphaseOff(); + } + + protected void setMultiphaseOff() { + multiphaseChooser.setMultiphaseOff(); + } + + public void enableChoice(MultiphaseModel mm) { + multiphaseChooser.enableChoice(mm); + } + + public void disableChoice(MultiphaseModel mm) { + multiphaseChooser.disableChoice(mm); + } + + public void setListener(PropertyChangeListener listener) { + this.listener = listener; + } +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/SolutionStatePanel.java b/src/eu/engys/gui/casesetup/solution/panels/SolutionStatePanel.java new file mode 100644 index 0000000..c870451 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/SolutionStatePanel.java @@ -0,0 +1,225 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.beans.PropertyChangeListener; +import java.util.Set; + +import javax.swing.JPanel; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.state.Flow; +import eu.engys.core.project.state.Mach; +import eu.engys.core.project.state.Method; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.SolverType; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.Time; + +public class SolutionStatePanel extends JPanel { + + protected SolverTypePanel solverTypePanel; + protected TimePanel timePanel; + protected FlowPanel flowPanel; + protected MethodPanel methodPanel; + protected MachPanel machPanel; + + private PropertyChangeListener listener; + private Set modules; + + public SolutionStatePanel(Set modules, boolean visibleSolverType) { + super(new GridBagLayout()); + this.modules = modules; + layoutComponents(visibleSolverType); + } + + public void setListener(PropertyChangeListener listener) { + this.listener = listener; + } + + private void layoutComponents(boolean visibleSolverType) { + solverTypePanel = new SolverTypePanel(); + timePanel = new TimePanel(); + flowPanel = new FlowPanel(); + methodPanel = new MethodPanel(); + machPanel = new MachPanel(); + + + if (visibleSolverType) { + add(solverTypePanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + add(timePanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + add(flowPanel, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + add(methodPanel, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + add(machPanel, new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + } else { + add(timePanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + add(flowPanel, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + add(methodPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + add(machPanel, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + } + + for (ApplicationModule m : modules) { + m.getSolutionView().buildSolution(solverTypePanel); + } + } + + public void updateFromState(State state) { + solverTypePanel.updateFromState(state); + timePanel.updateFromState(state); + flowPanel.updateFromState(state); + methodPanel.updateFromState(state); + machPanel.updateFromState(state); + } + + public void fix(SolutionState ss) { + if (ss.isSolverNone()) { + timePanel.setEnabled(false); + methodPanel.setEnabled(false); + flowPanel.setEnabled(false); + machPanel.setEnabled(false); + } else { + timePanel.setEnabled(true); + if (ss.isSegregated()) { + if (ss.isTimeNone()) { + methodPanel.setEnabled(false); + flowPanel.setEnabled(false); + machPanel.setEnabled(false); + } else { + methodPanel.setEnabled(true); + flowPanel.setEnabled(true); + machPanel.setEnabled(true); + if (ss.isSteady()) { + methodPanel.setEnabled(false); + methodPanel.select(SolutionState.RANS); + machPanel.setEnabled(false); + machPanel.select(SolutionState.LO_MACH); + } else if (ss.isTransient()) { + if (ss.isFlowNone()) { + methodPanel.setEnabled(false); + machPanel.setEnabled(false); + } else { + methodPanel.setEnabled(true); + if (ss.isCompressible()) { + machPanel.setEnabled(true); + if (ss.isMachNone()) { + machPanel.select(SolutionState.LO_MACH); + } + } else if (ss.isIncompressible()) { + machPanel.setEnabled(false); + machPanel.select(SolutionState.LO_MACH); + } + } + } + } + } else if (ss.isCoupled()) { + flowPanel.select(SolutionState.INCOMPRESSIBLE); + flowPanel.setEnabled(false); + methodPanel.select(SolutionState.RANS); + methodPanel.setEnabled(false); + machPanel.select(SolutionState.LO_MACH); + machPanel.setEnabled(false); + } + } + } + + public SolutionState getSolutionState() { + SolutionState ss = new SolutionState(); + ss.time = timePanel.getSelectedState(); + ss.flow = flowPanel.getSelectedState(); + ss.turbulence = methodPanel.getSelectedState(); + ss.solver = solverTypePanel.getSelectedState(); + ss.mach = machPanel.getSelectedState(); + return ss; + } + + public void removeListeners() { + solverTypePanel.removePropertyChangeListener(listener); + timePanel.removePropertyChangeListener(listener); + flowPanel.removePropertyChangeListener(listener); + methodPanel.removePropertyChangeListener(listener); + machPanel.removePropertyChangeListener(listener); + } + + public void addListeners() { + solverTypePanel.addPropertyChangeListener(listener); + timePanel.addPropertyChangeListener(listener); + flowPanel.addPropertyChangeListener(listener); + methodPanel.addPropertyChangeListener(listener); + machPanel.addPropertyChangeListener(listener); + } + + public SolverTypePanel getSolverTypePanel() { + return solverTypePanel; + } + + public SolverType getSolverType() { + return solverTypePanel.getSolverType(); + } + + public Time getTime() { + return timePanel.getTime(); + } + + public Flow getFlow() { + return flowPanel.getFlow(); + } + + public Method getMethod() { + return methodPanel.getMethod(); + } + + public Mach getMach() { + return machPanel.getMach(); + } + + public boolean isCoupled() { + return solverTypePanel.isCoupled(); + } + + public boolean isSegregated() { + return solverTypePanel.isSegregated(); + } + + public boolean isCompressible() { + return flowPanel.isCompressible(); + } + + public boolean isIncompressible() { + return flowPanel.isIncompressible(); + } + + public boolean isLES() { + return methodPanel.isLES(); + } + + public boolean isRAS() { + return methodPanel.isRAS(); + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/SolverTypePanel.java b/src/eu/engys/gui/casesetup/solution/panels/SolverTypePanel.java new file mode 100644 index 0000000..9ffff3d --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/SolverTypePanel.java @@ -0,0 +1,71 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.SolverType; +import eu.engys.core.project.state.State; +import eu.engys.util.ui.ChooserPanel; + +public class SolverTypePanel extends ChooserPanel { + + public static final String SOLVER_TYPE = "Solver Type"; + + public SolverTypePanel() { + super(SOLVER_TYPE, false); + addChoice(SolutionState.SEGREGATED); + addChoice(SolutionState.COUPLED); + getButton(SolutionState.COUPLED).setEnabled(false); + } + + public void updateFromState(State state) { + if (state.getSolverType().isSegregated()) { + select(SolutionState.SEGREGATED); + } else if (state.getSolverType().isCoupled()) { + select(SolutionState.COUPLED); + } else { + selectNone(); + } + } + + public SolverType getSolverType() { + String selectedState = getSelectedState(); + if (selectedState.equals(SolutionState.SEGREGATED)) + return SolverType.SEGREGATED; + if (selectedState.equals(SolutionState.COUPLED)) + return SolverType.COUPLED; + return SolverType.NONE; + } + + public boolean isCoupled() { + return getSelectedState().equals(SolutionState.COUPLED); + } + + public boolean isSegregated() { + return getSelectedState().equals(SolutionState.SEGREGATED); + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/TimePanel.java b/src/eu/engys/gui/casesetup/solution/panels/TimePanel.java new file mode 100644 index 0000000..61bc0c7 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/TimePanel.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import static eu.engys.core.project.state.SolutionState.STEADY; +import static eu.engys.core.project.state.SolutionState.TRANSIENT; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.Time; +import eu.engys.util.ui.ChooserPanel; + +public class TimePanel extends ChooserPanel { + + public static final String TIME = "Time"; + + public TimePanel() { + super(TimePanel.TIME); + addChoice(STEADY); + addChoice(TRANSIENT); + } + + public void updateFromState(State state) { + if (state.isSteady()) + select(STEADY); + else if (state.isTransient()) + select(TRANSIENT); + else + selectNone(); + } + + public Time getTime() { + String selectedState = getSelectedState(); + if (selectedState.equals(STEADY)) + return Time.STEADY; + else if (selectedState.equals(TRANSIENT)) + return Time.TRANSIENT; + return Time.NONE; + } + + public boolean isSteady() { + return getSelectedState().equals(STEADY); + } + + public boolean isTransient() { + return getSelectedState().equals(TRANSIENT); + } + +} diff --git a/src/eu/engys/gui/casesetup/solution/panels/TurbulencePanel.java b/src/eu/engys/gui/casesetup/solution/panels/TurbulencePanel.java new file mode 100644 index 0000000..e3cc9c6 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solution/panels/TurbulencePanel.java @@ -0,0 +1,119 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solution.panels; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.util.List; + +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +import eu.engys.core.project.Model; +import eu.engys.core.project.TurbulenceModel; +import eu.engys.core.project.state.Flow; +import eu.engys.core.project.state.Method; +import eu.engys.core.project.state.SolutionState; +import eu.engys.core.project.state.SolverType; +import eu.engys.core.project.state.State; +import eu.engys.util.ui.builder.PanelBuilder; + +public class TurbulencePanel extends JPanel { + + public static final String TURBULENCE_MODEL = "Turbulence Model"; + private JComboBox modelsCombo; + + public TurbulencePanel() { + super(new BorderLayout()); + layoutComponents(); + } + + private void layoutComponents() { + modelsCombo = new JComboBox(); + modelsCombo.setPrototypeDisplayValue(new TurbulenceModel("", "MMMMMMM")); + final ListCellRenderer renderer = modelsCombo.getRenderer(); + modelsCombo.setRenderer(new ListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, TurbulenceModel value, int index, boolean isSelected, boolean cellHasFocus) { + Component c = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (c instanceof JLabel && value instanceof TurbulenceModel) { + TurbulenceModel model = (TurbulenceModel) value; + ((JLabel) c).setText(model.getDescription()); + } + return c; + } + }); + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(TurbulencePanel.TURBULENCE_MODEL, modelsCombo); + add(builder.margins(.5, 0, .5, 0).getPanel(), BorderLayout.CENTER); + } + + public TurbulenceModel getSelectedTurbulenceModel() { + return (TurbulenceModel) modelsCombo.getSelectedItem(); + } + + public void updateTurbulenceModels(Model model, SolverType solvertype, Method method, Flow flow) { + Object selectedItem = modelsCombo.getSelectedItem(); + + List models = model.getTurbulenceModels().getModelsForState(solvertype, method, flow); + modelsCombo.removeAllItems(); + TurbulenceModel laminar = null; + for (TurbulenceModel turbModel : models) { + modelsCombo.addItem(turbModel); + if (turbModel.getType().isLaminar()) { + laminar = turbModel; + } + } + + if (((DefaultComboBoxModel) modelsCombo.getModel()).getIndexOf(selectedItem) < 0) { + modelsCombo.setSelectedItem(laminar); + } else { + modelsCombo.setSelectedItem(selectedItem); + } + } + + public void updateFromState(Model model, State state) { + updateTurbulenceModels(model, state.getSolverType(), state.getMethod(), state.getFlow()); + + if (state.getTurbulenceModel() != null) { + modelsCombo.setSelectedItem(state.getTurbulenceModel()); + } else { + modelsCombo.setSelectedIndex(-1); + } + } + + public void fixSolutionState(Model model, SolutionState ss) { + SolverType solvertype = ss.isCoupled() ? SolverType.COUPLED : ss.isSegregated() ? SolverType.SEGREGATED : SolverType.NONE; + Method method = ss.isLES() ? Method.LES : ss.isRANS() ? Method.RANS : Method.NONE; + Flow flow = ss.isCompressible() ? Flow.COMPRESSIBLE : ss.isIncompressible() ? Flow.INCOMPRESSIBLE : Flow.NONE; + updateTurbulenceModels(model, solvertype, method, flow); + } + +} diff --git a/src/eu/engys/gui/casesetup/solver/SolverSettingsBuilder.java b/src/eu/engys/gui/casesetup/solver/SolverSettingsBuilder.java new file mode 100644 index 0000000..84ea771 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solver/SolverSettingsBuilder.java @@ -0,0 +1,200 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solver; + +import static eu.engys.core.project.system.ControlDict.MAX_ALPHA_CO_KEY; +import static eu.engys.core.project.system.ControlDict.MAX_CO_KEY; +import static eu.engys.core.project.system.FvSolution.EQUATIONS_KEY; +import static eu.engys.core.project.system.FvSolution.FIELDS_KEY; +import static eu.engys.core.project.system.FvSolution.N_CORRECTORS_KEY; +import static eu.engys.core.project.system.FvSolution.N_NON_ORTHOGONAL_CORRECTORS_KEY; +import static eu.engys.core.project.system.FvSolution.N_OUTER_CORRECTORS_KEY; +import static eu.engys.core.project.system.FvSolution.RELAXATION_FACTORS_KEY; +import static eu.engys.core.project.system.FvSolution.RESIDUAL_CONTROL_KEY; +import static eu.engys.core.project.system.FvSolution.RHO_MAX_KEY; +import static eu.engys.core.project.system.FvSolution.RHO_MIN_KEY; +import static eu.engys.core.project.system.FvSolution.SONIC_KEY; +import static eu.engys.core.project.zero.fields.Fields.FINAL; +import static eu.engys.core.project.zero.fields.Fields.P; +import static eu.engys.core.project.zero.fields.Fields.P_RGH; +import static eu.engys.core.project.zero.fields.Fields.RHO; +import eu.engys.core.dictionary.DefaultElement; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.gui.casesetup.solver.panels.SolverPanel; + +public class SolverSettingsBuilder { + + public static void build(Model model, SolverPanel solverPanel) { + Dictionary fvSolution = model.getProject().getSystemFolder().getFvSolution(); + Dictionary solverDictionary = solverPanel.getSolverDictionary(); + Dictionary relaxationDictionary = solverPanel.getRelaxationFactorsDictionary(); + Dictionary residualDictionary = solverPanel.getResidualControlDictionary(); + + buildSolverSection(fvSolution, solverDictionary, residualDictionary); + buildRelaxationFactorsSection(fvSolution, relaxationDictionary); + + if (model.getState().isHighMach()) { + fvSolution.add(SONIC_KEY, "true"); + } else if (fvSolution.found(SONIC_KEY)) { + fvSolution.remove(SONIC_KEY); + } + } + + private static void buildSolverSection(Dictionary fvSolution, Dictionary solverDictionary, Dictionary residualControl) { + Dictionary solver = fvSolution.subDict(solverDictionary.getName()); // SIMPLE-PIMPLEorPISO + if (solver != null) { + if (solverDictionary.found(N_NON_ORTHOGONAL_CORRECTORS_KEY)) { + solver.add(N_NON_ORTHOGONAL_CORRECTORS_KEY, solverDictionary.lookup(N_NON_ORTHOGONAL_CORRECTORS_KEY)); + } + if (solverDictionary.found(N_CORRECTORS_KEY)) { + solver.add(N_CORRECTORS_KEY, solverDictionary.lookup(N_CORRECTORS_KEY)); + } + if (solverDictionary.found(N_OUTER_CORRECTORS_KEY)) { + solver.add(N_OUTER_CORRECTORS_KEY, solverDictionary.lookup(N_OUTER_CORRECTORS_KEY)); + } + if (solverDictionary.found(RHO_MIN_KEY)) { + solver.add(solverDictionary.lookupScalar(RHO_MIN_KEY)); + } + if (solverDictionary.found(RHO_MAX_KEY)) { + solver.add(solverDictionary.lookupScalar(RHO_MAX_KEY)); + } + if (solverDictionary.found(MAX_CO_KEY)) { + solver.add(MAX_CO_KEY, solverDictionary.lookupString(MAX_CO_KEY)); + } + if (solverDictionary.found(MAX_ALPHA_CO_KEY)) { + solver.add(MAX_ALPHA_CO_KEY, solverDictionary.lookupString(MAX_ALPHA_CO_KEY)); + } + if (residualControl != null) { + if (solver.found(RESIDUAL_CONTROL_KEY)) { + solver.subDict(RESIDUAL_CONTROL_KEY).merge(residualControl); + } else { + solver.add(residualControl); + } + } else { + if (solver.found(RESIDUAL_CONTROL_KEY)) { + solver.remove(RESIDUAL_CONTROL_KEY); + } + } + } + } + + private static void buildRelaxationFactorsSection(Dictionary fvSolution, Dictionary relFactorsDictionaryForGUI) { + Dictionary relaxationFactors = fvSolution.subDict(RELAXATION_FACTORS_KEY); + if (relaxationFactors != null) { + relaxationFactors.merge(encodeRelaxactionFactorsForSaving(relFactorsDictionaryForGUI)); + } + } + + private static Dictionary encodeRelaxactionFactorsForSaving(Dictionary relFactorsDictionaryForGUI) { + Dictionary relFactorsDict = new Dictionary(RELAXATION_FACTORS_KEY); + Dictionary fieldsDict = new Dictionary(FIELDS_KEY); + Dictionary equationsDict = new Dictionary(EQUATIONS_KEY); + relFactorsDict.add(fieldsDict); + relFactorsDict.add(equationsDict); + + for (FieldElement field : relFactorsDictionaryForGUI.getFields()) { + String name = field.getName(); + if (goesToFieldSection(name)) { + fieldsDict.add(name, relFactorsDictionaryForGUI.lookup(name)); + } else { + equationsDict.add(name, relFactorsDictionaryForGUI.lookup(name)); + } + } + return relFactorsDict; + } + + private static boolean goesToFieldSection(String name) { + boolean isP = name.equals(P) || name.equals(P + FINAL); + boolean isPrgh = name.equals(P_RGH) || name.equals(P_RGH + FINAL); + boolean isRho = name.equals(RHO) || name.equals(RHO + FINAL); + return isP || isPrgh || isRho; + } + + /** + * li mette tutti in un unico dictionary + */ + public static Dictionary decodeRelaxationFactorsForGUI(Model model, Dictionary relaxationFactorsDict) { + if (relaxationFactorsDict.found(FIELDS_KEY)) { // formato nuovo + Dictionary fieldsDict = relaxationFactorsDict.subDict(FIELDS_KEY); + Dictionary equationsDict = relaxationFactorsDict.subDict(EQUATIONS_KEY); + Dictionary relFactorsDictionaryForGUI = new Dictionary(RELAXATION_FACTORS_KEY); + for (FieldElement field : fieldsDict.getFields()) { + String name = field.getName(); + relFactorsDictionaryForGUI.add(name, fieldsDict.lookup(name)); + } + for (FieldElement field : equationsDict.getFields()) { + String name = field.getName(); + relFactorsDictionaryForGUI.add(name, equationsDict.lookup(name)); + } + fixAlphas(model, relFactorsDictionaryForGUI); + return relFactorsDictionaryForGUI; + } else { // ho il vecchio formato + return new Dictionary(relaxationFactorsDict); + } + } + + private static void fixAlphas(Model model, Dictionary relFactorsDictionaryForGUI) { + for (FieldElement field : relFactorsDictionaryForGUI.getFields()) { + String name = field.getName(); + if (model.getState().getMultiphaseModel().isMultiphase()) { + if (model.getFields().containsKey(Fields.ALPHA_1)) { + fixAlphasForVOF(model, relFactorsDictionaryForGUI, name); + } else { + fixAlphasForEuler(model, relFactorsDictionaryForGUI, name); + } + } + + } + } + + private static void fixAlphasForVOF(Model model, Dictionary relFactorsDictionaryForGUI, String name) { + if (name.equals("\"" + Fields.ALPHA + ".*\"")) { + DefaultElement alpha = relFactorsDictionaryForGUI.remove(name); + alpha.setName(Fields.ALPHA_1); + relFactorsDictionaryForGUI.add(alpha); + } else if (name.equals("\"" + Fields.ALPHA + ".*Final\"")) { + DefaultElement alpha = relFactorsDictionaryForGUI.remove(name); + alpha.setName(Fields.ALPHA_1 + "Final"); + relFactorsDictionaryForGUI.add(alpha); + } + } + + private static void fixAlphasForEuler(Model model, Dictionary relFactorsDictionaryForGUI, String name) { + if (name.equals("\"" + Fields.ALPHA + ".*\"")) { + DefaultElement alpha = relFactorsDictionaryForGUI.remove(name); + alpha.setName(Fields.ALPHA + "." + model.getMaterials().getFirstMaterialName()); + relFactorsDictionaryForGUI.add(alpha); + } else if (name.equals("\"" + Fields.ALPHA + ".*Final\"")) { + DefaultElement alpha = relFactorsDictionaryForGUI.remove(name); + alpha.setName(Fields.ALPHA + "." + model.getMaterials().getFirstMaterialName() + "Final"); + relFactorsDictionaryForGUI.add(alpha); + } + } + +} diff --git a/src/eu/engys/gui/casesetup/solver/SolverSettingsPanel.java b/src/eu/engys/gui/casesetup/solver/SolverSettingsPanel.java new file mode 100644 index 0000000..a1c51b1 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solver/SolverSettingsPanel.java @@ -0,0 +1,357 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solver; + +import static eu.engys.core.project.state.SolverFamily.CENTRAL; +import static eu.engys.core.project.state.SolverFamily.COUPLED; +import static eu.engys.core.project.state.SolverFamily.PIMPLE; +import static eu.engys.core.project.state.SolverFamily.PISO; +import static eu.engys.core.project.state.SolverFamily.SIMPLE; +import static eu.engys.core.project.system.FvSchemes.FV_SCHEMES; +import static eu.engys.core.project.system.FvSolution.FV_SOLUTION; +import static eu.engys.core.project.system.SystemFolder.SYSTEM; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.SolverFamily; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.Table15; +import eu.engys.core.project.system.SystemFolder; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.gui.casesetup.solver.panels.CentralSettingsPanel; +import eu.engys.gui.casesetup.solver.panels.CoupledSettingsPanel; +import eu.engys.gui.casesetup.solver.panels.PimpleSettingsPanel; +import eu.engys.gui.casesetup.solver.panels.PisoSettingsPanel; +import eu.engys.gui.casesetup.solver.panels.SimpleSettingsPanel; +import eu.engys.gui.casesetup.solver.panels.SolverPanel; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; + +public class SolverSettingsPanel extends DefaultGUIPanel { + + private static final String EMPTY = "EMPTY"; + private static final String STATE_CHANGED_WARNING = "Solution state has been changed.\nAll fields default settings are going to be reset now.\nContinue?"; + + public static final String SOLVER_SETTINGS = "Solver Settings"; + public static final String SOLUTION_ALGORITHM_LABEL = "Solution Algorithm"; + + private JComboBox algorithmCombo; + private ActionListener algorithmActionListener; + + private Map solverPanelMap = new LinkedHashMap<>(); + private Table15 solversTable; + private Set modules; + + @Inject + public SolverSettingsPanel(Model model, Table15 solversTable, Set modules) { + super(SOLVER_SETTINGS, model); + this.solversTable = solversTable; + this.modules = modules; + } + + @Override + protected JComponent layoutComponents() { + solverPanelMap.put(SIMPLE, new SimpleSettingsPanel()); + solverPanelMap.put(PIMPLE, new PimpleSettingsPanel()); + solverPanelMap.put(PISO, new PisoSettingsPanel()); + solverPanelMap.put(CENTRAL, new CentralSettingsPanel()); + solverPanelMap.put(COUPLED, new CoupledSettingsPanel()); + + final CardLayout cardLayout = new CardLayout(); + final JPanel cardLayoutPanel = new JPanel(cardLayout); + cardLayoutPanel.add(new JLabel(""), EMPTY); + cardLayoutPanel.setOpaque(false); + + algorithmCombo = createAlgorithmsCombo(cardLayout, cardLayoutPanel); + algorithmActionListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionevent) { + SolverFamily selectedType = (SolverFamily) algorithmCombo.getSelectedItem(); + if (selectedType != null) { + cardLayout.show(cardLayoutPanel, selectedType.getKey()); + fixPIMPLE_PISOSolver(model); + fixPIMPLE_CENTRALSolver(model); + solverPanelMap.get(selectedType).load(model); + } else { + cardLayout.show(cardLayoutPanel, EMPTY); + } + } + }; + algorithmCombo.addActionListener(algorithmActionListener); + + PanelBuilder comboBuilder = new PanelBuilder(); + comboBuilder.addComponent(SOLUTION_ALGORITHM_LABEL, algorithmCombo); + + PanelBuilder cardBuilder = new PanelBuilder(); + cardBuilder.addComponent(cardLayoutPanel); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(comboBuilder.margins(0, 0, 1, 0).getPanel(), BorderLayout.NORTH); + panel.add(cardBuilder.removeMargins().getPanel(), BorderLayout.CENTER); + return panel; + } + + private JComboBox createAlgorithmsCombo(final CardLayout cardLayout, final JPanel cardLayoutPanel) { + JComboBox combo = new JComboBox(); + combo.setPrototypeDisplayValue(SolverFamily.CENTRAL); + final ListCellRenderer renderer = combo.getRenderer(); + combo.setRenderer(new ListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, SolverFamily value, int index, boolean isSelected, boolean cellHasFocus) { + Component c = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (c instanceof JLabel && value instanceof SolverFamily) { + SolverFamily model = (SolverFamily) value; + ((JLabel) c).setText(model.getKey()); + } + return c; + } + }); + + combo.setEnabled(false); + for (SolverFamily solver : solverPanelMap.keySet()) { + cardLayoutPanel.add(solverPanelMap.get(solver).getPanel(), solver.getKey()); + } + combo.setSelectedIndex(-1); + return combo; + } + + @Override + public void stateChanged() { + loadLater(); + } + + @Override + public void materialsChanged() { + loadLater(); + } + + @Override + public void fieldsChanged() { + loadLater(); + } + + private void loadLater() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + load(); + } + }); + } + + @Override + public void load() { + if (model.hasProject()) { + Set solverFamilies = new LinkedHashSet<>(); + solversTable.updateSolverFamilies(model.getState(), solverFamilies); + ModulesUtil.updateSolverFamilies(modules, model.getState(), solverFamilies); + + loadSolverPanels(model, solverFamilies); + populateCombo(solverFamilies); + fixComboSelection(); + } + } + + private void loadSolverPanels(Model model, Set solverFamiliesForState) { + Dictionary fvSolution = model.getProject().getSystemFolder().getFvSolution(); + if (fvSolution != null) { + leaveOneSolverDictionaryOnFvSolution(fvSolution); + for (SolverFamily family : solverFamiliesForState) { + solverPanelMap.get(family).load(model); + } + } + } + + private void leaveOneSolverDictionaryOnFvSolution(Dictionary fvSolution) { + if (fvSolution.found(SolverFamily.SIMPLE.getKey())) { + if (fvSolution.found(SolverFamily.PIMPLE.getKey()) || fvSolution.found(SolverFamily.PISO.getKey()) || fvSolution.found(SolverFamily.CENTRAL.getKey())) { + fvSolution.remove(SolverFamily.SIMPLE.getKey()); + } + } + } + + private void populateCombo(Set solverFamiliesForState) { + algorithmCombo.removeAllItems(); + algorithmCombo.removeActionListener(algorithmActionListener); + for (SolverFamily algo : solverFamiliesForState) { + algorithmCombo.addItem(algo); + } + algorithmCombo.addActionListener(algorithmActionListener); + } + + private void fixComboSelection() { + algorithmCombo.setEnabled(true); + SolverFamily solverFamily = model.getState().getSolverFamily(); + if (solverFamily.isNone() || algorithmCombo.getItemCount() == 0) { + algorithmCombo.setSelectedIndex(-1); + algorithmCombo.setEnabled(false); + } else { + algorithmCombo.setEnabled(true); + boolean itemNotInComboBox = ((DefaultComboBoxModel) algorithmCombo.getModel()).getIndexOf(solverFamily) == -1; + if (itemNotInComboBox) { + algorithmCombo.setSelectedIndex(0); + } else { + algorithmCombo.setSelectedItem(solverFamily); + } + if (algorithmCombo.getItemCount() < 2) { + algorithmCombo.setEnabled(false); + } + } + } + + @Override + public boolean canStop() { + if (stateHasChanged()) { + if (JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), STATE_CHANGED_WARNING, "State Changed", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION) { + return true; + } else { + return false; + } + } + return true; + } + + @Override + public void save() { + fixPIMPLE_PISOSolver(model); + fixPIMPLE_CENTRALSolver(model); + if (algorithmCombo.getSelectedIndex() != -1) { + SolverPanel selectedSolverPanel = solverPanelMap.get(algorithmCombo.getSelectedItem()); + SolverSettingsBuilder.build(model, selectedSolverPanel); + } + } + + private boolean stateHasChanged() { + State state = model.getState(); + SolverFamily family = state.getSolverFamily(); + if (state.isTransient() && state.isIncompressible()) { + return family.isPiso() && isPIMPLE() || family.isPimple() && isPISO(); + } + if (state.isTransient() && state.isCompressible() && state.isHighMach()) { + return family.isCentral() && isPIMPLE() || family.isPimple() && isCENTRAL(); + } + return false; + } + + private boolean isCENTRAL() { + SolverFamily selectedItem = (SolverFamily) algorithmCombo.getSelectedItem(); + return selectedItem.isCentral(); + } + + private boolean isPISO() { + SolverFamily selectedItem = (SolverFamily) algorithmCombo.getSelectedItem(); + return selectedItem.isPiso(); + } + + private boolean isPIMPLE() { + SolverFamily selectedItem = (SolverFamily) algorithmCombo.getSelectedItem(); + return selectedItem.isPimple(); + } + + private void fixPIMPLE_PISOSolver(Model model) { + State state = model.getState(); + if (state.isTransient() && state.isIncompressible()) { + SystemFolder systemFolder = model.getProject().getSystemFolder(); + Dictionary fvSolution = systemFolder.getFvSolution(); + + Dictionary stateData = model.getDefaults().getDefaultStateData(); + Dictionary pisoSolution = stateData.subDict("pisoFoamRAS").subDict(SYSTEM).subDict(FV_SOLUTION); + Dictionary pimpleSolution = stateData.subDict("pimpleFoamRAS").subDict(SYSTEM).subDict(FV_SOLUTION); + + if (isPISO() && fvSolution.found(SolverFamily.PIMPLE.getKey())) { + systemFolder.setFvSolution(pisoSolution); + state.setSolverFamily(SolverFamily.PISO); + solversTable.updateSolver(state); + ModulesUtil.updateSolver(modules, state); + model.solverChanged(); + } else if (isPIMPLE() && fvSolution.found(SolverFamily.PISO.getKey())) { + systemFolder.setFvSolution(pimpleSolution); + state.setSolverFamily(SolverFamily.PIMPLE); + solversTable.updateSolver(state); + ModulesUtil.updateSolver(modules, state); + model.solverChanged(); + } + } + } + + private void fixPIMPLE_CENTRALSolver(Model model) { + State state = model.getState(); + if (state.isTransient() && state.isCompressible() && state.isHighMach()) { + SystemFolder systemFolder = model.getProject().getSystemFolder(); + if (isCENTRAL() && state.getSolverFamily().isPimple()) { + state.setSolverFamily(SolverFamily.CENTRAL); + solversTable.updateSolver(state); + ModulesUtil.updateSolver(modules, state); + + Dictionary stateData = model.getDefaults().getDefaultsFor(state); + Dictionary solutionDict = stateData.subDict(SYSTEM).subDict(FV_SOLUTION); + Dictionary schemesDict = stateData.subDict(SYSTEM).subDict(FV_SCHEMES); + + systemFolder.setFvSolution(solutionDict); + systemFolder.setFvSchemes(schemesDict); + + model.solverChanged(); + } else if (isPIMPLE() && state.getSolverFamily().isCentral()) { + state.setSolverFamily(SolverFamily.PIMPLE); + solversTable.updateSolver(state); + ModulesUtil.updateSolver(modules, state); + + Dictionary stateData = model.getDefaults().getDefaultsFor(state); + Dictionary solutionDict = stateData.subDict(SYSTEM).subDict(FV_SOLUTION); + Dictionary schemesDict = stateData.subDict(SYSTEM).subDict(FV_SCHEMES); + + systemFolder.setFvSolution(solutionDict); + systemFolder.setFvSchemes(schemesDict); + + model.solverChanged(); + } + } + } + +} diff --git a/src/eu/engys/gui/casesetup/solver/panels/CentralSettingsPanel.java b/src/eu/engys/gui/casesetup/solver/panels/CentralSettingsPanel.java new file mode 100644 index 0000000..629907c --- /dev/null +++ b/src/eu/engys/gui/casesetup/solver/panels/CentralSettingsPanel.java @@ -0,0 +1,76 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.solver.panels; + +import static eu.engys.core.project.system.FvSolution.RELAXATION_FACTORS_KEY; +import static eu.engys.core.project.system.FvSolution.RESIDUAL_CONTROL_KEY; + +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.SolverFamily; + +public class CentralSettingsPanel implements SolverPanel { + + private DictionaryModel centralDictModel; + + public CentralSettingsPanel() { + centralDictModel = new DictionaryModel(new Dictionary(getKey())); + } + + @Override + public String getKey() { + return SolverFamily.CENTRAL.getKey(); + } + + @Override + public JPanel getPanel() { + return new JPanel(); + } + + @Override + public Dictionary getSolverDictionary() { + return centralDictModel.getDictionary(); + } + + @Override + public Dictionary getRelaxationFactorsDictionary() { + return new Dictionary(RELAXATION_FACTORS_KEY); + } + + @Override + public Dictionary getResidualControlDictionary() { + return new Dictionary(RESIDUAL_CONTROL_KEY); + } + + @Override + public void load(Model model) { + } + +} diff --git a/src/eu/engys/gui/casesetup/solver/panels/CoupledSettingsPanel.java b/src/eu/engys/gui/casesetup/solver/panels/CoupledSettingsPanel.java new file mode 100644 index 0000000..05464de --- /dev/null +++ b/src/eu/engys/gui/casesetup/solver/panels/CoupledSettingsPanel.java @@ -0,0 +1,74 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solver.panels; + +import static eu.engys.core.project.system.FvSolution.RELAXATION_FACTORS_KEY; + +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.SolverFamily; + +public class CoupledSettingsPanel implements SolverPanel { + + private DictionaryModel coupledDictModel; + + public CoupledSettingsPanel() { + coupledDictModel = new DictionaryModel(new Dictionary(getKey())); + } + + @Override + public String getKey() { + return SolverFamily.COUPLED.getKey(); + } + + @Override + public JPanel getPanel() { + return new JPanel(); + } + + @Override + public Dictionary getSolverDictionary() { + return coupledDictModel.getDictionary(); + } + + @Override + public Dictionary getRelaxationFactorsDictionary() { + return new Dictionary(RELAXATION_FACTORS_KEY); + } + + @Override + public Dictionary getResidualControlDictionary() { + return null; + } + + @Override + public void load(Model model) { + } + +} diff --git a/src/eu/engys/gui/casesetup/solver/panels/PimpleSettingsPanel.java b/src/eu/engys/gui/casesetup/solver/panels/PimpleSettingsPanel.java new file mode 100644 index 0000000..b051f8b --- /dev/null +++ b/src/eu/engys/gui/casesetup/solver/panels/PimpleSettingsPanel.java @@ -0,0 +1,238 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solver.panels; + +import static eu.engys.core.project.system.ControlDict.MAX_ALPHA_CO_KEY; +import static eu.engys.core.project.system.ControlDict.MAX_CO_KEY; +import static eu.engys.core.project.system.FvSolution.FV_SOLUTION; +import static eu.engys.core.project.system.FvSolution.N_CORRECTORS_KEY; +import static eu.engys.core.project.system.FvSolution.N_NON_ORTHOGONAL_CORRECTORS_KEY; +import static eu.engys.core.project.system.FvSolution.N_OUTER_CORRECTORS_KEY; +import static eu.engys.core.project.system.FvSolution.RELAXATION_FACTORS_KEY; +import static eu.engys.core.project.system.FvSolution.REL_TOLERANCE_KEY; +import static eu.engys.core.project.system.FvSolution.RESIDUAL_CONTROL_KEY; +import static eu.engys.core.project.system.FvSolution.RHO_MAX_KEY; +import static eu.engys.core.project.system.FvSolution.RHO_MIN_KEY; +import static eu.engys.core.project.system.FvSolution.TOLERANCE_KEY; +import static eu.engys.core.project.system.SystemFolder.SYSTEM; +import static eu.engys.core.project.zero.fields.Fields.FINAL; +import static eu.engys.core.project.zero.fields.Fields.P; +import static eu.engys.core.project.zero.fields.Fields.P_RGH; +import static eu.engys.core.project.zero.fields.Fields.RHO; + +import java.awt.BorderLayout; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.SolverFamily; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.gui.casesetup.solver.SolverSettingsBuilder; +import eu.engys.util.DimensionalUnits; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; + +public class PimpleSettingsPanel implements SolverPanel { + + public static final String COURANT_NUMBER_LABEL = "Courant Number"; + public static final String MAX_COURANT_ALPHA_LABEL = "Max Courant Alpha"; + public static final String MAX_COURANT_NUMBER_LABEL = "Max Courant Number"; + + private DictionaryModel pimpleDictModel; + + private DictionaryModel relaxationFactorsDictModel; + private Map pimpleResidualMap; + + private JPanel relaxationFactorsPanel; + private JPanel residualControlPanel; + + private PanelBuilder builder; + + private JComponent pimpleRhoMin; + private JComponent pimpleRhoMax; + + private JComponent maxCourantNumber; + private JComponent maxAlphaCourant; + + public PimpleSettingsPanel() { + relaxationFactorsDictModel = new DictionaryModel(new Dictionary(RELAXATION_FACTORS_KEY)); + pimpleResidualMap = new HashMap<>(); + + pimpleDictModel = new DictionaryModel(new Dictionary(getKey())); + + builder = new PanelBuilder(); + builder.addComponent(OUTER_CORRECTORS_LABEL, pimpleDictModel.bindIntegerPositive(N_OUTER_CORRECTORS_KEY)); + builder.addComponent(CORRECTORS_LABEL, pimpleDictModel.bindIntegerPositive(N_CORRECTORS_KEY)); + builder.addComponent(NON_ORTHOGONAL_CORRECTORS_LABEL, pimpleDictModel.bindIntegerPositive(N_NON_ORTHOGONAL_CORRECTORS_KEY)); + pimpleRhoMin = builder.addComponent(RHO_MIN_LABEL, pimpleDictModel.bindDimensionedDouble(RHO_MIN_KEY, DimensionalUnits.KG_M3)); + pimpleRhoMax = builder.addComponent(RHO_MAX_LABEL, pimpleDictModel.bindDimensionedDouble(RHO_MAX_KEY, DimensionalUnits.KG_M3)); + pimpleRhoMin.setEnabled(false); + pimpleRhoMax.setEnabled(false); + + PanelBuilder courantBuilder = new PanelBuilder(); + maxCourantNumber = courantBuilder.addComponent(MAX_COURANT_NUMBER_LABEL, pimpleDictModel.bindDouble(MAX_CO_KEY)); + maxAlphaCourant = courantBuilder.addComponent(MAX_COURANT_ALPHA_LABEL, pimpleDictModel.bindDouble(MAX_ALPHA_CO_KEY)); + maxCourantNumber.setEnabled(false); + maxAlphaCourant.setEnabled(false); + courantBuilder.getPanel().setBorder(BorderFactory.createTitledBorder(COURANT_NUMBER_LABEL)); + courantBuilder.getPanel().setName(COURANT_NUMBER_LABEL); + builder.addFill(courantBuilder.getPanel()); + + residualControlPanel = new JPanel(new BorderLayout()); + residualControlPanel.setOpaque(false); + residualControlPanel.setBorder(BorderFactory.createTitledBorder(RESIDUAL_CONTROL_LABEL)); + residualControlPanel.setName(RESIDUAL_CONTROL_LABEL); + builder.addFill(residualControlPanel); + + relaxationFactorsPanel = new JPanel(new BorderLayout()); + relaxationFactorsPanel.setOpaque(false); + relaxationFactorsPanel.setBorder(BorderFactory.createTitledBorder(RELAXATION_FACTORS_LABEL)); + relaxationFactorsPanel.setName(RELAXATION_FACTORS_LABEL); + builder.addFill(relaxationFactorsPanel); + } + + @Override + public String getKey() { + return SolverFamily.PIMPLE.getKey(); + } + + @Override + public Dictionary getSolverDictionary() { + return pimpleDictModel.getDictionary(); + } + + @Override + public Dictionary getRelaxationFactorsDictionary() { + return relaxationFactorsDictModel.getDictionary(); + } + + @Override + public Dictionary getResidualControlDictionary() { + return getPimpleResidualDictionary(); + } + + @Override + public JPanel getPanel() { + return builder.removeMargins().getPanel(); + } + + @Override + public void load(Model model) { + residualControlPanel.removeAll(); + DictionaryPanelBuilder residualBuilder = new DictionaryPanelBuilder(); + residualControlPanel.add(residualBuilder.getPanel()); + + relaxationFactorsPanel.removeAll(); + DictionaryPanelBuilder relaxationBuilder = new DictionaryPanelBuilder(); + relaxationFactorsPanel.add(relaxationBuilder.getPanel()); + + pimpleResidualMap.clear(); + + Fields fields = model.getFields(); + + Dictionary fvSolution = model.getProject().getSystemFolder().getFvSolution(); + if (fvSolution != null) { + Dictionary PIMPLEDict = fvSolution.subDict(getKey()); + pimpleDictModel.setDictionary(PIMPLEDict != null ? new Dictionary(PIMPLEDict) : getDictionaryFromDefaults(model)); + + residualBuilder.addComponent("", new JLabel(RELATIVE_TOLERANCE_LABEL), new JLabel(TOLERANCE_LABEL)); + for (Field field : fields.orderedFieldsExcludingPassiveScalars()) { + String fieldName = field.getName(); + DictionaryModel fieldModel = new DictionaryModel(new Dictionary(fieldName)); + DoubleField relativeTolerance = fieldModel.bindDouble(REL_TOLERANCE_KEY, 0.0, 1.0); + DoubleField tolerance = fieldModel.bindDouble(TOLERANCE_KEY, 0.0, 1.0); + pimpleResidualMap.put(fieldName, fieldModel); + residualBuilder.addComponent(fieldName, relativeTolerance, tolerance); + } + for (Field field : fields.orderedFields()) { + String fieldName = field.getName(); + + DoubleField normalField = relaxationFactorsDictModel.bindDouble(fieldName, 0.0, 1.0); + normalField.setName(fieldName); + + JComponent finalField = null; + JLabel finalLabel = null; + if (P_RGH.equals(fieldName) || P.equals(fieldName) || RHO.equals(fieldName)) { + finalLabel = new JLabel(""); + finalField = new JLabel(""); + } else { + finalLabel = new JLabel(fieldName + FINAL); + finalField = relaxationFactorsDictModel.bindDouble(fieldName + FINAL, 0.0, 1.0); + } + finalField.setName(fieldName + FINAL); + relaxationBuilder.addComponent(new JLabel(fieldName), normalField, finalLabel, finalField); + } + + if (PIMPLEDict != null && PIMPLEDict.found(RESIDUAL_CONTROL_KEY)) { + Dictionary residualControlDict = PIMPLEDict.subDict(RESIDUAL_CONTROL_KEY); + for (String key : pimpleResidualMap.keySet()) { + pimpleResidualMap.get(key).setDictionary(residualControlDict.subDict(key)); + } + } + + if (fvSolution.found(RELAXATION_FACTORS_KEY)) { + Dictionary relaxationFactors = fvSolution.subDict(RELAXATION_FACTORS_KEY); + Dictionary relaxationFactorsForGUI = SolverSettingsBuilder.decodeRelaxationFactorsForGUI(model, relaxationFactors); + relaxationFactorsDictModel.setDictionary(relaxationFactorsForGUI); + } + + } + updatePanel(model); + } + + private Dictionary getDictionaryFromDefaults(Model model) { + Dictionary stateData = model.getDefaults().getDefaultStateData(); + Dictionary pimpleSolution = stateData.subDict("pimpleFoamRAS").subDict(SYSTEM).subDict(FV_SOLUTION); + return pimpleSolution.subDict(getKey()); + } + + private void updatePanel(Model model) { + boolean isLTS = model.getState().isSteady() && model.getState().getMultiphaseModel().isMultiphase(); + maxAlphaCourant.setEnabled(isLTS); + maxCourantNumber.setEnabled(isLTS); + + pimpleRhoMin.setEnabled(model.getState().isCompressible()); + pimpleRhoMax.setEnabled(model.getState().isCompressible()); + } + + private Dictionary getPimpleResidualDictionary() { + Dictionary dictionary = new Dictionary(RESIDUAL_CONTROL_KEY); + for (DictionaryModel dm : pimpleResidualMap.values()) { + dictionary.add(dm.getDictionary()); + } + return dictionary; + } + +} diff --git a/src/eu/engys/gui/casesetup/solver/panels/PisoSettingsPanel.java b/src/eu/engys/gui/casesetup/solver/panels/PisoSettingsPanel.java new file mode 100644 index 0000000..17c265a --- /dev/null +++ b/src/eu/engys/gui/casesetup/solver/panels/PisoSettingsPanel.java @@ -0,0 +1,154 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.solver.panels; + +import static eu.engys.core.project.system.FvSolution.FV_SOLUTION; +import static eu.engys.core.project.system.FvSolution.N_CORRECTORS_KEY; +import static eu.engys.core.project.system.FvSolution.N_NON_ORTHOGONAL_CORRECTORS_KEY; +import static eu.engys.core.project.system.FvSolution.RELAXATION_FACTORS_KEY; +import static eu.engys.core.project.system.FvSolution.RESIDUAL_CONTROL_KEY; +import static eu.engys.core.project.system.FvSolution.RHO_MAX_KEY; +import static eu.engys.core.project.system.FvSolution.RHO_MIN_KEY; +import static eu.engys.core.project.system.SystemFolder.SYSTEM; + +import java.awt.BorderLayout; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.SolverFamily; +import eu.engys.core.project.state.State; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.gui.casesetup.solver.SolverSettingsBuilder; +import eu.engys.util.DimensionalUnits; +import eu.engys.util.ui.textfields.DoubleField; + +public class PisoSettingsPanel implements SolverPanel { + + private DictionaryModel pisoDictModel; + + private DictionaryModel relaxationFactorsDictModel; + private JPanel relaxationFactorsPanel; + + private DictionaryPanelBuilder builder; + + private JComponent pisoRhoMin; + private JComponent pisoRhoMax; + + public PisoSettingsPanel() { + relaxationFactorsDictModel = new DictionaryModel(new Dictionary(RELAXATION_FACTORS_KEY)); + + pisoDictModel = new DictionaryModel(new Dictionary(getKey())); + + builder = new DictionaryPanelBuilder(); + builder.addComponent(CORRECTORS_LABEL, pisoDictModel.bindIntegerPositive(N_CORRECTORS_KEY)); + builder.addComponent(NON_ORTHOGONAL_CORRECTORS_LABEL, pisoDictModel.bindIntegerPositive(N_NON_ORTHOGONAL_CORRECTORS_KEY)); + pisoRhoMin = builder.addComponent(RHO_MIN_LABEL, pisoDictModel.bindDimensionedDouble(RHO_MIN_KEY, DimensionalUnits.KG_M3)); + pisoRhoMax = builder.addComponent(RHO_MAX_LABEL, pisoDictModel.bindDimensionedDouble(RHO_MAX_KEY, DimensionalUnits.KG_M3)); + + relaxationFactorsPanel = new JPanel(new BorderLayout()); + relaxationFactorsPanel.setOpaque(false); + relaxationFactorsPanel.setBorder(BorderFactory.createTitledBorder(RELAXATION_FACTORS_LABEL)); + relaxationFactorsPanel.setName(RELAXATION_FACTORS_LABEL); + builder.addFill(relaxationFactorsPanel); + } + + @Override + public String getKey() { + return SolverFamily.PISO.getKey(); + } + + @Override + public JPanel getPanel() { + return builder.removeMargins().getPanel(); + } + + @Override + public Dictionary getSolverDictionary() { + return pisoDictModel.getDictionary(); + } + + @Override + public Dictionary getRelaxationFactorsDictionary() { + return relaxationFactorsDictModel.getDictionary(); + } + + @Override + public Dictionary getResidualControlDictionary() { + return new Dictionary(RESIDUAL_CONTROL_KEY); + } + + @Override + public void load(Model model) { + relaxationFactorsPanel.removeAll(); + DictionaryPanelBuilder relaxationBuilder = new DictionaryPanelBuilder(); + relaxationFactorsPanel.add(relaxationBuilder.getPanel()); + + Fields fields = model.getFields(); + + Dictionary fvSolution = model.getProject().getSystemFolder().getFvSolution(); + if (fvSolution != null) { + Dictionary PISODict = fvSolution.subDict(getKey()); + pisoDictModel.setDictionary(PISODict != null ? new Dictionary(PISODict) : getDictionaryFromDefaults(model)); + + for (Field field : fields.orderedFields()) { + String fieldName = field.getName(); + DoubleField textField = relaxationFactorsDictModel.bindDouble(fieldName, 0.0, 1.0); + textField.setEnabled(false); + relaxationBuilder.addComponent(fieldName, textField); + } + + if (fvSolution.found(RELAXATION_FACTORS_KEY)) { + Dictionary relaxationFactors = fvSolution.subDict(RELAXATION_FACTORS_KEY); + Dictionary relaxationFactorsForGUI = SolverSettingsBuilder.decodeRelaxationFactorsForGUI(model, relaxationFactors); + relaxationFactorsDictModel.setDictionary(relaxationFactorsForGUI); + } + + updatePanel(model); + } + } + + private Dictionary getDictionaryFromDefaults(Model model) { + Dictionary stateData = model.getDefaults().getDefaultStateData(); + Dictionary pisoSolution = stateData.subDict("pisoFoamRAS").subDict(SYSTEM).subDict(FV_SOLUTION); + return pisoSolution.subDict(getKey()); + } + + protected void updatePanel(Model model) { + State state = model.getState(); + boolean isCompressible = state.isCompressible(); + pisoRhoMin.setEnabled(isCompressible); + pisoRhoMax.setEnabled(isCompressible); + } + +} diff --git a/src/eu/engys/gui/casesetup/solver/panels/SimpleSettingsPanel.java b/src/eu/engys/gui/casesetup/solver/panels/SimpleSettingsPanel.java new file mode 100644 index 0000000..b60cb61 --- /dev/null +++ b/src/eu/engys/gui/casesetup/solver/panels/SimpleSettingsPanel.java @@ -0,0 +1,147 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.casesetup.solver.panels; + +import static eu.engys.core.project.system.FvSolution.N_NON_ORTHOGONAL_CORRECTORS_KEY; +import static eu.engys.core.project.system.FvSolution.RELAXATION_FACTORS_KEY; +import static eu.engys.core.project.system.FvSolution.RESIDUAL_CONTROL_KEY; + +import java.awt.BorderLayout; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.SolverFamily; +import eu.engys.core.project.zero.fields.Field; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.gui.casesetup.solver.SolverSettingsBuilder; + +public class SimpleSettingsPanel implements SolverPanel { + + private DictionaryPanelBuilder builder; + + private DictionaryModel simpleDictModel; + private DictionaryModel relaxationFactorsDictModel; + private DictionaryModel residualControlDict; + + private JPanel relaxationFactorsPanel; + private JPanel residualControlPanel; + + public SimpleSettingsPanel() { + relaxationFactorsDictModel = new DictionaryModel(new Dictionary(RELAXATION_FACTORS_KEY)); + residualControlDict = new DictionaryModel(new Dictionary(RESIDUAL_CONTROL_KEY)); + + simpleDictModel = new DictionaryModel(new Dictionary(getKey())); + + builder = new DictionaryPanelBuilder(); + builder.addComponent(NON_ORTHOGONAL_CORRECTORS_LABEL, simpleDictModel.bindIntegerPositive(N_NON_ORTHOGONAL_CORRECTORS_KEY)); + + residualControlPanel = new JPanel(new BorderLayout()); + residualControlPanel.setOpaque(false); + residualControlPanel.setBorder(BorderFactory.createTitledBorder(RESIDUAL_CONTROL_LABEL)); + residualControlPanel.setName(RESIDUAL_CONTROL_LABEL); + builder.addFill(residualControlPanel); + + relaxationFactorsPanel = new JPanel(new BorderLayout()); + relaxationFactorsPanel.setOpaque(false); + relaxationFactorsPanel.setBorder(BorderFactory.createTitledBorder(RELAXATION_FACTORS_LABEL)); + relaxationFactorsPanel.setName(RELAXATION_FACTORS_LABEL); + builder.addFill(relaxationFactorsPanel); + } + + @Override + public String getKey() { + return SolverFamily.SIMPLE.getKey(); + } + + @Override + public JPanel getPanel() { + return builder.removeMargins().getPanel(); + } + + @Override + public Dictionary getSolverDictionary() { + return simpleDictModel.getDictionary(); + } + + @Override + public Dictionary getRelaxationFactorsDictionary() { + return relaxationFactorsDictModel.getDictionary(); + } + + @Override + public Dictionary getResidualControlDictionary() { + return residualControlDict.getDictionary(); + } + + @Override + public void load(Model model) { + residualControlPanel.removeAll(); + DictionaryPanelBuilder residualBuilder = new DictionaryPanelBuilder(); + residualControlPanel.add(residualBuilder.getPanel()); + + relaxationFactorsPanel.removeAll(); + DictionaryPanelBuilder relaxationBuilder = new DictionaryPanelBuilder(); + relaxationFactorsPanel.add(relaxationBuilder.getPanel()); + + Fields fields = model.getFields(); + + Dictionary fvSolution = model.getProject().getSystemFolder().getFvSolution(); + + + if (fvSolution != null) { + Dictionary SIMPLEDict = fvSolution.subDict(getKey()); + simpleDictModel.setDictionary(SIMPLEDict != null ? new Dictionary(SIMPLEDict) : new Dictionary(getKey())); + +// System.out.println("SimpleSettingsPanel.load(): " + fields.orderedFieldsExcludingPassiveScalars()); + + for (Field field : fields.orderedFieldsExcludingPassiveScalars()) { + String fieldName = field.getName(); + residualBuilder.addComponent(fieldName, residualControlDict.bindDouble(fieldName, 0.0, 1.0)); + } + + for (Field field : fields.orderedFields()) { + String fieldName = field.getName(); + relaxationBuilder.addComponent(fieldName, relaxationFactorsDictModel.bindDouble(fieldName, 0.0, 1.0)); + } + + if (SIMPLEDict != null && SIMPLEDict.found(RESIDUAL_CONTROL_KEY)) { + residualControlDict.setDictionary(SIMPLEDict.subDict(RESIDUAL_CONTROL_KEY)); + } + if (fvSolution.found(RELAXATION_FACTORS_KEY)) { + Dictionary relaxationFactors = fvSolution.subDict(RELAXATION_FACTORS_KEY); + Dictionary relaxationFactorsForGUI = SolverSettingsBuilder.decodeRelaxationFactorsForGUI(model, relaxationFactors); + relaxationFactorsDictModel.setDictionary(relaxationFactorsForGUI); + } + } + } + +} diff --git a/src/eu/engys/gui/casesetup/solver/panels/SolverPanel.java b/src/eu/engys/gui/casesetup/solver/panels/SolverPanel.java new file mode 100644 index 0000000..950563e --- /dev/null +++ b/src/eu/engys/gui/casesetup/solver/panels/SolverPanel.java @@ -0,0 +1,57 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.casesetup.solver.panels; + +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; + +public interface SolverPanel { + + public static final String OUTER_CORRECTORS_LABEL = "Outer Correctors"; + public static final String CORRECTORS_LABEL = "Correctors"; + public static final String NON_ORTHOGONAL_CORRECTORS_LABEL = "Non-orthogonal Correctors"; + public static final String RHO_MIN_LABEL = "Rho Min"; + public static final String RHO_MAX_LABEL = "Rho Max"; + public static final String RESIDUAL_CONTROL_LABEL = "Residual Control"; + public static final String RELAXATION_FACTORS_LABEL = "Relaxation Factors"; + public static final String RELATIVE_TOLERANCE_LABEL = "Relative Tolerance"; + public static final String TOLERANCE_LABEL = "Tolerance"; + + Dictionary getSolverDictionary(); + + Dictionary getRelaxationFactorsDictionary(); + + Dictionary getResidualControlDictionary(); + + void load(Model model); + + JPanel getPanel(); + + String getKey(); + +} diff --git a/src/eu/engys/gui/custom/CustomFileDialog.java b/src/eu/engys/gui/custom/CustomFileDialog.java new file mode 100644 index 0000000..fa7dbf1 --- /dev/null +++ b/src/eu/engys/gui/custom/CustomFileDialog.java @@ -0,0 +1,501 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.custom; + +import static eu.engys.core.project.constant.ConstantFolder.CONSTANT; +import static eu.engys.core.project.custom.CustomFileType.DICTIONARY; +import static eu.engys.core.project.custom.CustomFileType.DIRECTORY; +import static eu.engys.core.project.custom.CustomFileType.FIELD; +import static eu.engys.core.project.system.SystemFolder.SYSTEM; +import static eu.engys.util.ui.ComponentsFactory.selectField; +import static eu.engys.util.ui.ComponentsFactory.selectFieldWithItemSupport; +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.awt.BorderLayout; +import java.awt.Dialog.ModalityType; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.FileFilter; +import java.util.Arrays; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import eu.engys.core.project.Model; +import eu.engys.core.project.custom.CustomFile; +import eu.engys.core.project.custom.CustomFileType; +import eu.engys.core.project.custom.CustomUtils; +import eu.engys.core.project.system.CaseSetupDict; +import eu.engys.core.project.system.CustomNodeDict; +import eu.engys.core.project.system.RunDict; +import eu.engys.util.ui.JComboBoxWithItemsSupport; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.StringField; +import eu.engys.util.ui.textfields.verifiers.AbstractVerifier; +import eu.engys.util.ui.textfields.verifiers.AbstractVerifier.ValidationStatusListener; + +public class CustomFileDialog { + + public static final String CUSTOM_DIALOG_NAME = "custom.dialog"; + + public static final String TITLE = "New Custom File"; + + public static final String VALUE_LABEL = "Value"; + public static final String NAME_LABEL = "Name"; + public static final String TYPE_LABEL = "Type"; + public static final String PARENT_LABEL = "Parent"; + public static final String DEFAULT_NAME = "newFile"; + public static final String NEW_NAME = "New ..."; + + public static final String CANCEL_LABEL = "Cancel"; + public static final String CREATE_NEW_LABEL = "Create New"; + + private static final String[] VETOED_DICT_LIST = new String[] { RunDict.RUN_DICT, CaseSetupDict.CASE_SETUP_DICT, CustomNodeDict.CUSTOM_NODE_DICT }; + + private JComboBoxWithItemsSupport typeCombo; + private JComboBox parentCombo; + private JComboBox namesCombo; + private StringField nameField; + private JDialog dialog; + private JButton okButton; + private Model model; + + private PropertyChangeListener enableOKButtonListener; + private PropertyChangeListener enableTYPESComboListener; + private PropertyChangeListener updateNamesCombo; + + private static final int LOAD = 0; + private static final int NEW = 1; + private static final int CANCEL = 2; + + public CustomFileDialog(Model model) { + this.model = model; + + dialog = new JDialog(UiUtil.getActiveWindow(), ModalityType.APPLICATION_MODAL); + dialog.setTitle(TITLE); + dialog.setSize(300, 200); + dialog.setLocationRelativeTo(null); + dialog.setName(CUSTOM_DIALOG_NAME); + + PanelBuilder builder = new PanelBuilder(); + namesCombo = createNamesCombo(); + nameField = createNameField(); + parentCombo = createParentCombo(); + typeCombo = createTypeCombo(); + + builder.addComponent(PARENT_LABEL, parentCombo); + builder.addComponent(TYPE_LABEL, typeCombo); + builder.addComponent(NAME_LABEL, namesCombo); + builder.addComponent(VALUE_LABEL, nameField); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(builder.getPanel(), BorderLayout.CENTER); + mainPanel.add(createButtonsPanel(), BorderLayout.SOUTH); + + dialog.add(mainPanel); + dialog.getRootPane().setDefaultButton(okButton); + + enableOKButtonListener = new EnableOkButtonListener(); + enableTYPESComboListener = new EnableTypesComboListener(); + updateNamesCombo = new UpdateNamesCombo(); + } + + private StringField createNameField() { + StringField newFoNameField = stringField(DEFAULT_NAME); + ((AbstractVerifier) newFoNameField.getInputVerifier()).setValidationStatusListener(new ValidationStatusListener() { + @Override + public void validatePassed() { + okButton.setEnabled(true); + } + + @Override + public void validateFailed() { + okButton.setEnabled(false); + } + }); + return newFoNameField; + } + + private JComboBox createNamesCombo() { + JComboBox namesCombo = selectField(); + namesCombo.addPropertyChangeListener(new EnableNameFieldListener()); + return namesCombo; + } + + private JComboBoxWithItemsSupport createTypeCombo() { + JComboBoxWithItemsSupport typeCombo = selectFieldWithItemSupport(CustomFileType.keys(), CustomFileType.labels()); + typeCombo.setSelectedIndex(-1); + typeCombo.addPropertyChangeListener(enableOKButtonListener); + typeCombo.addPropertyChangeListener(updateNamesCombo); + return typeCombo; + } + + private JComboBox createParentCombo() { + JComboBox parentCombo = selectField(); + parentCombo.setSelectedIndex(-1); + parentCombo.addPropertyChangeListener(enableTYPESComboListener); + parentCombo.addPropertyChangeListener(updateNamesCombo); + return parentCombo; + } + + private JPanel createButtonsPanel() { + JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + okButton = new JButton(new AddCustomFile()); + okButton.setEnabled(false); + okButton.setName("ok"); + panel.add(okButton); + + JButton cancelButton = new JButton(new AbstractAction("Cancel") { + + @Override + public void actionPerformed(ActionEvent e) { + resetAndClose(); + } + + }); + cancelButton.setName("cancel"); + panel.add(cancelButton); + return panel; + } + + private void resetAndClose() { + nameField.setText(DEFAULT_NAME); + typeCombo.setSelectedIndex(-1); + disposeDialog(); + } + + private void disposeDialog() { + dialog.setVisible(false); + dialog.dispose(); + dialog = null; + } + + public void show(CustomFile parent) { + removeListeners(); + updateNamesCombo(parent); + updateParentCombo(parent); + fixTypeCombo(parentCombo.getSelectedItem()); + addListeners(); + dialog.setVisible(true); + } + + private void updateParentCombo(CustomFile selected) { + List parentFiles = model.getCustom().getParentFiles(); + for (CustomFile customFile : parentFiles) { + parentCombo.addItem(customFile); + } + parentCombo.setSelectedItem(selected); + } + + private void updateNamesCombo(CustomFile parent) { + namesCombo.removeAllItems(); + namesCombo.addItem(NEW_NAME); + + if (parent != null && typeCombo.getSelectedItem() != null) { + _updateNamesCombo(parent); + } + namesCombo.setSelectedItem(0); + } + + private void _updateNamesCombo(CustomFile parent) { + List children = parent.getChildrenNames(); + File parentFile = CustomUtils.getFiles(model, parent).get(0); + if (parentFile.exists()) { + addNames(children, parentFile); + } + } + + private void addNames(List children, File parentFile) { + if (isTypeSelected(DIRECTORY)) { + addDirectoryNames(children, parentFile); + } else if (isTypeSelected(DICTIONARY)) { + addDictionaryNames(children, parentFile); + } else if (isTypeSelected(FIELD)) { + addFieldsNames(children, parentFile); + } + } + + private void addDictionaryNames(final List children, File parentFile) { + for (File f : parentFile.listFiles(new ValidDictionaryFileFilter(children))) { + namesCombo.addItem(f.getName()); + } + } + + private void addFieldsNames(final List children, File parentFile) { + for (File f : parentFile.listFiles(new ValidFieldFileFilter(children))) { + namesCombo.addItem(f.getName()); + } + } + + private void addDirectoryNames(final List children, File parentFile) { + for (File f : parentFile.listFiles(new ValidDirectoryFileFilter(children))) { + namesCombo.addItem(f.getName()); + } + } + + private boolean isTypeSelected(CustomFileType type) { + return typeCombo.getSelectedItem().equals(type.getKey()); + } + + private boolean isNewFile() { + return namesCombo.getSelectedIndex() == 0; + } + + private void removeListeners() { + typeCombo.removePropertyChangeListener(enableOKButtonListener); + typeCombo.removePropertyChangeListener(updateNamesCombo); + parentCombo.removePropertyChangeListener(enableTYPESComboListener); + parentCombo.removePropertyChangeListener(updateNamesCombo); + } + + private void addListeners() { + typeCombo.addPropertyChangeListener(enableOKButtonListener); + typeCombo.addPropertyChangeListener(updateNamesCombo); + parentCombo.addPropertyChangeListener(enableTYPESComboListener); + parentCombo.addPropertyChangeListener(updateNamesCombo); + } + + private class AddCustomFile extends AbstractAction { + + public AddCustomFile() { + super("OK"); + } + + @Override + public void actionPerformed(ActionEvent e) { + addFile(); + } + + private void addFile() { + String type = typeCombo.getItemAt(typeCombo.getSelectedIndex()); + CustomFile parent = parentCombo.getItemAt(parentCombo.getSelectedIndex()); + + if (parent == null) { + JOptionPane.showMessageDialog(dialog, "Please, specify a parent for the file", "Warning", JOptionPane.WARNING_MESSAGE); + return; + } + + String fileName = getValidName(parent, nameField.getText()); + CustomFileType fileType = CustomFileType.valueOf(type.toUpperCase()); + CustomFile customFile = new CustomFile(parent, fileType, fileName); + + File file = CustomUtils.getFiles(model, customFile).get(0); + boolean exists = file.exists(); + + if (exists && !customFile.getType().isDirectory()) { + if (isNewFile()) { + boolean parallel = model.getProject().isParallel(); + String suffix = (customFile.getType().isField() && parallel) ? "Template" : "from File"; + Object[] options = { "Load " + suffix, CREATE_NEW_LABEL, CANCEL_LABEL }; + String message = customFile.getName() + " already exists, please select an action."; + int retVal = JOptionPane.showOptionDialog(dialog, message, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]); + switch (retVal) { + case CANCEL: + return; + case NEW: + break; + case LOAD: + CustomUtils.loadFromDisk(fileName, customFile, file); + break; + default: + break; + } + } else { + CustomUtils.loadFromDisk(fileName, customFile, file); + } + + } + model.getCustom().add(customFile); + model.customFileChanged(customFile); + resetAndClose(); + } + + private String getValidName(CustomFile parent, String text) { + if (!isValidName(parent, text)) { + return getValidName(parent, text + "_copy"); + } + return text; + } + + private boolean isValidName(CustomFile parent, String text) { + for (CustomFile cf : parent.getChildren()) { + if (cf.getName().equals(text)) { + return false; + } + } + return true; + } + + } + + private class EnableOkButtonListener implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + okButton.setEnabled(evt.getNewValue() != null); + } + } + + } + + private class UpdateNamesCombo implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + updateNamesCombo((CustomFile) parentCombo.getSelectedItem()); + } + } + } + + private class EnableNameFieldListener implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + if (isNewFile()) { + nameField.setText(DEFAULT_NAME); + nameField.setEnabled(true); + } else { + Object selectedItem = namesCombo.getSelectedItem(); + nameField.setText(selectedItem != null ? selectedItem.toString() : DEFAULT_NAME); + nameField.setEnabled(false); + } + } + } + + } + + private class EnableTypesComboListener implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + fixTypeCombo(evt.getNewValue()); + } + } + + } + + public void fixTypeCombo(Object selectedItem) { + if (selectedItem != null) { + switch (selectedItem.toString()) { + case "0": + typeCombo.clearDisabledIndexes(); + if (typeCombo.getSelectedItem() == DICTIONARY.getKey()) { + typeCombo.setSelectedItem(FIELD.getKey()); + } + // typeCombo.addDisabledIndex(directoryIndex); + typeCombo.addDisabledItem(DICTIONARY.getKey()); + break; + case SYSTEM: + case CONSTANT: + default: + typeCombo.clearDisabledIndexes(); + if (typeCombo.getSelectedItem() == FIELD.getKey()) { + typeCombo.setSelectedItem(DICTIONARY.getKey()); + } + typeCombo.addDisabledItem(FIELD.getKey()); + break; + } + } else { + typeCombo.setSelectedIndex(-1); + typeCombo.clearDisabledIndexes(); + } + } + + private class ValidDictionaryFileFilter implements FileFilter { + + private List children; + + public ValidDictionaryFileFilter(List children) { + this.children = children; + } + + @Override + public boolean accept(File pathname) { + boolean isFile = pathname.isFile(); + boolean isVisible = !pathname.isHidden(); + boolean isValidName = !pathname.getName().endsWith("~"); + boolean isNotAlreadyUsed = !children.contains(pathname.getName()); + boolean isNotVetoed = !Arrays.asList(VETOED_DICT_LIST).contains(pathname.getName()); + return isFile && isVisible && isValidName && isNotAlreadyUsed && isNotVetoed; + } + + } + + private class ValidFieldFileFilter implements FileFilter { + + private List children; + + public ValidFieldFileFilter(List children) { + this.children = children; + } + + @Override + public boolean accept(File pathname) { + boolean isFile = pathname.isFile(); + boolean isVisible = !pathname.isHidden(); + boolean isValidName = !pathname.getName().endsWith("~"); + boolean isNotAlreadyUsed = !children.contains(pathname.getName()); + boolean isFieldName = model.getFields().orderedFieldsNames().contains(pathname.getName()) || isDynamic(pathname.getName()); + + return isFile && isVisible && isValidName && isNotAlreadyUsed && isFieldName; + } + + private boolean isDynamic(String name) { + return name.equals("pointMotionU") || name.equals("pointDisplacement"); + } + } + + private class ValidDirectoryFileFilter implements FileFilter { + + private List children; + + public ValidDirectoryFileFilter(List children) { + this.children = children; + } + + @Override + public boolean accept(File pathname) { + boolean isDir = pathname.isDirectory(); + boolean isVisible = !pathname.isHidden(); + boolean isNotAlreadyUsed = !children.contains(pathname.getName()); + return isDir && isVisible && isNotAlreadyUsed && isNotAlreadyUsed; + } + } + +} diff --git a/src/eu/engys/gui/custom/CustomNodePanel.java b/src/eu/engys/gui/custom/CustomNodePanel.java new file mode 100644 index 0000000..393b474 --- /dev/null +++ b/src/eu/engys/gui/custom/CustomNodePanel.java @@ -0,0 +1,365 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.custom; + +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; + +import net.java.dev.designgridlayout.Componentizer; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryEditor; +import eu.engys.core.dictionary.FileEditor; +import eu.engys.core.project.Model; +import eu.engys.core.project.custom.Custom.ConstantDirectory; +import eu.engys.core.project.custom.Custom.SystemDirectory; +import eu.engys.core.project.custom.Custom.ZeroDirectory; +import eu.engys.core.project.custom.CustomFile; +import eu.engys.gui.AbstractGUIPanel; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.StringField; + +public class CustomNodePanel extends AbstractGUIPanel { + + public static final String ADD_LABEL = "Add"; + public static final String REMOVE_LABEL = "Remove"; + + public static final String CUSTOM = "Custom"; + public static final String FILE_NAME_LABEL = "File Name"; + public static final String FILE_TYPE_LABEL = "File Type"; + public static final String FILE_PARENT_LABEL = "File Parent"; + public static final String EDIT_LABEL = "Edit"; + + private CustomTreeNodeManager treeNodeManager; + private JButton newButton; + private JButton removeButton; + private StringField typeField; + private StringField nameField; + private StringField parentField; + private JButton editButton; + + @Inject + public CustomNodePanel(Model model) { + super(CUSTOM, model); + this.treeNodeManager = new CustomTreeNodeManager(model, this); + model.addObserver(treeNodeManager); + } + + @Override + protected JComponent layoutComponents() { + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(createButtonsPanel()); + builder.addComponent(createNameTypePanel()); + + return builder.removeMargins().getPanel(); + } + + private JComponent createButtonsPanel() { + List actionsList = new ArrayList(); + + newButton = new JButton(getAddFileAction()); + newButton.setName(ADD_LABEL); + + removeButton = new JButton(getRemoveFileAction()); + removeButton.setName(REMOVE_LABEL); + removeButton.setEnabled(false); + + actionsList.add(newButton); + actionsList.add(removeButton); + + JComponent buttonsPanel = UiUtil.getCommandRow(actionsList); + buttonsPanel.setBorder(BorderFactory.createEmptyBorder()); + return buttonsPanel; + } + + private JComponent createNameTypePanel() { + PanelBuilder nameTypeBuider = new PanelBuilder(); + + initNameField(); + initParentField(); + initTypeField(); + initEditButton(); + + nameTypeBuider.addComponent(FILE_NAME_LABEL, nameField); + nameTypeBuider.addComponent(FILE_TYPE_LABEL, typeField); + nameTypeBuider.addComponent(FILE_PARENT_LABEL, parentField); + nameTypeBuider.addComponent(EDIT_LABEL, Componentizer.create().minToPref(editButton).prefAndMore(new JLabel()).component()); + + return nameTypeBuider.removeMargins().getPanel(); + } + + private void initEditButton() { + editButton = new JButton(getEditFileAction()); + editButton.setName(EDIT_LABEL); + editButton.setEnabled(false); + } + + private void initTypeField() { + typeField = stringField(); + typeField.setEnabled(false); + } + + private void initParentField() { + parentField = stringField(); + parentField.setEnabled(false); + } + + private void initNameField() { + nameField = stringField(); + nameField.setEnabled(false); + } + + public boolean canRemoveSelectedCustomFile(CustomFile[] currentSelection) { + if (!isSomethingSelected(currentSelection)) { + return false; + } else { + boolean notZero = !(currentSelection[0] instanceof ZeroDirectory); + boolean notConstant = !(currentSelection[0] instanceof ConstantDirectory); + boolean notSystem = !(currentSelection[0] instanceof SystemDirectory); + return notZero && notConstant && notSystem; + } + } + + public boolean canEditSelectedCustomFile(CustomFile[] currentSelection) { + if (!isSomethingSelected(currentSelection)) { + return false; + } else { + boolean notDirectory = !(currentSelection[0].getType().isDirectory()); + return notDirectory; + } + } + + public boolean canAddCustomFileToSelectedFile(CustomFile[] currentSelection) { + if (isSomethingSelected(currentSelection)) { + return currentSelection[0].getType().isDirectory(); + } else { + return false; + } + } + + private boolean isSomethingSelected(CustomFile[] selection) { + if (selection == null) { + return false; + } + if (selection.length == 0) { + return false; + } + if (selection.length == 1 && selection[0] == null) { + return false; + } + return true; + } + + public void updateSelection(CustomFile[] currentSelection) { + updateTypeField(currentSelection); + updateParentField(currentSelection); + updateNameField(currentSelection); + updateAddButton(currentSelection); + updateEditButton(currentSelection); + updateRemoveButton(currentSelection); + } + + private void updateAddButton(CustomFile[] currentSelection) { + newButton.setEnabled(canAddCustomFileToSelectedFile(currentSelection)); + } + + private void updateRemoveButton(CustomFile[] currentSelection) { + removeButton.setEnabled(canRemoveSelectedCustomFile(currentSelection)); + } + + private void updateEditButton(CustomFile[] currentSelection) { + if (currentSelection != null && currentSelection.length > 0) { + if (currentSelection.length == 1 && currentSelection[0] != null) { + editButton.setEnabled(!currentSelection[0].getType().isDirectory()); + } else { + editButton.setEnabled(false); + } + } + } + + private void updateTypeField(CustomFile... currentSelection) { + if (currentSelection != null && currentSelection.length > 0) { + if (currentSelection.length == 1 && currentSelection[0] != null) { + typeField.setText(currentSelection[0].getType() != null ? currentSelection[0].getType().getLabel() : ""); + } else { + StringBuilder sb = new StringBuilder(); + for (CustomFile file : currentSelection) { + sb.append(file.getType().getLabel() + " "); + } + typeField.setText(sb.toString()); + } + } + } + + private void updateParentField(CustomFile... currentSelection) { + if (currentSelection != null && currentSelection.length > 0) { + if (currentSelection.length == 1 && currentSelection[0] != null) { + parentField.setText(currentSelection[0].getParent().getName()); + } else { + StringBuilder sb = new StringBuilder(); + for (CustomFile file : currentSelection) { + sb.append(file.getParent().getName() + " "); + } + parentField.setText(sb.toString()); + parentField.setEnabled(false); + } + } + } + + private void updateNameField(CustomFile... currentSelection) { + if (currentSelection != null && currentSelection.length > 0) { + if (currentSelection.length == 1 && currentSelection[0] != null) { + nameField.setText(currentSelection[0].getName()); + } else { + StringBuilder sb = new StringBuilder(); + for (CustomFile file : currentSelection) { + sb.append(file.getName() + " "); + } + nameField.setText(sb.toString()); + } + } + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } + + public AbstractAction getAddFileAction() { + return new AddAction(); + } + + public AbstractAction getRemoveFileAction() { + return new RemoveAction(); + } + + public AbstractAction getEditFileAction() { + return new EditAction(); + } + + private class AddAction extends AbstractAction { + + public AddAction() { + super(ADD_LABEL); + } + + @Override + public void actionPerformed(ActionEvent e) { + addFile(); + + } + } + + private class RemoveAction extends AbstractAction { + + public RemoveAction() { + super(REMOVE_LABEL); + } + + @Override + public void actionPerformed(ActionEvent e) { + removeSelectedFiles(); + } + } + + private class EditAction extends AbstractAction { + + public EditAction() { + super(EDIT_LABEL); + } + + @Override + public void actionPerformed(ActionEvent e) { + editSelectedFile(); + } + } + + private void addFile() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + CustomFileDialog dialog = new CustomFileDialog(model); + dialog.show(treeNodeManager.getSelectedValue()); + updateRemoveButton(treeNodeManager.getSelectedValues()); + editSelectedFile(); + } + }); + } + + private void removeSelectedFiles() { + CustomFile[] selectedValue = treeNodeManager.getSelectedValues(); + for (CustomFile customFile : selectedValue) { + model.getCustom().remove(customFile); + } + model.customChanged(); + } + + private void editSelectedFile() { + final CustomFile customFile = treeNodeManager.getSelectedValue(); + Runnable onShowRunnable = new Runnable() { + @Override + public void run() { + editButton.setEnabled(false); + } + }; + Runnable onDisposeRunnable = new Runnable() { + @Override + public void run() { + editButton.setEnabled(true); + } + }; + Runnable onOKRunnable = new Runnable() { + @Override + public void run() { + customFile.setChanged(true); + } + }; + if (customFile != null) { + if (customFile.getType().isDictionary() || customFile.getType().isField()) { + Dictionary dictionaryToEdit = customFile.getDictionary(); + DictionaryEditor.getInstance().show(SwingUtilities.getWindowAncestor(this), dictionaryToEdit, onShowRunnable, onDisposeRunnable, onOKRunnable); + } else if (customFile.getType().isRaw()) { + List rawContent = customFile.getRawFileContent(); + FileEditor.getInstance().show(SwingUtilities.getWindowAncestor(this), rawContent, customFile.getName(), onShowRunnable, onDisposeRunnable, onOKRunnable); + } else { + // do nothing + } + } + } +} diff --git a/src/eu/engys/gui/custom/CustomTreeNodeManager.java b/src/eu/engys/gui/custom/CustomTreeNodeManager.java new file mode 100644 index 0000000..6cb2e58 --- /dev/null +++ b/src/eu/engys/gui/custom/CustomTreeNodeManager.java @@ -0,0 +1,293 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.custom; + +import java.awt.Component; +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.JPopupMenu; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreePath; + +import eu.engys.core.project.Model; +import eu.engys.core.project.custom.Custom; +import eu.engys.core.project.custom.CustomFile; +import eu.engys.core.project.custom.CustomUtils; +import eu.engys.gui.tree.AbstractSelectionHandler; +import eu.engys.gui.tree.DefaultTreeNodeManager; +import eu.engys.gui.tree.SelectionHandler; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.Symbols; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.TreeUtil; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class CustomTreeNodeManager extends DefaultTreeNodeManager { + + private SelectionHandler selectionHandler; + private Map filesMap = new HashMap<>(); + private CustomNodePanel panel; + private AbstractAction addFileAction; + private AbstractAction removeFileAction; + private AbstractAction editFileAction; + + public CustomTreeNodeManager(Model model, final CustomNodePanel panel) { + super(model, panel); + this.selectionHandler = new CustomSelectionHandler(panel); + this.panel = panel; + } + + @Override + public void update(Observable o, final Object arg) { + if (arg instanceof CustomFile || arg instanceof Custom) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + loadTree(); + expandTree(arg); + } + }); + } + } + + private void loadTree() { + clear(); + load(model.getCustom().getRoot()); + treeChanged(root); + } + + private void load(CustomFile file) { + if (file != null) { + _load(file); + } + } + + private void _load(CustomFile file) { + if (file.getName() != null) { + CustomFile parent = file.getParent(); + if (parent != null && nodeMap.containsKey(parent)) { + addNode(nodeMap.get(parent), file); + } else { + addNode(root, file); + } + } + for (CustomFile child : file.getChildren()) { + load(child); + } + } + + private void addNode(DefaultMutableTreeNode parent, CustomFile file) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(file); + parent.add(node); + filesMap.put(node, file); + nodeMap.put(file, node); + } + + private void expandTree(final Object arg) { + if (getTree() != null) { + getTree().expandNode(getRoot()); + if (arg instanceof CustomFile) { + CustomFile file = (CustomFile) arg; + setSelectedValue(file); + } + } + } + + @Override + public PopUpBuilder getPopUpBuilder() { + this.addFileAction = panel.getAddFileAction(); + this.removeFileAction = panel.getRemoveFileAction(); + this.editFileAction = panel.getEditFileAction(); + return new PopUpBuilder() { + @Override + public void populate(JPopupMenu popUp) { + popUp.add(addFileAction).setName((String) addFileAction.getValue(Action.NAME)); + popUp.add(removeFileAction).setName((String) removeFileAction.getValue(Action.NAME)); + popUp.add(editFileAction).setName((String) editFileAction.getValue(Action.NAME)); + } + }; + } + + public CustomFile[] getSelectedValues() { + if (getTree() != null) { + TreePath[] selectionPaths = getTree().getSelectionPaths(); + if (selectionPaths != null) { + CustomFile[] files = new CustomFile[selectionPaths.length]; + for (int i = 0; i < selectionPaths.length; i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPaths[i].getLastPathComponent(); + CustomFile file = filesMap.get(node); + files[i] = file; + } + return files; + } + } + return new CustomFile[0]; + } + + public CustomFile getSelectedValue() { + CustomFile[] values = getSelectedValues(); + return values.length > 0 ? values[0] : null; + } + + private void setSelectedValue(CustomFile file) { + DefaultMutableTreeNode selectedNode = nodeMap.get(file); + if (getTree() != null) { + if (selectedNode != null) { + getTree().setSelectedNode(selectedNode); + } + } + } + + public void clear() { + // clear node before selection handler! + clearNode(root); + selectionHandler.clear(); + nodeMap.clear(); + filesMap.clear(); + } + + public DefaultMutableTreeNode getRoot() { + return root; + } + + @Override + public Class getRendererClass() { + return CustomFile.class; + } + + public DefaultTreeCellRenderer getRenderer() { + return new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObject = node.getUserObject(); + + if (userObject instanceof CustomFile) { + CustomFile item = (CustomFile) userObject; + text(item); + icon(item); + } else { + setIcon(null); + } + return this; + } + + private void text(CustomFile item) { + if (model.getProject() != null && model.getProject().isParallel() && CustomUtils.isVirtualFolder(item)) { + String hint = "[processor0 .. " + (model.getProject().getProcessors() - 1) + "]"; + setText(getLabelWithHint(item.getName(), hint)); + } else if (item.getType().isDictionary() || item.getType().isField() || item.getType().isRaw()) { + File file = CustomUtils.getFiles(model, item).get(0); + if (file.exists()) { + if (item.hasChanged()) { + setText(getLabelWithHint(item.getName(), "*")); + } else { + setText(item.getName()); + } + } else { + setText(getLabelWithHint(item.getName(), Symbols.PLUS_UPPERCASE)); + } + } else { + setText(item.getName()); + } + } + + private String getLabelWithHint(String label, String hint) { + return "" + label + " " + "" + hint + ""; + } + + private void icon(CustomFile item) { + if (item.getType().isDirectory()) { + setIcon(getDefaultOpenIcon()); + } else { + setIcon(getDefaultLeafIcon()); + } + } + }; + } + + @Override + public SelectionHandler getSelectionHandler() { + return selectionHandler; + } + + public final class CustomSelectionHandler extends AbstractSelectionHandler { + + private final CustomNodePanel panel; + private CustomFile[] currentSelection; + + public CustomSelectionHandler(CustomNodePanel panel) { + this.panel = panel; + } + + @Override + public void handleSelection(boolean fire3DEvent, Object... selection) { + if (currentSelection != null && currentSelection.length > 0) { + // panel.saveSurfaces(currentSelection); + } + if (TreeUtil.isConsistent(selection, CustomFile.class)) { + this.currentSelection = Arrays.copyOf(selection, selection.length, CustomFile[].class); + } else { + this.currentSelection = new CustomFile[0]; + } + + panel.updateSelection(currentSelection); + updateActions(); + } + + private void updateActions() { + addFileAction.setEnabled(panel.canAddCustomFileToSelectedFile(getSelectedValues())); + removeFileAction.setEnabled(panel.canRemoveSelectedCustomFile(getSelectedValues())); + editFileAction.setEnabled(panel.canEditSelectedCustomFile(getSelectedValues())); + } + + @Override + public void handleVisibility(VisibleItem item) { + } + + @Override + public void process3DSelectionEvent(Picker picker, Actor actor, boolean keep) { + } + + @Override + public void process3DVisibilityEvent(boolean selected) { + } + + public void clear() { + currentSelection = null; + } + } +} diff --git a/src/eu/engys/gui/events/EventManager.java b/src/eu/engys/gui/events/EventManager.java new file mode 100644 index 0000000..7d7fe54 --- /dev/null +++ b/src/eu/engys/gui/events/EventManager.java @@ -0,0 +1,287 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.events; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.EventListener; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class EventManager { + + public interface Condition { + public abstract boolean matches(Object obj, Event event, Object obj1); + } + + public interface Event extends Serializable { + public abstract Object getPayload(); + } + + public interface GenericEventListener extends EventListener { + public abstract void eventTriggered(Object obj, Event event); + } + + public interface EventExceptionHandler { + public abstract void handleException(Exception exception); + } + + public interface EventManagerExtension { + public abstract void afterTriggerEvent(Object obj, Event event, Object obj1); + + public abstract void afterRegisterEventListener(GenericEventListener genericeventlistener, Class class1, Condition condition, Map map); + } + + private EventManagerExtension eventManagerExtension; + private ExecutorService scheduler; + private Timer timer; + private EventExceptionHandler exceptionHandler; + protected Map> eventSubscriptionLists; + private Map> contextSubscriptionsMap; + + private static EventManager eventManager = new EventManager(); + + private static boolean asynchronous = true; + + private EventManager() { + scheduler = Executors.newCachedThreadPool(); + timer = new Timer(); + exceptionHandler = new EventExceptionHandler() { + + @Override + public void handleException(Exception ex) { + ex.printStackTrace(System.err); + } + }; + eventSubscriptionLists = new HashMap>(); + contextSubscriptionsMap = new HashMap>(); + } + + public static void registerEventListener(GenericEventListener receiver, Class eventClass) { + eventManager.registerEventListener(null, receiver, eventClass, null); + } + + public static void registerEventListener(Object context, GenericEventListener receiver, Class eventClass) { + eventManager.registerEventListener(context, receiver, eventClass, null); + } + + public static void unregisterAllEventSubscriptions() { + eventManager.eventSubscriptionLists = new HashMap>(); + } + + public static void unregisterEventSubscriptions(Class eventClass) { + eventManager.eventSubscriptionLists.remove(eventClass.getName()); + } + + public static void registerEventListener(GenericEventListener receiver, Class eventClass, Condition condition) { + eventManager.registerEventListener(null, receiver, eventClass, condition); + } + + private synchronized void registerEventListener(Object context, GenericEventListener receiver, Class eventClass, Condition condition) { + Map subcriptionList = eventSubscriptionLists.get(eventClass.getName()); + if (subcriptionList == null) { + subcriptionList = new HashMap(); + eventSubscriptionLists.put(eventClass.getName(), subcriptionList); + } + EventSubscription subscription = new EventSubscription(receiver, eventClass, condition); + if (!subcriptionList.containsKey(Integer.valueOf(subscription.hashCode()))) + subcriptionList.put(Integer.valueOf(subscription.hashCode()), subscription); + manageContext(context, subscription); + if (eventManagerExtension != null) + eventManagerExtension.afterRegisterEventListener(receiver, eventClass, condition, eventSubscriptionLists); + } + + private void manageContext(Object context, EventSubscription subscription) { + if (context != null) { + List subscriptionsAssociatedWithContext = contextSubscriptionsMap.get(context); + if (subscriptionsAssociatedWithContext == null) { + subscriptionsAssociatedWithContext = new ArrayList(); + contextSubscriptionsMap.put(context, subscriptionsAssociatedWithContext); + } + subscriptionsAssociatedWithContext.add(subscription); + } + } + + public synchronized void unregisterEventListener(GenericEventListener receiver, Class eventClass) { + EventSubscription tempSubscription = new EventSubscription(receiver, eventClass, null); + Map subcriptionList = eventSubscriptionLists.get(eventClass.getName()); + if (subcriptionList.containsKey(Integer.valueOf(tempSubscription.hashCode()))) + subcriptionList.remove(Integer.valueOf(tempSubscription.hashCode())); + } + + public synchronized void unregisterAllEventListenersForContext(Object context) { + List subscriptionsAssociatedWithContext = contextSubscriptionsMap.get(context); + for (EventSubscription eventSubscription : subscriptionsAssociatedWithContext) { + unregisterEventListener(eventSubscription.getReceiver(), eventSubscription.getEventClass()); + } + + } + + public static boolean waitUntilTriggered(Class eventClass) { + return eventManager.waitUntilTriggered(eventClass, 1000); + } + + public boolean waitUntilTriggered(Class eventClass, long timeout) { + EventWatcher eventWatcher = new EventWatcher(this, eventClass); + return eventWatcher.waitUntilTriggeredThenUnregister(timeout); + } + + public boolean waitUntilTriggered(Class eventClass, long timeout, Condition condition) { + EventWatcher eventWatcher = new EventWatcher(this, eventClass, condition); + return eventWatcher.waitUntilTriggeredThenUnregister(timeout); + } + + public static void triggerEvent(Object sender, Event event) { + eventManager.triggerEvent(sender, event, null); + } + + public synchronized void triggerEvent(Object sender, Event event, Object conditionalExpression) { + Map subscriptionList = eventSubscriptionListsForClass(event.getClass()); + if (subscriptionList != null && !subscriptionList.isEmpty()) { + for (EventSubscription eventSubscription : subscriptionList.values()) { + if (isASubscriptionForThatEvent(event, eventSubscription) && satisfyCondition(sender, event, conditionalExpression, eventSubscription)){ + if(asynchronous){ + invokeHandlerMethodAsynchronously(sender, event, eventSubscription.getReceiver()); + } else { + invokeHandlerMethodSynchronously(sender, event, eventSubscription.getReceiver()); + } + } + } + } + if (eventManagerExtension != null) + eventManagerExtension.afterTriggerEvent(sender, event, conditionalExpression); + } + + private boolean satisfyCondition(Object sender, Event event, Object conditionalExpression, EventSubscription eventSubscription) { + return eventSubscription.getCondition() == null || conditionalExpression != null && eventSubscription.getCondition().matches(sender, event, conditionalExpression); + } + + private boolean isASubscriptionForThatEvent(Event event, EventSubscription eventSubscription) { + return eventSubscription.getEventClass().isAssignableFrom(event.getClass()); + } + + private Map eventSubscriptionListsForClass(Class klass) { + String className = klass.getName(); + // System.out.println("className: "+className); + if (eventSubscriptionLists.containsKey(className)) + return eventSubscriptionLists.get(className); + for (Class interfaceClass : klass.getInterfaces()) { + String interfaceClassName = interfaceClass.getName(); + // System.out.println("interfaceClassName: "+interfaceClassName); + if (eventSubscriptionLists.containsKey(interfaceClassName)) + return eventSubscriptionLists.get(interfaceClassName); + } + if (klass.getSuperclass() != null) { + return eventSubscriptionListsForClass((Class) klass.getSuperclass()); + } + return null; + } + + public synchronized void triggerFutureEvent(Object sender, Event event, long delay, TimeUnit timeUnit) { + triggerFutureEvent(sender, event, null, delay, timeUnit); + } + + public synchronized void triggerFutureEvent(final Object sender, final Event event, final Object conditionalExpression, long delay, TimeUnit timeUnit) { + timer.schedule(new TimerTask() { + + @Override + public void run() { + triggerEvent(sender, event, conditionalExpression); + } + + }, TimeUnit.MILLISECONDS.convert(delay, timeUnit)); + } + + public synchronized void triggerPeriodicEvent(Object sender, Event event, long initialDelay, long delay, TimeUnit timeUnit) { + triggerPeriodicEvent(sender, event, null, initialDelay, delay, timeUnit); + } + + public synchronized void triggerPeriodicEvent(final Object sender, final Event event, final Object conditionalExpression, long initialDelay, long delay, TimeUnit timeUnit) { + long delayInMs = TimeUnit.MILLISECONDS.convert(initialDelay, timeUnit); + long periodInMs = TimeUnit.MILLISECONDS.convert(delay, timeUnit); + timer.scheduleAtFixedRate(new TimerTask() { + + @Override + public void run() { + triggerEvent(sender, event, conditionalExpression); + } + + }, delayInMs, periodInMs); + } + + private void invokeHandlerMethodAsynchronously(final Object sender, final Event event, final GenericEventListener receiver) { + scheduler.submit(new Runnable() { + + @Override + public void run() { + try { + receiver.eventTriggered(sender, event); + } catch (Exception ex) { + exceptionHandler.handleException(ex); + } + } + }); + } + + private void invokeHandlerMethodSynchronously(final Object sender, final Event event, final GenericEventListener receiver) { + try { + receiver.eventTriggered(sender, event); + } catch (Exception ex) { + exceptionHandler.handleException(ex); + } + } + + public static void setAsynchronous(boolean asynchronous) { + EventManager.asynchronous = asynchronous; + } + + public EventManagerExtension getEventManagerExtension() { + return eventManagerExtension; + } + + public static void setEventManagerExtension(EventManagerExtension eventManagerExtension) { + eventManager.eventManagerExtension = eventManagerExtension; + } + + public void setEventExceptionHandler(EventExceptionHandler eventExceptionHandler) { + exceptionHandler = eventExceptionHandler; + } + + public EventExceptionHandler getEventExceptionHandler() { + return exceptionHandler; + } + + public void shutdown() { + timer.cancel(); + scheduler.shutdownNow(); + } +} diff --git a/src/eu/engys/gui/events/EventObject.java b/src/eu/engys/gui/events/EventObject.java new file mode 100644 index 0000000..fa552e2 --- /dev/null +++ b/src/eu/engys/gui/events/EventObject.java @@ -0,0 +1,45 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events; + +import eu.engys.gui.events.EventManager.Event; + +public class EventObject implements Event { + + public EventObject() { + } + + public EventObject(Object payload) { + this.payload = payload; + } + + public Object getPayload() { + return payload; + } + + private Object payload; +} diff --git a/src/eu/engys/gui/events/EventSubscription.java b/src/eu/engys/gui/events/EventSubscription.java new file mode 100644 index 0000000..a07e3fa --- /dev/null +++ b/src/eu/engys/gui/events/EventSubscription.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events; + +import eu.engys.gui.events.EventManager.Condition; +import eu.engys.gui.events.EventManager.Event; +import eu.engys.gui.events.EventManager.GenericEventListener; + +public class EventSubscription { + + public EventSubscription(GenericEventListener receiver, Class eventClass, Condition condition) { + this.receiver = receiver; + this.eventClass = eventClass; + this.condition = condition; + } + + public GenericEventListener getReceiver() { + return receiver; + } + + public Class getEventClass() { + return eventClass; + } + + public int hashCode() { + return (new StringBuilder()).append(receiver.hashCode()).append(eventClass.getName()).append("").toString().hashCode(); + } + + public Condition getCondition() { + return condition; + } + + private GenericEventListener receiver; + private Class eventClass; + private Condition condition; +} diff --git a/src/eu/engys/gui/events/EventWatcher.java b/src/eu/engys/gui/events/EventWatcher.java new file mode 100644 index 0000000..6913bb1 --- /dev/null +++ b/src/eu/engys/gui/events/EventWatcher.java @@ -0,0 +1,120 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events; + +import eu.engys.gui.events.EventManager.Condition; +import eu.engys.gui.events.EventManager.Event; +import eu.engys.gui.events.EventManager.GenericEventListener; + +public class EventWatcher { + + private boolean triggered; + private final Object lockObject; + private Class eventClass; + private Condition condition; + private GenericEventListener eventListener; + private Object eventPayload; + private EventManager eventManager; + + public EventWatcher(EventManager eventManager, Class eventClass) { + this(eventManager, eventClass, null); + } + + public EventWatcher(EventManager eventManager, Class eventClass, Condition condition) { + triggered = false; + lockObject = new Object(); + this.eventManager = eventManager; + this.eventClass = eventClass; + this.condition = condition; + registerEventListener(eventClass, condition); + } + + private synchronized void registerEventListener(Class eventClass, Condition condition) { + createEventListener(); + if (condition != null) + EventManager.registerEventListener(eventListener, eventClass, condition); + else + EventManager.registerEventListener(eventListener, eventClass); + } + + private synchronized void createEventListener() { + eventListener = new GenericEventListener() { + + public synchronized void eventTriggered(Object sender, Event event) { + synchronized (lockObject) { + eventPayload = event.getPayload(); + triggered = true; + lockObject.notifyAll(); + } + } + }; + } + + public synchronized void unregisterEvent() { + eventManager.unregisterEventListener(eventListener, eventClass); + } + + public boolean hasBeenTriggered() { + if (triggered) { + triggered = false; + return true; + } + return false; + } + + public boolean waitUntilTriggeredThenUnregister(long timeout) { + boolean result = waitUntilTriggered(timeout); + unregisterEvent(); + return result; + } + + public boolean waitUntilTriggered(long timeout) { + if (hasBeenTriggered()) + return true; + try { + synchronized (lockObject) { + lockObject.wait(timeout); + } + } catch (InterruptedException e) { + } + return hasBeenTriggered(); + } + + public void reEnableEventWatcher() { + triggered = false; + registerEventListener(eventClass, condition); + } + + public Object getEventPayload() { + return eventPayload; + } + + public Class getEvent() { + return eventClass; + } + +} diff --git a/src/eu/engys/gui/events/application/ApplicationEvent.java b/src/eu/engys/gui/events/application/ApplicationEvent.java new file mode 100644 index 0000000..4fb2654 --- /dev/null +++ b/src/eu/engys/gui/events/application/ApplicationEvent.java @@ -0,0 +1,33 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.application; + +import eu.engys.gui.events.EventManager.Event; + +public interface ApplicationEvent extends Event { + +} diff --git a/src/eu/engys/gui/events/application/BaseMeshTypeChangedEvent.java b/src/eu/engys/gui/events/application/BaseMeshTypeChangedEvent.java new file mode 100644 index 0000000..6368c06 --- /dev/null +++ b/src/eu/engys/gui/events/application/BaseMeshTypeChangedEvent.java @@ -0,0 +1,37 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.application; + +import eu.engys.gui.events.EventObject; + +public class BaseMeshTypeChangedEvent extends EventObject implements ApplicationEvent{ + + public BaseMeshTypeChangedEvent() { + super(); + } + +} diff --git a/src/eu/engys/gui/events/application/OpenMonitorEvent.java b/src/eu/engys/gui/events/application/OpenMonitorEvent.java new file mode 100644 index 0000000..947cffe --- /dev/null +++ b/src/eu/engys/gui/events/application/OpenMonitorEvent.java @@ -0,0 +1,37 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.application; + +import eu.engys.gui.events.EventObject; + +public class OpenMonitorEvent extends EventObject implements ApplicationEvent { + + public OpenMonitorEvent() { + super(); + } + +} diff --git a/src/eu/engys/gui/events/view3D/ActorExtractEvent.java b/src/eu/engys/gui/events/view3D/ActorExtractEvent.java new file mode 100644 index 0000000..0b21f47 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/ActorExtractEvent.java @@ -0,0 +1,49 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.gui.events.EventObject; + +public class ActorExtractEvent extends EventObject { + + private String actorName; + private String newName; + + public ActorExtractEvent(String actorName, String newName) { + super(); + this.actorName = actorName; + this.newName = newName; + } + + public String getActorName() { + return actorName; + } + + public String getNewName() { + return newName; + } +} diff --git a/src/eu/engys/gui/events/view3D/ActorPopUpEvent.java b/src/eu/engys/gui/events/view3D/ActorPopUpEvent.java new file mode 100644 index 0000000..121292d --- /dev/null +++ b/src/eu/engys/gui/events/view3D/ActorPopUpEvent.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import java.awt.event.MouseEvent; + +import eu.engys.gui.events.EventObject; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; + +public class ActorPopUpEvent extends EventObject { + + private Actor actor; + private Picker picker; + private MouseEvent event; + + + public ActorPopUpEvent(MouseEvent event, Picker picker, Actor actor) { + this.picker = picker; + this.actor = actor; + this.event = event; + } + + public Actor getActor() { + return actor; + } + + public Picker getPicker() { + return picker; + } + + public MouseEvent getMouseEvent() { + return event; + } + +} diff --git a/src/eu/engys/gui/events/view3D/ActorSelectionEvent.java b/src/eu/engys/gui/events/view3D/ActorSelectionEvent.java new file mode 100644 index 0000000..41556ee --- /dev/null +++ b/src/eu/engys/gui/events/view3D/ActorSelectionEvent.java @@ -0,0 +1,57 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.gui.events.EventObject; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; + +public class ActorSelectionEvent extends EventObject { + + private Actor actor; + private Picker picker; + private boolean keep; + + public ActorSelectionEvent(Picker picker, Actor actor, boolean keep) { + super(); + this.picker = picker; + this.actor = actor; + this.keep = keep; + } + + public Actor getActor() { + return actor; + } + + public Picker getPicker() { + return picker; + } + + public boolean isKeep() { + return keep; + } +} diff --git a/src/eu/engys/gui/events/view3D/ActorVisibilityEvent.java b/src/eu/engys/gui/events/view3D/ActorVisibilityEvent.java new file mode 100644 index 0000000..f14f6eb --- /dev/null +++ b/src/eu/engys/gui/events/view3D/ActorVisibilityEvent.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.gui.events.EventObject; + +public class ActorVisibilityEvent extends EventObject { + + private final boolean select; + + public ActorVisibilityEvent(boolean select) { + super(); + this.select = select; + } + + public boolean isSelect() { + return select; + } + +} diff --git a/src/eu/engys/gui/events/view3D/AddSTLEvent.java b/src/eu/engys/gui/events/view3D/AddSTLEvent.java new file mode 100644 index 0000000..dc838e1 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/AddSTLEvent.java @@ -0,0 +1,46 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import java.util.EventObject; + +import eu.engys.core.project.geometry.surface.Stl; + +public class AddSTLEvent extends EventObject { + + private Stl stl; + + public AddSTLEvent(Object source, Stl stl) { + super(source); + this.stl = stl; + } + + public Stl getStl() { + return stl; + } + +} diff --git a/src/eu/engys/gui/events/view3D/AddSurfaceEvent.java b/src/eu/engys/gui/events/view3D/AddSurfaceEvent.java new file mode 100644 index 0000000..6a9c009 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/AddSurfaceEvent.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.events.EventObject; + +public class AddSurfaceEvent extends EventObject implements View3DEvent { + + private Surface[] surfaces; + private boolean resetZoom; + + public AddSurfaceEvent(boolean resetZoom, Surface... surfaces) { + super(surfaces); + this.resetZoom = resetZoom; + this.surfaces = surfaces; + } + + public AddSurfaceEvent(Surface... surfaces) { + this(true, surfaces); + } + + public Surface[] getSurfaces() { + return surfaces; + } + + public boolean isResetZoom() { + return resetZoom; + } +} diff --git a/src/eu/engys/gui/events/view3D/AxisEvent.java b/src/eu/engys/gui/events/view3D/AxisEvent.java new file mode 100644 index 0000000..3a4fa77 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/AxisEvent.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.dictionary.model.AxisInfo; +import eu.engys.gui.events.EventObject; + +public class AxisEvent extends EventObject implements View3DEvent { + + private AxisInfo axisInfo; + + public AxisEvent(AxisInfo axisInfo) { + super(); + this.axisInfo = axisInfo; + } + + public AxisInfo getAxisInfo() { + return axisInfo; + } +} diff --git a/src/eu/engys/gui/events/view3D/BoxEvent.java b/src/eu/engys/gui/events/view3D/BoxEvent.java new file mode 100644 index 0000000..1b9b32e --- /dev/null +++ b/src/eu/engys/gui/events/view3D/BoxEvent.java @@ -0,0 +1,68 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.events.EventObject; +import eu.engys.util.ui.textfields.DoubleField; + +public class BoxEvent extends EventObject implements View3DEvent { + + private DoubleField[] min; + private DoubleField[] max; + private EventActionType action; + + public BoxEvent(DoubleField[] min, DoubleField[] max, EventActionType action) { + super(); + this.min = min; + this.max = max; + this.action = action; + } + + public DoubleField[] getMin() { + return min; + } + public void setMin(DoubleField[] min) { + this.min = min; + } + + public DoubleField[] getMax() { + return max; + } + public void setMax(DoubleField[] max) { + this.max = max; + } + + public EventActionType getAction() { + return action; + } + + public void setAction(EventActionType action) { + this.action = action; + } + +} diff --git a/src/eu/engys/gui/events/view3D/ChangeSurfaceEvent.java b/src/eu/engys/gui/events/view3D/ChangeSurfaceEvent.java new file mode 100644 index 0000000..35d54c1 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/ChangeSurfaceEvent.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.events.EventObject; + +public class ChangeSurfaceEvent extends EventObject implements View3DEvent { + + private Surface surface; + private final boolean resetZoom; + + public ChangeSurfaceEvent(Surface surface, boolean resetZoom) { + super(); + this.surface = surface; + this.resetZoom = resetZoom; + } + + public Surface getSurface() { + return surface; + } + + public boolean isResetZoom() { + return resetZoom; + } + +} diff --git a/src/eu/engys/gui/events/view3D/ColorSurfaceEvent.java b/src/eu/engys/gui/events/view3D/ColorSurfaceEvent.java new file mode 100644 index 0000000..e7e438b --- /dev/null +++ b/src/eu/engys/gui/events/view3D/ColorSurfaceEvent.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import java.awt.Color; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.events.EventObject; + +public class ColorSurfaceEvent extends EventObject implements View3DEvent { + + private Surface selection; + private Color color; + + public ColorSurfaceEvent(Surface selection, Color value) { + super(); + this.selection = selection; + this.color = value; + } + + public Surface getSelection() { + return selection; + } + + public Color getColor() { + return color; + } +} diff --git a/src/eu/engys/gui/events/view3D/LayersCoverageEvent.java b/src/eu/engys/gui/events/view3D/LayersCoverageEvent.java new file mode 100644 index 0000000..4742222 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/LayersCoverageEvent.java @@ -0,0 +1,64 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import javax.swing.JPanel; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.events.EventObject; +import eu.engys.gui.view3D.LayerInfo; + +public class LayersCoverageEvent extends EventObject implements View3DEvent { + + private EventActionType action; + private JPanel colorBar; + private LayerInfo layerInfo; + + public LayersCoverageEvent(LayerInfo layerInfo, JPanel colorBar, EventActionType action) { + super(); + this.layerInfo = layerInfo; + this.colorBar = colorBar; + this.action = action; + } + + public EventActionType getAction() { + return action; + } + + public JPanel getColorBar() { + return colorBar; + } + + public LayerInfo getLayerInfo() { + return layerInfo; + } + + public void setAction(EventActionType action) { + this.action = action; + } + +} diff --git a/src/eu/engys/gui/events/view3D/MeshQualityEvent.java b/src/eu/engys/gui/events/view3D/MeshQualityEvent.java new file mode 100644 index 0000000..60f38a9 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/MeshQualityEvent.java @@ -0,0 +1,56 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.events.EventObject; +import eu.engys.gui.view3D.QualityInfo; + +public class MeshQualityEvent extends EventObject implements View3DEvent { + + private EventActionType action; + private QualityInfo quality; + + public MeshQualityEvent(QualityInfo quality, EventActionType action) { + super(); + this.quality = quality; + this.action = action; + } + + public EventActionType getAction() { + return action; + } + + public void setAction(EventActionType action) { + this.action = action; + } + + public QualityInfo getQualityInfo() { + return quality; + } + +} diff --git a/src/eu/engys/gui/events/view3D/PlaneEvent.java b/src/eu/engys/gui/events/view3D/PlaneEvent.java new file mode 100644 index 0000000..2e53ed2 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/PlaneEvent.java @@ -0,0 +1,86 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.events.EventObject; +import eu.engys.util.ui.textfields.DoubleField; + +public class PlaneEvent extends EventObject implements View3DEvent { + + private DoubleField[] normal; + private DoubleField[] origin; + private EventActionType action; + private boolean interactive; + + public PlaneEvent(DoubleField[] origin, DoubleField[] normal, EventActionType action) { + super(); + this.origin = origin; + this.normal = normal; + this.action = action; + this.interactive = true; + } + + public PlaneEvent(DoubleField[] origin, DoubleField[] normal, EventActionType action, boolean interactive) { + super(); + this.origin = origin; + this.normal = normal; + this.action = action; + this.interactive = interactive; + } + + public DoubleField[] getOrigin() { + return origin; + } + + public void setOrigin(DoubleField[] origin) { + this.origin = origin; + } + + public DoubleField[] getNormal() { + return normal; + } + + public void setNormal(DoubleField[] normal) { + this.normal = normal; + } + + public EventActionType getAction() { + return action; + } + + public void setAction(EventActionType action) { + this.action = action; + } + + public void setInteractive(boolean interactive) { + this.interactive = interactive; + } + public boolean isInteractive() { + return interactive; + } +} diff --git a/src/eu/engys/gui/events/view3D/PointEvent.java b/src/eu/engys/gui/events/view3D/PointEvent.java new file mode 100644 index 0000000..4efdc27 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/PointEvent.java @@ -0,0 +1,66 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import java.awt.Color; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.events.EventObject; +import eu.engys.util.ui.textfields.DoubleField; + +public class PointEvent extends EventObject implements View3DEvent { + + private DoubleField[] field; + private Color color; + private String key; + private EventActionType action; + + public PointEvent(DoubleField[] field, String key, EventActionType action, Color color) { + super(); + this.field = field; + this.key = key; + this.action = action; + this.color = color; + } + + public DoubleField[] getPoint() { + return field; + } + + public String getKey() { + return key; + } + + public EventActionType getAction() { + return action; + } + + public Color getColor() { + return color; + } + +} diff --git a/src/eu/engys/gui/events/view3D/RemoveSurfaceEvent.java b/src/eu/engys/gui/events/view3D/RemoveSurfaceEvent.java new file mode 100644 index 0000000..468ee77 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/RemoveSurfaceEvent.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.events.EventObject; + +public class RemoveSurfaceEvent extends EventObject implements View3DEvent { + + private Surface[] surfaces; + private boolean resetZoom; + + public RemoveSurfaceEvent(boolean resetZoom, Surface... surfaces) { + super(); + this.resetZoom = resetZoom; + this.surfaces = surfaces; + } + + public RemoveSurfaceEvent(Surface... surfaces) { + this(false, surfaces); + } + + public Surface[] getSurfaces() { + return surfaces; + } + + public boolean isResetZoom() { + return resetZoom; + } +} diff --git a/src/eu/engys/gui/events/view3D/RenameSurfaceEvent.java b/src/eu/engys/gui/events/view3D/RenameSurfaceEvent.java new file mode 100644 index 0000000..0eb8c1a --- /dev/null +++ b/src/eu/engys/gui/events/view3D/RenameSurfaceEvent.java @@ -0,0 +1,56 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.events.EventObject; + +public class RenameSurfaceEvent extends EventObject implements View3DEvent { + + private Surface surface; + private String oldName; + private String newName; + + public RenameSurfaceEvent(Surface surface, String oldName, String newName) { + super(); + this.surface = surface; + this.newName = newName; + this.oldName = oldName; + } + + public Surface getSurface() { + return surface; + } + + public String getOldName() { + return oldName; + } + + public String getNewName() { + return newName; + } +} diff --git a/src/eu/engys/gui/events/view3D/ScalarBarWidgetEvent.java b/src/eu/engys/gui/events/view3D/ScalarBarWidgetEvent.java new file mode 100644 index 0000000..9c98a80 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/ScalarBarWidgetEvent.java @@ -0,0 +1,43 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.gui.events.EventObject; + +public class ScalarBarWidgetEvent extends EventObject implements View3DEvent { + + private boolean on; + + public ScalarBarWidgetEvent(boolean on) { + super(); + this.on = on; + } + + public boolean isOn() { + return on; + } +} diff --git a/src/eu/engys/gui/events/view3D/SelectCellZonesEvent.java b/src/eu/engys/gui/events/view3D/SelectCellZonesEvent.java new file mode 100644 index 0000000..dd26ab8 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/SelectCellZonesEvent.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.gui.events.EventObject; + +public class SelectCellZonesEvent extends EventObject implements View3DEvent { + + private CellZone[] selection; + + public SelectCellZonesEvent(CellZone[] selection) { + super(); + this.selection = selection; + } + + public CellZone[] getSelection() { + return selection; + } +} diff --git a/src/eu/engys/gui/events/view3D/SelectPatchesEvent.java b/src/eu/engys/gui/events/view3D/SelectPatchesEvent.java new file mode 100644 index 0000000..f05cba8 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/SelectPatchesEvent.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.gui.events.EventObject; + +public class SelectPatchesEvent extends EventObject implements View3DEvent { + + private Patch[] selection; + + public SelectPatchesEvent(Patch[] patches) { + super(); + this.selection = patches; + } + + public Patch[] getSelection() { + return selection; + } +} diff --git a/src/eu/engys/gui/events/view3D/SelectSurfaceEvent.java b/src/eu/engys/gui/events/view3D/SelectSurfaceEvent.java new file mode 100644 index 0000000..00bd45a --- /dev/null +++ b/src/eu/engys/gui/events/view3D/SelectSurfaceEvent.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.events.EventObject; + +public class SelectSurfaceEvent extends EventObject implements View3DEvent { + + private Surface[] selection; + + public SelectSurfaceEvent(Surface[] selection) { + super(); + this.selection = selection; + } + + public Surface[] getSelection() { + return selection; + } +} diff --git a/src/eu/engys/gui/events/view3D/SelectionEvent.java b/src/eu/engys/gui/events/view3D/SelectionEvent.java new file mode 100644 index 0000000..6a0102a --- /dev/null +++ b/src/eu/engys/gui/events/view3D/SelectionEvent.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.events.EventObject; +import eu.engys.gui.view3D.Selection; + +public class SelectionEvent extends EventObject implements View3DEvent { + + private EventActionType action; + private Selection selection; + + public SelectionEvent(Selection selection, EventActionType action) { + super(); + this.selection = selection; + this.action = action; + } + + public void setSelection(Selection selection) { + this.selection = selection; + } + + public Selection getSelection() { + return selection; + } + + public EventActionType getAction() { + return action; + } + + public void setAction(EventActionType action) { + this.action = action; + } + +} diff --git a/src/eu/engys/gui/events/view3D/TransformSurfaceEvent.java b/src/eu/engys/gui/events/view3D/TransformSurfaceEvent.java new file mode 100644 index 0000000..c9714fb --- /dev/null +++ b/src/eu/engys/gui/events/view3D/TransformSurfaceEvent.java @@ -0,0 +1,57 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.gui.events.EventObject; + +public class TransformSurfaceEvent extends EventObject implements View3DEvent{ + + private Surface[] surfaces; + private AffineTransform transformation; + private boolean save; + + public TransformSurfaceEvent(AffineTransform t, boolean save, Surface... surfaces) { + super(t); + this.save = save; + this.surfaces = surfaces; + this.transformation = t; + } + + public Surface[] getSurfaces() { + return surfaces; + } + + public AffineTransform getTransformation() { + return transformation; + } + + public boolean shouldSave() { + return save; + } +} diff --git a/src/eu/engys/gui/events/view3D/View3DEvent.java b/src/eu/engys/gui/events/view3D/View3DEvent.java new file mode 100644 index 0000000..53cbb22 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/View3DEvent.java @@ -0,0 +1,33 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.gui.events.EventManager.Event; + +public interface View3DEvent extends Event { + +} diff --git a/src/eu/engys/gui/events/view3D/VisibleItemEvent.java b/src/eu/engys/gui/events/view3D/VisibleItemEvent.java new file mode 100644 index 0000000..c652022 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/VisibleItemEvent.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.gui.events.EventObject; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class VisibleItemEvent extends EventObject implements View3DEvent { + + private VisibleItem selection; + private Object invoker; + + public VisibleItemEvent(Object invoker, VisibleItem selection) { + super(); + this.invoker = invoker; + this.selection = selection; + } + + public VisibleItem getSelection() { + return selection; + } + + public Object getInvoker() { + return invoker; + } + +} diff --git a/src/eu/engys/gui/events/view3D/VolumeReportEvent.java b/src/eu/engys/gui/events/view3D/VolumeReportEvent.java new file mode 100644 index 0000000..6376a6c --- /dev/null +++ b/src/eu/engys/gui/events/view3D/VolumeReportEvent.java @@ -0,0 +1,58 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import javax.vecmath.Point3d; + +import eu.engys.gui.events.EventObject; + +public class VolumeReportEvent extends EventObject implements View3DEvent { + + private final Point3d minAtLocation; + private final Point3d maxAtLocation; + private final String varName; + + public VolumeReportEvent(Point3d minAtLocation, Point3d maxAtLocation, String varName) { + super(); + this.minAtLocation = minAtLocation; + this.maxAtLocation = maxAtLocation; + this.varName = varName; + } + + public String getVarName() { + return varName; + } + + public Point3d getMinAtLocation() { + return minAtLocation; + } + + public Point3d getMaxAtLocation() { + return maxAtLocation; + } + +} diff --git a/src/eu/engys/gui/events/view3D/VolumeReportVisibilityEvent.java b/src/eu/engys/gui/events/view3D/VolumeReportVisibilityEvent.java new file mode 100644 index 0000000..a8b8e91 --- /dev/null +++ b/src/eu/engys/gui/events/view3D/VolumeReportVisibilityEvent.java @@ -0,0 +1,68 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.events.view3D; + +import eu.engys.gui.events.EventObject; + +public class VolumeReportVisibilityEvent extends EventObject implements View3DEvent { + + private String key; + private Kind kind; + private boolean visible; + + public enum Kind { + MIN, MAX; + + public boolean isMin() { + return this == MIN; + } + + public boolean isMax() { + return this == MAX; + } + } + + public VolumeReportVisibilityEvent(String key, Kind kind, boolean visible) { + super(); + this.key = key; + this.kind = kind; + this.visible = visible; + } + + public String getKey() { + return key; + } + + public Kind getKind() { + return kind; + } + + public boolean isVisible() { + return visible; + } + +} diff --git a/src/eu/engys/gui/mesh/GeometryPanel.java b/src/eu/engys/gui/mesh/GeometryPanel.java new file mode 100644 index 0000000..3fd8fe1 --- /dev/null +++ b/src/eu/engys/gui/mesh/GeometryPanel.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh; + +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.util.progress.ProgressMonitor; + +public interface GeometryPanel { + + void addSTL(); + + void addBox(); + + void addCylinder(); + + void addSphere(); + + void addRing(); + + void addPlane(); + + void renameSurface(String text); + + void changeSurface(Surface surface); + + Model getModel(); + + ProgressMonitor getMonitor(); + +} diff --git a/src/eu/engys/gui/mesh/Mesh.java b/src/eu/engys/gui/mesh/Mesh.java new file mode 100644 index 0000000..36e3e7f --- /dev/null +++ b/src/eu/engys/gui/mesh/Mesh.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import com.google.inject.BindingAnnotation; + +@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME) +public @interface Mesh { + +} diff --git a/src/eu/engys/gui/mesh/Mesh3DElement.java b/src/eu/engys/gui/mesh/Mesh3DElement.java new file mode 100644 index 0000000..72547fe --- /dev/null +++ b/src/eu/engys/gui/mesh/Mesh3DElement.java @@ -0,0 +1,50 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh; + +import java.util.Set; + +import javax.inject.Inject; + +import eu.engys.gui.GUIPanel; +import eu.engys.gui.view.AbstractView3DElement; +import eu.engys.gui.view3D.CanvasPanel; + +public class Mesh3DElement extends AbstractView3DElement { + + @Inject + public Mesh3DElement(@Mesh Set panels) { + super(panels); + } + + @Override + public void load(CanvasPanel view3D) { + view3D.getMeshController().newContext(getClass()); + view3D.getGeometryController().newContext(getClass()); + } + +} diff --git a/src/eu/engys/gui/mesh/MeshElement.java b/src/eu/engys/gui/mesh/MeshElement.java new file mode 100644 index 0000000..988ba0f --- /dev/null +++ b/src/eu/engys/gui/mesh/MeshElement.java @@ -0,0 +1,115 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh; + +import java.util.Observable; +import java.util.Observer; +import java.util.Set; + +import javax.inject.Inject; +import javax.swing.SwingUtilities; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.Model; +import eu.engys.core.project.ProjectReader; +import eu.engys.core.project.ProjectWriter; +import eu.engys.gui.Actions; +import eu.engys.gui.GUIPanel; +import eu.engys.gui.mesh.actions.DefaultMeshActions; +import eu.engys.gui.view.AbstractViewElement; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view.ViewElementPanel; +import eu.engys.util.plaf.ILookAndFeel; + +public class MeshElement extends AbstractViewElement { + + private static final Logger logger = LoggerFactory.getLogger(MeshElement.class); + + private ViewElementPanel viewElementPanel; + private Model model; + private Observer modelObserver; + + @Inject + public MeshElement(Model model, @Mesh String title, @Mesh Set panels, Set modules, @Mesh View3DElement view3DElement, @Mesh Actions actions, ILookAndFeel lookAndFeel) { + super(title, panels, modules, view3DElement, actions, lookAndFeel); + this.model = model; + } + + @Override + public void layoutComponents() { + viewElementPanel = new ViewElementPanel(this); + modelObserver = new Observer() { + @Override + public void update(Observable o, Object arg) { + logger.debug("Observerd a change: arg is " + arg.getClass()); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + ((DefaultMeshActions) actions).update(); + } + }); + } + }; + super.layoutComponents(); + } + + @Override + public int getPreferredWidth() { + return 650; + } + + @Override + public ViewElementPanel getPanel() { + return viewElementPanel; + } + + @Override + public void start() { + super.start(); + model.addObserver(modelObserver); + } + + @Override + public void stop() { + model.deleteObserver(modelObserver); + super.stop(); + } + + @Override + public ProjectReader getReader() { + return null; + } + + @Override + public ProjectWriter getWriter() { + return null; + } + +} diff --git a/src/eu/engys/gui/mesh/actions/AddIGES.java b/src/eu/engys/gui/mesh/actions/AddIGES.java new file mode 100644 index 0000000..fb8ef5c --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/AddIGES.java @@ -0,0 +1,153 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.JOptionPane; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; + +import eu.engys.core.controller.actions.RunCommand; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.geometry.stl.ImportIGES; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.util.TempFolder; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.UiUtil; + +public abstract class AddIGES { + + private ProgressMonitor monitor; + private Model model; + + public AddIGES(Model model, ProgressMonitor monitor) { + this.model = model; + this.monitor = monitor; + } + + public void execute() { + IGESFileChooserWrapper fc = new IGESFileChooserWrapper(); + ReturnValue returnedValue = fc.showOpenDialog(); + + if (returnedValue.isApprove()) { + final File[] files = fc.getSelectedFiles(); + final AffineTransform[] transformations = fc.getSelectedTransform(); + final boolean split = fc.getIGESAccessory().getSplit(); + final double precision = fc.getIGESAccessory().getPrecision(); + + boolean filesOK = files != null && files.length > 0; + boolean transformationsOK = transformations != null && transformations.length > 0; + boolean sameLength = transformations.length == files.length; + if (filesOK && transformationsOK && sameLength) { + try { + convertIGES(files, transformations, split, precision); + } catch (IOException e) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Unable to load selected IGES: " + e.getMessage(), "File Type Error", JOptionPane.ERROR_MESSAGE); + } + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Unable to load selected IGES", "File Type Error", JOptionPane.ERROR_MESSAGE); + } + } + } + + public void convertIGES(File[] igesToCopy, final AffineTransform[] transformations, final boolean split, double precision) throws IOException { + final File[] copiedIgesList = new File[igesToCopy.length]; + final File[] createdStlList = new File[igesToCopy.length]; + final File tmpFolder = TempFolder.get(AddIGES.class.getSimpleName()); + + for (int i = 0; i < igesToCopy.length; i++) { + File iges = igesToCopy[i]; + FileUtils.copyFileToDirectory(iges, tmpFolder); + + copiedIgesList[i] = new File(tmpFolder, iges.getName()); + createdStlList[i] = new File(tmpFolder, FilenameUtils.removeExtension(iges.getName()) + ".stl"); + } + + Runnable loadSTLRunnable = new Runnable() { + @Override + public void run() { + monitor.setIndeterminate(false); + monitor.start("Loading IGES Files", false, new Runnable() { + @Override + public void run() { + Map fileMap = getSTLFilesToImport(createdStlList, split); + List keySet = new ArrayList(fileMap.keySet()); + List stls = new ArrayList<>(); + for (int i = 0; i < keySet.size(); i++) { + String key = keySet.get(i); + for (File stlFile : fileMap.get(key)) { + monitor.info(String.format("Loading %s ", stlFile.getAbsolutePath())); + + Stl stl = model.getGeometry().getFactory().readSTL(stlFile, monitor); + stl.setTransformation(transformations[i]); + stls.add(stl); + + } + } + postLoad(stls); + FileUtils.deleteQuietly(tmpFolder); + monitor.end(); + } + }); + } + }; + + RunCommand command = new ImportIGES(model, loadSTLRunnable, copiedIgesList, createdStlList, split, precision); + command.beforeExecute(); + command.executeClient(); + } + + private Map getSTLFilesToImport(File[] createdStlList, boolean split) { + final Map map = new LinkedHashMap(); + for (final File stl : createdStlList) { + if (split) { + File[] stlComponents = stl.getParentFile().listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.startsWith(FilenameUtils.removeExtension(stl.getName())) && name.contains("Component"); + } + }); + map.put(stl.getName(), stlComponents); + } else { + map.put(stl.getName(), new File[] { stl }); + } + } + return map; + } + + public abstract void postLoad(List stls); + +} diff --git a/src/eu/engys/gui/mesh/actions/AddSTL.java b/src/eu/engys/gui/mesh/actions/AddSTL.java new file mode 100644 index 0000000..3b7be8a --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/AddSTL.java @@ -0,0 +1,107 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh.actions; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JOptionPane; + +import org.apache.commons.io.FileUtils; + +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.util.ArchiveUtils; +import eu.engys.util.TempFolder; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.UiUtil; + +public abstract class AddSTL { + + private ProgressMonitor monitor; + private Model model; + + public AddSTL(Model model, ProgressMonitor monitor) { + this.model = model; + this.monitor = monitor; + } + + public void execute() { + STLFileChooserWrapper fc = new STLFileChooserWrapper(); + ReturnValue returnedValue = fc.showOpenDialog(); + + if (returnedValue.isApprove()) { + final File[] files = fc.getSelectedFiles(); + final AffineTransform[] transformations = fc.getSelectedTransform(); + + boolean filesOK = files != null && files.length > 0; + boolean transformationsOK = transformations != null && transformations.length > 0; + boolean sameLength = transformations.length == files.length; + if (filesOK && transformationsOK && sameLength) { + monitor.setIndeterminate(false); + monitor.start("Loading STL Files", false, new Runnable() { + @Override + public void run() { + List stls = new ArrayList<>(); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + AffineTransform transform = transformations[i]; + + if (ArchiveUtils.isArchive(file)) { + File tmpFolder = TempFolder.get(AddSTL.class.getSimpleName()); + + List extractedFiles = ArchiveUtils.unarchive(file, tmpFolder); + for (File target : extractedFiles) { + monitor.info(String.format("Loading %s-%s ", file.getAbsolutePath(), target.getName())); + Stl stl = model.getGeometry().getFactory().readSTL(target, monitor); + stl.setTransformation(transform); + stls.add(stl); + } + FileUtils.deleteQuietly(tmpFolder); + } else { + monitor.info(String.format("Loading %s ", file.getAbsolutePath())); + Stl stl = model.getGeometry().getFactory().readSTL(file, monitor); + stl.setTransformation(transform); + stls.add(stl); + } + } + postLoad(stls); + monitor.end(); + } + }); + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Unable to load selected STLs", "File Type Error", JOptionPane.ERROR_MESSAGE); + } + } + } + + public abstract void postLoad(List stls); + +} diff --git a/src/eu/engys/gui/mesh/actions/DefaultMeshActions.java b/src/eu/engys/gui/mesh/actions/DefaultMeshActions.java new file mode 100644 index 0000000..90c3bc0 --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/DefaultMeshActions.java @@ -0,0 +1,164 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; + +import eu.engys.core.controller.Controller; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.gui.Actions; +import eu.engys.gui.mesh.panels.DefaultMeshAdvancedOptionsPanel; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public abstract class DefaultMeshActions implements Actions { + + public static final String ADVANCED_OPTIONS = "Advanced Options"; + protected Model model; + protected Controller controller; + protected ProgressMonitor monitor; + protected DefaultMeshAdvancedOptionsPanel generalOptionsPanel; + + protected final Action createMesh, checkMesh, deleteMesh, virtualMesh; + + public DefaultMeshActions(Model model, Controller controller, ProgressMonitor monitor, DefaultMeshAdvancedOptionsPanel generalOptionsPanel) { + this.model = model; + this.controller = controller; + this.monitor = monitor; + this.generalOptionsPanel = generalOptionsPanel; + + createMesh = ActionManager.getInstance().get("mesh.create"); + checkMesh = ActionManager.getInstance().get("mesh.check"); + deleteMesh = ActionManager.getInstance().get("mesh.delete"); + virtualMesh = ActionManager.getInstance().get("mesh.batch"); + } + + @Override + public void update() { + createMesh.setEnabled(!model.getGeometry().isEmpty()); + checkMesh.setEnabled(!model.getPatches().isEmpty()); + deleteMesh.setEnabled(!model.getPatches().isEmpty()); + } + + protected final Action openOptionsDialog = new ViewAction(OPEN_OPTIONS_DIALOG_LABEL, OPT_ICON, OPEN_OPTIONS_DIALOG_TOOLTIP) { + + private JDialog dialog; + + public void actionPerformed(ActionEvent e) { + // Commented because there seems to be no reason to save the case + // here + // controller.save(null); + createGeneralOptionsDialog(); + generalOptionsPanel.load(); + dialog.setVisible(true); + } + + private void createGeneralOptionsDialog() { + if (dialog == null) { + dialog = new JDialog(UiUtil.getActiveWindow()); + dialog.setName("general.options.dialog"); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.setName("general.options.panel"); + + JPanel buttonsPanel = new JPanel(new GridLayout(1, 2)); + JPanel leftButtonsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + JPanel rightButtonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonsPanel.add(leftButtonsPanel); + buttonsPanel.add(rightButtonsPanel); + + generalOptionsPanel.layoutPanel(); + mainPanel.add(generalOptionsPanel.getPanel(), BorderLayout.CENTER); + + AbstractAction saveAndCloseDialogAction = new AbstractAction("OK") { + @Override + public void actionPerformed(ActionEvent e) { + generalOptionsPanel.save(); + generalOptionsPanel.handleClose(); + dialog.setVisible(false); + } + }; + + AbstractAction cancelAction = new AbstractAction("Cancel") { + @Override + public void actionPerformed(ActionEvent e) { + generalOptionsPanel.handleClose(); + dialog.setVisible(false); + } + }; + + AbstractAction resetToDefaultsAction = new AbstractAction("Reset") { + @Override + public void actionPerformed(ActionEvent e) { + generalOptionsPanel.resetToDefaults(); + } + }; + + JButton okButton = new JButton(saveAndCloseDialogAction); + okButton.setName("OK"); + rightButtonsPanel.add(okButton); + + JButton cancelButton = new JButton(cancelAction); + cancelButton.setName("Cancel"); + rightButtonsPanel.add(cancelButton); + + JButton resetButton = new JButton(resetToDefaultsAction); + resetButton.setName("Reset"); + leftButtonsPanel.add(resetButton); + + mainPanel.add(buttonsPanel, BorderLayout.SOUTH); + + dialog.setTitle(ADVANCED_OPTIONS); + dialog.add(mainPanel); + dialog.setSize(600, 420); + dialog.setLocationRelativeTo(null); + dialog.setModal(false); + dialog.getRootPane().setDefaultButton(okButton); + } + } + }; + + /** + * Resources + */ + + public static final String OPEN_OPTIONS_DIALOG_LABEL = ResourcesUtil.getString("mesh.options.label"); + public static final String OPEN_OPTIONS_DIALOG_TOOLTIP = ResourcesUtil.getString("mesh.options.tooltip"); + public static final Icon OPT_ICON = ResourcesUtil.getIcon("general.options.icon"); +} diff --git a/src/eu/engys/gui/mesh/actions/IGESAccessory.java b/src/eu/engys/gui/mesh/actions/IGESAccessory.java new file mode 100644 index 0000000..e369c72 --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/IGESAccessory.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions; + +import javax.swing.JCheckBox; + +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; + +public class IGESAccessory extends STLAccessory { + + private JCheckBox split; + private DoubleField precision; + + public IGESAccessory(HelyxFileChooser chooser) { + super(chooser); + } + + @Override + public void layoutOptionsPanel(PanelBuilder optionsBuilder) { + super.layoutOptionsPanel(optionsBuilder); + + split = ComponentsFactory.checkField(); + precision = ComponentsFactory.doubleField(0.01, 0.0, 1.0); + + optionsBuilder.addComponent("Split by Component", split); + optionsBuilder.addComponent("Precision", precision); + } + + public double getPrecision() { + return precision.getDoubleValue(); + } + + public boolean getSplit() { + return split.isSelected(); + } +} diff --git a/src/eu/engys/gui/mesh/actions/IGESFileChooserWrapper.java b/src/eu/engys/gui/mesh/actions/IGESFileChooserWrapper.java new file mode 100644 index 0000000..1fcf7db --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/IGESFileChooserWrapper.java @@ -0,0 +1,78 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh.actions; + +import java.awt.HeadlessException; +import java.io.File; + +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.util.PrefUtil; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.UiUtil; + +public class IGESFileChooserWrapper { + + private IGESAccessory igesAccessory; + private HelyxFileChooser chooser; + public static final HelyxFileFilter IGES_FILTER = new HelyxFileFilter("IGES File (*.igs, *.iges)", "igs", "iges"); + + public IGESFileChooserWrapper() { + chooser = new HelyxFileChooser(PrefUtil.getWorkDir(PrefUtil.LAST_IMPORT_DIR).getAbsolutePath()); + chooser.setTitle("Open IGES"); + chooser.setSelectionMode(SelectionMode.FILES_ONLY); + chooser.setMultiSelectionEnabled(true); + igesAccessory = new IGESAccessory(chooser); + } + + public ReturnValue showOpenDialog() throws HeadlessException { + ReturnValue returnedValue = chooser.showOpenDialog(igesAccessory, UiUtil.getPreferredScreenSize(), IGES_FILTER); + if (returnedValue.isApprove()) { + final File[] files = getSelectedFiles(); + if (files != null && files.length > 0) { + PrefUtil.putFile(PrefUtil.LAST_IMPORT_DIR, files[0].getParentFile()); + } + } + return returnedValue; + } + + public File[] getSelectedFiles() { + if (chooser == null) + return new File[0]; + return chooser.getSelectedFiles(); + } + + public AffineTransform[] getSelectedTransform() { + return igesAccessory.getTransformations(); + } + + public IGESAccessory getIGESAccessory() { + return igesAccessory; + } +} diff --git a/src/eu/engys/gui/mesh/actions/RunBlockMesh.java b/src/eu/engys/gui/mesh/actions/RunBlockMesh.java new file mode 100644 index 0000000..f849f9e --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/RunBlockMesh.java @@ -0,0 +1,143 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.loadEnvironment; +import static eu.engys.core.OpenFOAMEnvironment.printHeader; +import static eu.engys.core.OpenFOAMEnvironment.printVariables; +import static eu.engys.core.project.constant.ConstantFolder.CONSTANT; +import static eu.engys.core.project.constant.ConstantFolder.POLY_MESH; +import static eu.engys.core.project.openFOAMProject.LOG; +import static eu.engys.util.OpenFOAMCommands.BLOCK_MESH; +import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR; + +import java.io.File; +import java.nio.file.Paths; + +import org.apache.commons.io.FileUtils; + +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.Controller.OpenOptions; +import eu.engys.core.controller.ScriptBuilder; +import eu.engys.core.controller.actions.AbstractRunCommand; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.ExecutorHook; +import eu.engys.core.executor.ExecutorListener.ExecutorState; +import eu.engys.core.executor.ExecutorMonitor; +import eu.engys.core.executor.ExecutorTerminal; +import eu.engys.core.executor.TerminalExecutorMonitor; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.util.IOUtils; +import eu.engys.util.Util; + +public class RunBlockMesh extends AbstractRunCommand { + + public static final String ACTION_NAME = "Run Block Mesh"; + + public static final String BLOCK_MESH_LOG = "blockMesh.log"; + public static final String BLOCK_MESH_RUN = "block_mesh.run"; + public static final String BLOCK_MESH_BAT = "block_mesh.bat"; + + private File logFile; + + public RunBlockMesh(Model model, Controller controller) { + super(model, controller); + this.logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, BLOCK_MESH_LOG).toFile(); + } + + @Override + public void beforeExecute() { + IOUtils.clearFile(logFile); + clearPolyMesh(); + setupLogFolder(); + } + + private void clearPolyMesh() { + model.getProject().getZeroFolder().deleteMesh(); + } + + private void setupLogFolder() { + File log = new File(model.getProject().getBaseDir(), openFOAMProject.LOG); + if (!log.exists()) { + log.mkdir(); + } + } + + @Override + public void executeClient() { + File baseDir = model.getProject().getBaseDir(); + File script = getScript(); + + ExecutorTerminal terminal = new TerminalExecutorMonitor(logFile); + ExecutorMonitor monitor = new ExecutorMonitor(); + monitor.addHook(ExecutorState.FINISH, new FinishHook()); + + this.executor = Executor.script(script).description(ACTION_NAME).inFolder(baseDir).inTerminal(terminal).withMonitors(monitor).env(getEnvironment(model, BLOCK_MESH_LOG)); + executor.exec(); + } + + private File getScript() { + File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? BLOCK_MESH_BAT : BLOCK_MESH_RUN); + ScriptBuilder sb = new ScriptBuilder(); + writeScript(sb); + + IOUtils.writeLinesToFile(file, sb.getLines()); + + file.setExecutable(true); + return file; + } + + private void writeScript(ScriptBuilder sb) { + printHeader(sb, ACTION_NAME.toUpperCase()); + printVariables(sb); + loadEnvironment(sb); + writeCommand(sb); + } + + private void writeCommand(ScriptBuilder sb) { + sb.append(BLOCK_MESH()); + if (model.getProject().isParallel()) { + sb.append(DECOMPOSE_PAR()); + } + } + + private class FinishHook implements ExecutorHook { + @Override + public void run(ExecutorMonitor m) { + if (model.getProject().isParallel()) { + File polyMesh = Paths.get(model.getProject().getBaseDir().getAbsolutePath()).resolve(CONSTANT).resolve(POLY_MESH).toFile(); + FileUtils.deleteQuietly(polyMesh); + } + controller.reopenCase(OpenOptions.CURRENT_SETTINGS); + if(controller.getListener() != null){ + controller.getListener().afterBlockMesh(); + } + } + } + +} diff --git a/src/eu/engys/gui/mesh/actions/RunBlockMeshAction.java b/src/eu/engys/gui/mesh/actions/RunBlockMeshAction.java new file mode 100644 index 0000000..414f1ef --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/RunBlockMeshAction.java @@ -0,0 +1,85 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.Icon; + +import eu.engys.core.OpenFOAMEnvironment; +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.actions.RunCommand; +import eu.engys.core.project.Model; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class RunBlockMeshAction extends ViewAction { + + private Model model; + private Controller controller; + + public RunBlockMeshAction(Model model, Controller controller) { + super(BLOCK_LABEL, BLOCK_ICON, BLOCK_TOOLTIP); + this.model = model; + this.controller = controller; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (controller.isDemo()) { + UiUtil.showDemoMessage(); + } else { + if (OpenFOAMEnvironment.isEnvironementLoaded()) { + fixDecomposeParDict(); + controller.saveCase(model.getProject().getBaseDir()); + blockMesh(); + } else { + UiUtil.showCoreEnvironmentNotLoadedWarning(); + } + } + } + + private void blockMesh() { + RunCommand command = new RunBlockMesh(model, controller); + command.beforeExecute(); + command.executeClient(); + } + + private void fixDecomposeParDict() { + model.getProject().getSystemFolder().getDecomposeParDict().toHierarchical(model); + } + + /* + * Resources + */ + + private static final Icon BLOCK_ICON = ResourcesUtil.getIcon("block.mesh.create.icon"); + + private static final String BLOCK_LABEL = ResourcesUtil.getString("block.mesh.create.label"); + private static final String BLOCK_TOOLTIP = ResourcesUtil.getString("block.mesh.create.tooltip"); + +} diff --git a/src/eu/engys/gui/mesh/actions/STLAccessory.java b/src/eu/engys/gui/mesh/actions/STLAccessory.java new file mode 100644 index 0000000..72d1b06 --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/STLAccessory.java @@ -0,0 +1,292 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.io.File; +import java.util.EventObject; + +import javax.swing.DefaultCellEditor; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.text.JTextComponent; + +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.filechooser.gui.Accessory; +import eu.engys.util.ui.CopyPasteSupport; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.groupcolumnheader.ColumnGroup; +import eu.engys.util.ui.groupcolumnheader.GroupableTableColumnModel; +import eu.engys.util.ui.groupcolumnheader.GroupableTableHeader; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; +import eu.engys.util.ui.textfields.StringField; + +public class STLAccessory implements Accessory { + + + public static final String GEOMETRY_IS_IN_MM = "Geometry is in mm"; + public static final String NAME = "stl.accessory"; + + private final String[] COLUMN_NAMES = { "Part Name", "X", "Y", "Z", "X", "Y", "Z", "X", "Y", "Z" }; + private DefaultTableModel tableModel; + private JTable table; + private AffineTransform[] transformations; + private JPanel panel; + private final HelyxFileChooser chooser; + private JCheckBox geometryInMm; + + public STLAccessory(HelyxFileChooser chooser) { + this.chooser = chooser; + + panel = new JPanel(new BorderLayout()); + panel.setName(NAME); + + PanelBuilder optionsBuilder = new PanelBuilder(); + layoutOptionsPanel(optionsBuilder); + layoutTable(); + + panel.add(optionsBuilder.getPanel(), BorderLayout.NORTH); + panel.add(new JScrollPane(table), BorderLayout.CENTER); + + panel.setPreferredSize(new Dimension(600, 600)); + + table.getColumnModel().getColumn(0).setPreferredWidth(120); + + table.getColumnModel().getColumn(1).setPreferredWidth(50); + table.getColumnModel().getColumn(2).setPreferredWidth(50); + table.getColumnModel().getColumn(3).setPreferredWidth(50); + + table.getColumnModel().getColumn(4).setPreferredWidth(50); + table.getColumnModel().getColumn(5).setPreferredWidth(50); + table.getColumnModel().getColumn(6).setPreferredWidth(50); + + table.getColumnModel().getColumn(7).setPreferredWidth(50); + table.getColumnModel().getColumn(8).setPreferredWidth(50); + table.getColumnModel().getColumn(9).setPreferredWidth(50); + + } + + public void layoutOptionsPanel(PanelBuilder optionsBuilder) { + geometryInMm = new JCheckBox(); + geometryInMm.setName("stl.accessory.mm"); + geometryInMm.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + updateScale(geometryInMm.isSelected()); + } + }); + optionsBuilder.addComponent(GEOMETRY_IS_IN_MM, geometryInMm); + } + + private void layoutTable() { + tableModel = new DefaultTableModel(COLUMN_NAMES, 0) { + @Override + public Class getColumnClass(int columnIndex) { + return columnIndex == 0 ? File.class : Double.class; + } + }; + table = new JTable() { + public boolean editCellAt(int row, int column, EventObject e) { + boolean result = super.editCellAt(row, column, e); + final Component editor = getEditorComponent(); + if (e instanceof KeyEvent && editor instanceof JTextComponent) { + ((JTextComponent) editor).selectAll(); + } + + return result; + } + + }; + table.setDefaultRenderer(File.class, new FileRenderer()); + table.setColumnModel(new GroupableTableColumnModel()); + table.setTableHeader(new GroupableTableHeader((GroupableTableColumnModel) table.getColumnModel())); + table.setModel(tableModel); + tableModel.addTableModelListener(new TableModelListener() { + @Override + public void tableChanged(TableModelEvent e) { + if (e.getType() == TableModelEvent.UPDATE) { + saveTransformations(); + } + } + }); + setupEditors(table); + + // Setup Column Groups + GroupableTableColumnModel cm = (GroupableTableColumnModel) table.getColumnModel(); + + ColumnGroup g_trans = new ColumnGroup("Translate"); + g_trans.add(cm.getColumn(1)); + g_trans.add(cm.getColumn(2)); + g_trans.add(cm.getColumn(3)); + + ColumnGroup g_rot = new ColumnGroup("Rotate"); + g_rot.add(cm.getColumn(4)); + g_rot.add(cm.getColumn(5)); + g_rot.add(cm.getColumn(6)); + + ColumnGroup g_scale = new ColumnGroup("Scale"); + g_scale.add(cm.getColumn(7)); + g_scale.add(cm.getColumn(8)); + g_scale.add(cm.getColumn(9)); + + cm.addColumnGroup(g_trans); + cm.addColumnGroup(g_rot); + cm.addColumnGroup(g_scale); + + CopyPasteSupport.addSupportTo(table); + } + + private void updateScale(boolean isInMM) { + for (int r=0; r 0) { + PrefUtil.putFile(PrefUtil.LAST_IMPORT_DIR, files[0].getParentFile()); + } + } + return returnedValue; + } + + public File[] getSelectedFiles() { + if (chooser == null) + return new File[0]; + return chooser.getSelectedFiles(); + } + + public AffineTransform[] getSelectedTransform() { + return stlAccessory.getTransformations(); + } + + public STLAccessory getStlAccessory() { + return stlAccessory; + } +} diff --git a/src/eu/engys/gui/mesh/actions/StandardMeshActions.java b/src/eu/engys/gui/mesh/actions/StandardMeshActions.java new file mode 100644 index 0000000..07d62a6 --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/StandardMeshActions.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh.actions; + +import static eu.engys.util.ui.UiUtil.createToolBarButton; +import static eu.engys.util.ui.UiUtil.createToolBarButtonBar; + +import javax.inject.Inject; +import javax.swing.Box; +import javax.swing.JToolBar; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; +import eu.engys.gui.mesh.panels.DefaultMeshAdvancedOptionsPanel; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.UiUtil; + +public class StandardMeshActions extends DefaultMeshActions { + + @Inject + public StandardMeshActions(Model model, Controller controller, ProgressMonitor monitor, DefaultMeshAdvancedOptionsPanel generalOptionsPanel) { + super(model, controller, monitor, generalOptionsPanel); + } + + @Override + public JToolBar toolbar() { + JToolBar toolbar = UiUtil.getToolbar("view.element.toolbar"); + + toolbar.add(createToolBarButton(createMesh)); + toolbar.add(Box.createHorizontalStrut(2)); + toolbar.add(createToolBarButton(checkMesh)); + toolbar.add(createToolBarButton(deleteMesh)); + toolbar.addSeparator(); + toolbar.add(createToolBarButton(openOptionsDialog)); + toolbar.add(Box.createHorizontalGlue()); + + return toolbar; + } +} diff --git a/src/eu/engys/gui/mesh/actions/geometry/CloneSurfaceAction.java b/src/eu/engys/gui/mesh/actions/geometry/CloneSurfaceAction.java new file mode 100644 index 0000000..9358e1c --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/geometry/CloneSurfaceAction.java @@ -0,0 +1,95 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions.geometry; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.AddSurfaceEvent; +import eu.engys.gui.mesh.panels.AbstractGeometryPanel; +import eu.engys.util.Util; +import eu.engys.util.ui.UiUtil; + +public class CloneSurfaceAction extends AbstractAction { + + public static final String CLONE = "Clone"; + + private Model model; + private Surface[] surfaces; + private AbstractGeometryPanel panel; + + public CloneSurfaceAction(Model model, AbstractGeometryPanel panel) { + super(CLONE); + this.model = model; + this.panel = panel; + } + + public void update(boolean enabled, Surface[] surfaces) { + this.surfaces = surfaces; + Type type = surfaces[0].getType(); + setEnabled(enabled && type != Type.STL && type != Type.SOLID); + } + + @Override + public void actionPerformed(ActionEvent e) { + panel.getTreeNodeManager().getTree().clearSelection(); + new CloneSurface(model, surfaces).execute(); + } + + private class CloneSurface { + private Surface[] surfaces; + private Model model; + + public CloneSurface(Model model, Surface[] surfaces) { + this.model = model; + this.surfaces = surfaces; + } + + public void execute() { + if (Util.isVarArgsNotNull(surfaces)) { + Surface original = surfaces[0]; + Dictionary dictionary = original.toDictionary(); + if (dictionary.isDictionary("surface") && dictionary.isDictionary("volume")) { + Surface surface = model.getGeometry().getFactory().loadSurface(new Dictionary("CopyOf" + dictionary.getName(), original.getGeometryDictionary()), model, null); + surface.fromDictionary(dictionary); + model.getGeometry().addSurface(surface); + model.geometryChanged(surface); + + EventManager.triggerEvent(this, new AddSurfaceEvent(surface)); + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Cannot Clone: Invalid Format", "Clone Error", JOptionPane.ERROR_MESSAGE); + } + } + } + } +} diff --git a/src/eu/engys/gui/mesh/actions/geometry/CopySurfaceAction.java b/src/eu/engys/gui/mesh/actions/geometry/CopySurfaceAction.java new file mode 100644 index 0000000..664106e --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/geometry/CopySurfaceAction.java @@ -0,0 +1,79 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions.geometry; + +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.mesh.panels.AbstractGeometryPanel; +import eu.engys.util.Util; + +public class CopySurfaceAction extends AbstractAction { + + public static final String COPY = "Copy"; + + private Surface[] surfaces; + private AbstractGeometryPanel panel; + + public CopySurfaceAction(AbstractGeometryPanel panel) { + super(COPY); + this.panel = panel; + } + + public void update(boolean enabled, Surface[] surfaces) { + this.surfaces = surfaces; + // Type type = surfaces[0].getType(); + setEnabled(enabled); + } + + @Override + public void actionPerformed(ActionEvent e) { + panel.saveSurfaces(surfaces); + new CopySurface(surfaces).execute(); + } + + private class CopySurface { + private Surface[] surfaces; + + public CopySurface(Surface[] surfaces) { + this.surfaces = surfaces; + } + + public void execute() { + if (Util.isVarArgsNotNull(surfaces)) { + Surface surface = surfaces[0]; + StringSelection contents = new StringSelection(surface.toDictionary().toString()); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, contents); + } else { + // error + } + } + } +} diff --git a/src/eu/engys/gui/mesh/actions/geometry/ExtractLineAction.java b/src/eu/engys/gui/mesh/actions/geometry/ExtractLineAction.java new file mode 100644 index 0000000..d6dde76 --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/geometry/ExtractLineAction.java @@ -0,0 +1,72 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions.geometry; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.mesh.panels.DefaultGeometryActions; +import eu.engys.gui.mesh.panels.DefaultGeometryActions.Disable; +import eu.engys.gui.mesh.panels.DefaultGeometryActions.Enable; +import eu.engys.util.ui.UiUtil; + +public class ExtractLineAction extends AbstractAction { + + public static final String EXTRACT = "Extract"; + public static final String EXTRACT_NAME = EXTRACT + ".Lines"; + + private Model model; + private Surface[] surfaces; + + private DefaultGeometryActions actions; + + private Controller controller; + + public ExtractLineAction(Model model, Controller controller, DefaultGeometryActions actions) { + super(EXTRACT); + this.model = model; + this.controller = controller; + this.actions = actions; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (controller.isDemo()) { + UiUtil.showDemoMessage(); + } else { + new ExtractLinesDialog(UiUtil.getActiveWindow(), model, null).show(surfaces[0], new Disable(actions), new Enable(actions)); + } + } + + public void update(boolean enabled, Surface[] surfaces) { + this.surfaces = surfaces; + setEnabled(enabled && surfaces.length == 1); + } +} diff --git a/src/eu/engys/gui/mesh/actions/geometry/ExtractLinesDialog.java b/src/eu/engys/gui/mesh/actions/geometry/ExtractLinesDialog.java new file mode 100644 index 0000000..3804908 --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/geometry/ExtractLinesDialog.java @@ -0,0 +1,446 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions.geometry; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog.ModalityType; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.JToggleButton; +import javax.swing.SwingConstants; + +import vtk.vtkAppendPolyData; +import vtk.vtkPolyData; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.Region; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.AddSurfaceEvent; +import eu.engys.gui.events.view3D.BoxEvent; +import eu.engys.gui.events.view3D.RemoveSurfaceEvent; +import eu.engys.gui.view3D.Geometry3DController; +import eu.engys.util.ui.CheckBoxPanel; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.StringField; +import eu.engys.vtk.actions.ExtractLines; + +public class ExtractLinesDialog { + + private static final Icon ICON_ON = ResourcesUtil.getResourceIcon("eu/engys/resources/images/lightbulb16.png"); + private static final Icon ICON_OFF = ResourcesUtil.getResourceIcon("eu/engys/resources/images/lightbulb_off16.png"); + + + public static final String EXTRACT_LINES_DIALOG = "extract.lines.dialog"; + + public static final String TITLE = "Extract Feature Lines"; + public static final String FEATURE_ANGLE_LABEL = "Feature Angle"; + public static final String SURFACE_LABEL = "Surface"; + public static final String MANIFOLD_EDGES_LABEL = "Manifold Edges"; + public static final String NON_MANIFOLD_EDGES_LABEL = "Non-manifold Edges"; + public static final String BOUNDARY_EDGES_LABEL = "Boundary Edges"; + public static final String OUTSIDE_KEY = "outside"; + public static final String INSIDE_KEY = "inside"; + + public static final String MIN_LABEL = "Min"; + public static final String MAX_LABEL = "Max"; + public static final String OUTSIDE_LABEL = "Outside"; + public static final String INSIDE_LABEL = "Inside"; + public static final String APPLY_LABEL = "Apply"; + public static final String SAVE_LABEL = "Save"; + public static final String CANCEL_LABEL = "Cancel"; + + public static final String LINE_SUFFIX = "_line"; + + private final Model model; + + private JDialog dialog; + private DoubleField angle; + + private JCheckBox inside; + private DoubleField[] insideBoxMin; + private DoubleField[] insideBoxMax; + + private JCheckBox outside; + private DoubleField[] outsideBoxMin; + private DoubleField[] outsideBoxMax; + private StringField surfacesNameField; + + private Window parent; + + private JCheckBox boundaryEdges; + private JCheckBox nonManifoldEdges; + private JCheckBox manifoldEdges; + + private JToggleButton showInsideButton; + private JToggleButton showOutsideButton; + + private Surface surface; + + private FeatureLine line; + private Runnable onShow; + private Runnable onHide; + private Geometry3DController controller3d; + + // public static void main(String[] args) { + // new HelyxLookAndFeel().init(); + // Model model = new Model(); + // model.init(); + // + // model.getGeometry().addSurface(new Stl("a")); + // + // new ExtractLinesDialog(null, model, null).show(null, null, null); + // } + + public ExtractLinesDialog(Window parent, Model model, Geometry3DController controller3d) { + this.parent = parent; + this.model = model; + this.controller3d = controller3d; + + layoutComponents(); + } + + private void layoutComponents() { + surfacesNameField = ComponentsFactory.stringField(); + surfacesNameField.setEnabled(false); + + angle = ComponentsFactory.doubleField(30.0, 0.0, 180.0); + boundaryEdges = new JCheckBox(BOUNDARY_EDGES_LABEL, true); + nonManifoldEdges = new JCheckBox(NON_MANIFOLD_EDGES_LABEL, true); + manifoldEdges = new JCheckBox(MANIFOLD_EDGES_LABEL, true); + + inside = new JCheckBox(INSIDE_LABEL, false); + insideBoxMin = ComponentsFactory.doublePointField(8, 0.0); + insideBoxMax = ComponentsFactory.doublePointField(8, 1.0); + + outside = new JCheckBox(OUTSIDE_LABEL, false); + outsideBoxMin = ComponentsFactory.doublePointField(8, 0.0); + outsideBoxMax = ComponentsFactory.doublePointField(8, 1.0); + + showInsideButton = getShowBoxButton(insideBoxMin, insideBoxMax); + PanelBuilder insideBuilder = new PanelBuilder(); + insideBuilder.addComponent(MIN_LABEL, insideBoxMin[0], insideBoxMin[1], insideBoxMin[2], showInsideButton); + insideBuilder.addComponentAndSpan(MAX_LABEL, insideBoxMax); + JPanel insidePanel = new CheckBoxPanel(insideBuilder, inside); + insideBuilder.setEnabled(false); + + PanelBuilder outsideBuilder = new PanelBuilder(); + showOutsideButton = getShowBoxButton(outsideBoxMin, outsideBoxMax); + outsideBuilder.addComponent(MIN_LABEL, outsideBoxMin[0], outsideBoxMin[1], outsideBoxMin[2], showOutsideButton); + outsideBuilder.addComponentAndSpan(MAX_LABEL, outsideBoxMax); + JPanel outsidePanel = new CheckBoxPanel(outsideBuilder, outside); + outsideBuilder.setEnabled(false); + + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(SURFACE_LABEL, surfacesNameField); + builder.addComponent(FEATURE_ANGLE_LABEL, angle); + builder.addComponent(boundaryEdges); + builder.addComponent(nonManifoldEdges); + builder.addComponent(manifoldEdges); + builder.addComponent(insidePanel); + builder.addComponent(outsidePanel); + builder.addFill(new JSeparator()); + + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonsPanel.add(new ApplyButton()); + buttonsPanel.add(new SaveButton()); + buttonsPanel.add(new CancelButton()); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(builder.getPanel(), BorderLayout.CENTER); + mainPanel.add(buttonsPanel, BorderLayout.SOUTH); + + setNames(); + + dialog = new JDialog(parent, ModalityType.MODELESS); + dialog.setName(EXTRACT_LINES_DIALOG); + dialog.setTitle(TITLE); + dialog.setSize(500, 420); + dialog.getContentPane().add(mainPanel); + dialog.setResizable(false); + dialog.setLocationRelativeTo(null); + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + closeDialog(); + } + }); + } + + public void show(final Surface surface, Runnable onShow, Runnable onHide) { + this.surface = surface; + this.onShow = onShow; + this.onHide = onHide; + if (this.onShow != null) { + this.onShow.run(); + } + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + surfacesNameField.setText(surface.getName()); + dialog.setVisible(true); + } + }); + } + + private JToggleButton getShowBoxButton(final DoubleField[] min, final DoubleField[] max) { + final JToggleButton button = new JToggleButton(); + button.setAction(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + if (button.isSelected()) { + EventManager.triggerEvent(this, new BoxEvent(min, max, EventActionType.SHOW)); + } else { + EventManager.triggerEvent(this, new BoxEvent(min, max, EventActionType.HIDE)); + } + } + }); + button.setPreferredSize(new Dimension(36, 36)); + button.setIcon(ICON_OFF); + button.setSelectedIcon(ICON_ON); + button.setPressedIcon(ICON_ON); + button.setVerticalAlignment(SwingConstants.TOP); + button.setVerticalTextPosition(SwingConstants.CENTER); + return button; + } + + private void setNames() { + inside.setName(INSIDE_KEY); + showInsideButton.setName(INSIDE_KEY + ".show"); + insideBoxMin[0].setName(INSIDE_KEY + MIN_LABEL + "X"); + insideBoxMin[1].setName(INSIDE_KEY + MIN_LABEL + "Y"); + insideBoxMin[2].setName(INSIDE_KEY + MIN_LABEL + "Z"); + + insideBoxMax[0].setName(INSIDE_KEY + MAX_LABEL + "X"); + insideBoxMax[1].setName(INSIDE_KEY + MAX_LABEL + "Y"); + insideBoxMax[2].setName(INSIDE_KEY + MAX_LABEL + "Z"); + + outside.setName(OUTSIDE_KEY); + showOutsideButton.setName(OUTSIDE_KEY + ".show"); + outsideBoxMin[0].setName(OUTSIDE_KEY + MIN_LABEL + "X"); + outsideBoxMin[1].setName(OUTSIDE_KEY + MIN_LABEL + "Y"); + outsideBoxMin[2].setName(OUTSIDE_KEY + MIN_LABEL + "Z"); + + outsideBoxMax[0].setName(OUTSIDE_KEY + MAX_LABEL + "X"); + outsideBoxMax[1].setName(OUTSIDE_KEY + MAX_LABEL + "Y"); + outsideBoxMax[2].setName(OUTSIDE_KEY + MAX_LABEL + "Z"); + + } + + private void doExtract() { + hideLine(); + line = extractFeatureLines(); + showLine(); + } + + private void showLine() { + if (line != null) { + if (controller3d != null) { + controller3d.addSurfaces(line); + controller3d.render(); + } else { + EventManager.triggerEvent(this, new AddSurfaceEvent(false, line)); + } + } + } + + private void hideLine() { + if (line != null) { + if (controller3d != null) { + controller3d.removeSurfaces(line); + controller3d.render(); + } else { + EventManager.triggerEvent(this, new RemoveSurfaceEvent(false, line)); + } + } + } + + private FeatureLine extractFeatureLines() { + vtkPolyData input = getDatasetFrom(surface); + if (input != null) { + ExtractLines extract = new ExtractLines(); + extract.setInput(input); + extract.setAngle(angle.getDoubleValue()); + extract.setBoundary(boundaryEdges.isSelected()); + extract.setManifold(manifoldEdges.isSelected()); + extract.setNonmanifold(nonManifoldEdges.isSelected()); + + if (inside.isSelected()) { + extract.setInsideMin(new double[] { insideBoxMin[0].getDoubleValue(), insideBoxMin[1].getDoubleValue(), insideBoxMin[2].getDoubleValue() }); + extract.setInsideMax(new double[] { insideBoxMax[0].getDoubleValue(), insideBoxMax[1].getDoubleValue(), insideBoxMax[2].getDoubleValue() }); + } + if (outside.isSelected()) { + extract.setOutsideMin(new double[] { outsideBoxMin[0].getDoubleValue(), outsideBoxMin[1].getDoubleValue(), outsideBoxMin[2].getDoubleValue() }); + extract.setOutsideMax(new double[] { outsideBoxMax[0].getDoubleValue(), outsideBoxMax[1].getDoubleValue(), outsideBoxMax[2].getDoubleValue() }); + } + + vtkPolyData output = extract.execute(); + + String name = model.getGeometry().getALineName(surface.getName() + LINE_SUFFIX); + FeatureLine line = new FeatureLine(name); + line.setModified(true); + line.setDataSet(output); + line.setColor(Color.BLUE); + + return line; + } + + return null; + } + + private vtkPolyData getDatasetFrom(Surface surface) { + vtkPolyData dataset = null; + + if (surface != null) { + if (surface.hasRegions() && surface.getRegions().length > 0) { + if (surface.isSingleton()) { + dataset = surface.getRegions()[0].getTransformedDataSet(); + } else { + vtkAppendPolyData append = new vtkAppendPolyData(); + for (Region region : surface.getRegions()) { + append.AddInputData(region.getTransformedDataSet()); + } + append.Update(); + + dataset = append.GetOutput(); + } + } else { + dataset = surface.getTransformedDataSet(); + } + } + + return dataset; + } + + private void addLine() { + model.getGeometry().addLine(line); + model.geometryChanged(line); + } + + public Component getPanel() { + return dialog.getContentPane(); + } + + public FeatureLine getFeatureLine() { + return line; + } + + private void closeDialog() { + if (showInsideButton.isSelected()) { + showInsideButton.doClick(); + } + + if (showOutsideButton.isSelected()) { + showOutsideButton.doClick(); + } + + if (dialog != null) { + dialog.dispose(); + } + if (this.onHide != null) { + this.onHide.run(); + } + } + + class ApplyButton extends JButton { + public ApplyButton() { + super(new AbstractAction(APPLY_LABEL) { + @Override + public void actionPerformed(ActionEvent e) { + doExtract(); + } + }); + setName(APPLY_LABEL); + } + } + + class SaveButton extends JButton { + public SaveButton() { + super(new AbstractAction(SAVE_LABEL) { + @Override + public void actionPerformed(ActionEvent e) { + + doExtract(); + + addLine(); + + closeDialog(); + } + }); + setName(SAVE_LABEL); + } + } + + class CancelButton extends JButton { + public CancelButton() { + super(new AbstractAction(CANCEL_LABEL) { + @Override + public void actionPerformed(ActionEvent e) { + + hideLine(); + + closeDialog(); + } + }); + setName(CANCEL_LABEL); + } + + } + + /* + * Utils + */ + public void showTest(final Surface surface) { + this.surface = surface; + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + surfacesNameField.setText(surface.getName()); + } + }); + } + +} diff --git a/src/eu/engys/gui/mesh/actions/geometry/PasteSurfaceAction.java b/src/eu/engys/gui/mesh/actions/geometry/PasteSurfaceAction.java new file mode 100644 index 0000000..660d3a5 --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/geometry/PasteSurfaceAction.java @@ -0,0 +1,95 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions.geometry; + +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DictionaryUtils; +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.mesh.panels.AbstractGeometryPanel; +import eu.engys.util.Util; +import eu.engys.util.ui.UiUtil; + +public class PasteSurfaceAction extends AbstractAction { + + public static final String PASTE = "Paste"; + private Surface[] surfaces; + private AbstractGeometryPanel panel; + + public PasteSurfaceAction(AbstractGeometryPanel panel) { + super(PASTE); + this.panel = panel; + } + + public void update(boolean enabled, Surface[] surfaces) { + this.surfaces = surfaces; + // Type type = surfaces[0].getType(); + setEnabled(enabled); + } + + @Override + public void actionPerformed(ActionEvent e) { + panel.getTreeNodeManager().getTree().clearSelection(); + new PasteSurface(surfaces).execute(); + } + + private class PasteSurface { + private Surface[] surfaces; + + public PasteSurface(Surface[] surfaces) { + this.surfaces = surfaces; + } + + public void execute() { + if (Util.isVarArgsNotNull(surfaces)) { + Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this); + try { + String dictionaryString = (String) contents.getTransferData(DataFlavor.stringFlavor); + Dictionary dictionary = DictionaryUtils.readDictionary(dictionaryString).getDictionaries().get(0); + if (dictionary.isDictionary("surface") && dictionary.isDictionary("layer")) { + for (Surface surface : surfaces) { + surface.fromDictionary(dictionary); + } + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Cannot Paste: Invalid Format", "Copy/Paste Error", JOptionPane.ERROR_MESSAGE); + } + } catch (Exception ee) { + ee.printStackTrace(); + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Cannot Paste: An Error Occurred", "Copy/Paste Error", JOptionPane.ERROR_MESSAGE); + } + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Cannot Paste: Empty Selection", "Copy/Paste Error", JOptionPane.ERROR_MESSAGE); + } + } + } +} diff --git a/src/eu/engys/gui/mesh/actions/geometry/RemoveSurfaceAction.java b/src/eu/engys/gui/mesh/actions/geometry/RemoveSurfaceAction.java new file mode 100644 index 0000000..a1ac14d --- /dev/null +++ b/src/eu/engys/gui/mesh/actions/geometry/RemoveSurfaceAction.java @@ -0,0 +1,97 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.actions.geometry; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; + +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.MultiRegion; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.RemoveSurfaceEvent; + +public class RemoveSurfaceAction extends AbstractAction { + + public static final String REMOVE = "Remove"; + + private Model model; + private Surface[] surfaces; + + public RemoveSurfaceAction(Model model) { + super(REMOVE); + this.model = model; + } + + public void update(boolean enabled, Surface[] surfaces) { + this.surfaces = surfaces; + // Type type = surfaces[0].getType(); + // setEnabled(type != Type.SOLID); + setEnabled(enabled); + } + + @Override + public void actionPerformed(ActionEvent e) { + new RemoveSurface(model, surfaces).execute(); + } + + private class RemoveSurface { + private Surface[] surfaces; + private Model model; + + public RemoveSurface(Model model, Surface[] surfaces) { + this.model = model; + this.surfaces = surfaces; + } + + public void execute() { + if (surfaces[0].getType().isSolid()) { + MultiRegion parent = ((Solid) surfaces[0]).getParent(); + for (Surface surface : surfaces) { + Solid solid = (Solid) surface; + parent.removeRegion(solid.getName()); + EventManager.triggerEvent(this, new RemoveSurfaceEvent(solid)); + } + if (parent.getRegions().length > 0) { + parent.setModified(true); + model.geometryChanged(parent); + } else { + model.getGeometry().removeSurfaces(model, parent); + model.geometryChanged(parent); + + EventManager.triggerEvent(this, new RemoveSurfaceEvent(parent)); + } + } else { + model.getGeometry().removeSurfaces(model, surfaces); + model.geometryChanged(surfaces[0]); + + EventManager.triggerEvent(this, new RemoveSurfaceEvent(surfaces)); + } + } + } +} diff --git a/src/eu/engys/gui/mesh/panels/AbstractBaseMeshPanel.java b/src/eu/engys/gui/mesh/panels/AbstractBaseMeshPanel.java new file mode 100644 index 0000000..39e426e --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/AbstractBaseMeshPanel.java @@ -0,0 +1,281 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import static eu.engys.gui.mesh.panels.lines.AutomaticBaseMeshPanel.AUTOMATIC_LABEL; +import static eu.engys.gui.mesh.panels.lines.FromFileBaseMeshPanel.FROM_FILE_LABEL; +import static eu.engys.gui.mesh.panels.lines.UserDefinedBaseMeshPanel.USER_DEFINED_LABEL; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JComponent; +import javax.swing.JOptionPane; + +import eu.engys.core.controller.Controller; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Type; +import eu.engys.core.project.geometry.surface.PlaneRegion; +import eu.engys.core.project.system.BlockMeshDict; +import eu.engys.core.project.system.SnappyHexMeshDict; +import eu.engys.gui.AbstractGUIPanel; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.application.BaseMeshTypeChangedEvent; +import eu.engys.gui.events.view3D.RenameSurfaceEvent; +import eu.engys.gui.mesh.panels.lines.AutomaticBaseMeshPanel; +import eu.engys.gui.mesh.panels.lines.BoundingBoxFacesPanel; +import eu.engys.gui.mesh.panels.lines.FromFileBaseMeshPanel; +import eu.engys.gui.mesh.panels.lines.UserDefinedBaseMeshPanel; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.JComboBoxController; +import eu.engys.util.ui.textfields.StringField; + +public abstract class AbstractBaseMeshPanel extends AbstractGUIPanel { + + public static final String BASE_MESH = "Base Mesh"; + + public static final String BASE_MESH_TYPE_LABEL = "Base Mesh Type"; + + private BaseMeshTreeNodeManager treeNodeManager; + + protected JComboBoxController type; + protected ActionListener typeChangeListener; + + private PlaneRegion[] selectedPlane; + + private Controller controller; + + private AutomaticBaseMeshPanel automaticPanel; + private UserDefinedBaseMeshPanel userDefinedPanel; + private FromFileBaseMeshPanel fromFilePanel; + private BoundingBoxFacesPanel facesPanel; + + public AbstractBaseMeshPanel(Model model, Controller controller) { + super(BASE_MESH, model); + this.controller = controller; + this.treeNodeManager = new BaseMeshTreeNodeManager(model, this); + model.addObserver(treeNodeManager); + } + + protected JComponent layoutComponents() { + DictionaryPanelBuilder builder = new DictionaryPanelBuilder(); + + type = (JComboBoxController) builder.startChoice(BASE_MESH_TYPE_LABEL); + automaticPanel = new AutomaticBaseMeshPanel(model, builder); + userDefinedPanel = new UserDefinedBaseMeshPanel(model, builder); + fromFilePanel = new FromFileBaseMeshPanel(model, controller, builder); + builder.endChoice(); + + facesPanel = new BoundingBoxFacesPanel(new RenamePlaneListener()); + builder.addFill(facesPanel.getPanel()); + + type.addActionListener(typeChangeListener = new BaseMeshTypeChangeListener()); + return builder.removeMargins().getPanel(); + } + + @Override + public void load() { + SnappyHexMeshDict snappyDict = model.getProject().getSystemFolder().getSnappyHexMeshDict(); + BlockMeshDict blockMeshDict = model.getProject().getSystemFolder().getBlockMeshDict(); + if (snappyDict != null) { + loadSpacing(); + + type.removeActionListener(typeChangeListener); + loadBaseMeshType(snappyDict, blockMeshDict); + type.addActionListener(typeChangeListener); + } + } + + protected abstract void loadSpacing(); + + private void loadBaseMeshType(SnappyHexMeshDict snappyDict, BlockMeshDict blockMeshDict) { + userDefinedPanel.resetToDefault(); + if (snappyDict.isAutoBlockMesh()) { + type.setSelectedItem(AUTOMATIC_LABEL); + } else { + if (model.getGeometry().hasBlock()) { + type.setSelectedItem(USER_DEFINED_LABEL); + userDefinedPanel.load(); + } else { + if (blockMeshDict != null && blockMeshDict.isFromFile()) { + type.setSelectedItem(FROM_FILE_LABEL); + } else { + type.setSelectedItem(AUTOMATIC_LABEL); + } + } + } + } + + @Override + public void save() { + if (isUserDefined()) { + userDefinedPanel.save(); + saveSelectedPlane(); + } else if (isFromFile()) { + fromFilePanel.save(); + } else if (isAutomatic()) { + automaticPanel.save(); + } + } + + private void saveSelectedPlane() { + if (selectedPlane != null) { + facesPanel.save(selectedPlane); + } + } + + @Override + public void clear() { + facesPanel.setEnabled(false); + selectedPlane = null; + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } + + private void updateBlock() { + if (isUserDefined()) { + userDefinedPanel.updateBlock(); + } else { + userDefinedPanel.turnOffShowBoxButton(); + if (isAutomatic()) { + automaticPanel.updateBlock(); + } else if (isFromFile()) { + fromFilePanel.updateBlock(); + } + } + } + + @Override + public void stop() { + super.stop(); + userDefinedPanel.turnOffShowBoxButton(); + } + + public void selectPlane(PlaneRegion[] selection) { + if (selection.length == 0) { + clear(); + } else if (selection.length == 1) { + facesPanel.selectPlane(selection); + selectedPlane = selection; + } else { + selectedPlane = selection; + facesPanel.setEnabled(true); + facesPanel.setPlaneName(getMultipleSelectionName()); + facesPanel.disableNameField(); + } + } + + private String getMultipleSelectionName() { + StringBuilder sb = new StringBuilder(); + for (PlaneRegion plane : selectedPlane) { + sb.append(plane.getName()); + sb.append(" "); + } + return sb.toString(); + } + + protected void setBaseMeshSpacing(double baseMeshSpacing) { + automaticPanel.setBaseMeshSpacing(baseMeshSpacing); + } + + protected double getBaseMeshSpacing() { + return automaticPanel.getBaseMeshSpacing(); + } + + public void saveSurfaces(PlaneRegion[] selection) { + Type type = selection[0].getType(); + List planes = new ArrayList<>(); + for (PlaneRegion plane : selection) { + if (plane.getType() != type) + continue; /* uniform selection */ + planes.add(plane); + } + facesPanel.save(planes.toArray(new PlaneRegion[0])); + } + + protected boolean isUserDefined() { + return String.valueOf(type.getSelectedItem()).equals(USER_DEFINED_LABEL); + } + + protected boolean isFromFile() { + return String.valueOf(type.getSelectedItem()).equals(FROM_FILE_LABEL); + } + + protected boolean isAutomatic() { + return String.valueOf(type.getSelectedItem()).equals(AUTOMATIC_LABEL); + } + + private class BaseMeshTypeChangeListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + // To tell the Controller to delete mesh scripts + EventManager.triggerEvent(this, new BaseMeshTypeChangedEvent()); + updateBlock(); + save(); + } + } + + private class RenamePlaneListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value") && evt.getSource() instanceof StringField) { + renamePlane(selectedPlane[0]); + } + } + + private void renamePlane(PlaneRegion plane) { + if (plane != null) { + String oldPatchName = plane.getPatchName(); + + String newName = facesPanel.getPlaneName(); + + if (model.getGeometry().contains(newName)) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Name already in use", "Name Error", JOptionPane.ERROR_MESSAGE); + return; + } + + plane.rename(newName); + String newPatchName = plane.getPatchName(); + plane.getParent().renameRegion(oldPatchName, newPatchName); + + treeNodeManager.getTree().repaint(); + + EventManager.triggerEvent(this, new RenameSurfaceEvent(plane, oldPatchName, newPatchName)); + } + } + + } + +} diff --git a/src/eu/engys/gui/mesh/panels/AbstractGeometryPanel.java b/src/eu/engys/gui/mesh/panels/AbstractGeometryPanel.java new file mode 100644 index 0000000..1c0f1a1 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/AbstractGeometryPanel.java @@ -0,0 +1,502 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import eu.engys.core.controller.Controller; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.presentation.Action; +import eu.engys.core.presentation.ActionContainer; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.gui.AbstractGUIPanel; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.AddSurfaceEvent; +import eu.engys.gui.events.view3D.ChangeSurfaceEvent; +import eu.engys.gui.events.view3D.RenameSurfaceEvent; +import eu.engys.gui.mesh.GeometryPanel; +import eu.engys.gui.mesh.actions.AddIGES; +import eu.engys.gui.mesh.actions.AddSTL; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.util.Util; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.JComboBoxController; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; + +public abstract class AbstractGeometryPanel extends AbstractGUIPanel implements GeometryPanel, ActionContainer { + + public static final String ZONES_LABEL = "Zones"; + public static final String LAYERS_LABEL = "Layers"; + public static final String REFINEMENT_LABEL = "Refinement"; + public static final String GEOMETRY = "Geometry"; + + public static final String DISTANCE_M_LABEL = "Distance [m]"; + + public static final String SURFACE_LABEL = "Surface"; + public static final String BAFFLE_LABEL = "Baffle"; + public static final String BOUNDARY_LABEL = "Boundary"; + public static final String INTERNAL_LABEL = "Internal"; + public static final String TYPE_LABEL = "Type"; + public static final String NAME_LABEL = "Name"; + public static final String CELL_ZONE_LABEL = "Cell Zone"; + public static final String LEVEL_LABEL = "Level"; + public static final String PROXIMITY_REFINEMENT_LABEL = "Proximity Refinement"; + public static final String FINAL_LAYER_THICKNESS_LABEL = "Final Layer Thickness"; + public static final String LAYER_STRETCHING_LABEL = "Layer Stretching"; + public static final String NUMBER_OF_LAYERS_LABEL = "Number of Layers"; + public static final String CELL_SIZE_LABEL = "Cell Size [m]"; + + public static final String INSIDE_LEVEL_LABEL = "Inside Level"; + public static final String OUTSIDE_LEVEL_LABEL = "Outside Level"; + public static final String DISTANCE_LEVEL_LABEL = "Distance Level"; + + public static final String MODE_LABEL = "Mode"; + public static final String NONE = "none"; + public static final String INSIDE = "inside"; + public static final String OUTSIDE = "outside"; + public static final String DISTANCE = "distance"; + public static final String NONE_LABEL = "None"; + public static final String INSIDE_LABEL = "Inside"; + public static final String OUTSIDE_LABEL = "Outside"; + public static final String DISTANCE_LABEL = "Distance"; + + private GeometryBuilder surfaceRegionsBuilder; + + protected DictionaryModel surfaceModel; + protected DictionaryModel volumeModel; + protected DictionaryModel layerModel; + protected DictionaryModel zoneModel; + + private GeometriesPanelBuilder geometriesPanel; + + protected PanelBuilder layersBuilder; + protected PanelBuilder surfaceBuilder; + protected PanelBuilder volumesBuilder; + protected PanelBuilder zonesBuilder; + + private JTabbedPane tabbedPane; + + protected final GeometryTreeNodeManager treeNodeManager; + + public AbstractGeometryPanel(Model model, Controller controller) { + super(GEOMETRY, model); + this.treeNodeManager = new GeometryTreeNodeManager(model, controller, this, getGeometryActions(controller)); + model.addObserver(treeNodeManager); + ActionManager.getInstance().parseActions(this); + } + + protected abstract DefaultGeometryActions getGeometryActions(Controller controller); + + @Override + protected JComponent layoutComponents() { + surfaceModel = new DictionaryModel(); + volumeModel = new DictionaryModel(); + layerModel = new DictionaryModel(); + zoneModel = new DictionaryModel(); + + geometriesPanel = new GeometriesPanelBuilder(this); + surfaceRegionsBuilder = new GeometryBuilder(geometriesPanel, surfaceModel, volumeModel, layerModel, zoneModel); + + tabbedPane = new JTabbedPane(); + tabbedPane.setName("geometry.tabbed.pane"); + tabbedPane.putClientProperty("Synthetica.tabbedPane.tabIndex", 0); + + JPanel refinemetPanel = getRefinemetPanel(); + JPanel layersPanel = getLayersPanel(); + JPanel zonesPanel = getZonesPanel(); + + refinemetPanel.setName("refinement.panel"); + layersPanel.setName("layers.panel"); + zonesPanel.setName("zones.panel"); + + tabbedPane.addTab(REFINEMENT_LABEL, refinemetPanel); + tabbedPane.addTab(LAYERS_LABEL, layersPanel); + tabbedPane.addTab(ZONES_LABEL, zonesPanel); + + PanelBuilder builder = new PanelBuilder(); + builder.addButtons(getShapeButtons()); + builder.addSeparator(""); + geometriesPanel.addComponents(builder); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(builder.removeMargins().getPanel(), BorderLayout.NORTH); + mainPanel.add(tabbedPane, BorderLayout.CENTER); + + tabbedPane.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + saveSurfaces(treeNodeManager.getSelectedValues()); + selectSurface(treeNodeManager.getSelectedValues()); + } + }); + + return mainPanel; + } + + protected abstract JButton[] getShapeButtons(); + + private JPanel getRefinemetPanel() { + PanelBuilder builder = new PanelBuilder(); + + JPanel surfacesPanel = getSurfacesPanel(); + JPanel volumesPanel = getVolumesPanel(); + + surfacesPanel.setName("refinement.surfaces"); + volumesPanel.setName("refinement.volumes"); + + builder.addComponent(surfacesPanel); + builder.addComponent(volumesPanel); + return builder.getPanel(); + } + + protected abstract JPanel getSurfacesPanel(); + + protected JPanel getVolumesPanel() { + volumesBuilder = new PanelBuilder(); + final JComboBoxController comboBoxController = volumeModel.bindComboBoxController("mode"); + volumesBuilder.startChoice(MODE_LABEL, comboBoxController); + + volumesBuilder.startGroup(NONE, NONE_LABEL); + volumesBuilder.endGroup(); + + volumesBuilder.startGroup(INSIDE, INSIDE_LABEL); + IntegerField inside = volumeModel.bindIntegerLevels("levels", INSIDE); + volumesBuilder.addComponent(INSIDE_LEVEL_LABEL, inside); + volumesBuilder.addComponent(CELL_SIZE_LABEL, new Size(model, inside)); + volumesBuilder.endGroup(); + + volumesBuilder.startGroup(OUTSIDE, OUTSIDE_LABEL); + IntegerField outside = volumeModel.bindIntegerLevels("levels", OUTSIDE); + volumesBuilder.addComponent(OUTSIDE_LEVEL_LABEL, outside); + volumesBuilder.addComponent(CELL_SIZE_LABEL, new Size(model, outside)); + volumesBuilder.endGroup(); + + volumesBuilder.startGroup(DISTANCE, DISTANCE_LABEL); + String[] columnNames = { DISTANCE_M_LABEL, LEVEL_LABEL }; + Class[] type = { Double.class, Integer.class }; + volumesBuilder.addComponent(DISTANCE_LEVEL_LABEL, volumeModel.bindTableLevels(columnNames, type)); + volumesBuilder.endGroup(); + + volumesBuilder.endChoice(); + + comboBoxController.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + boolean distanceRefinementOrNone = isDistanceRefinementOrNone(comboBoxController.getSelectedKey()); + surfaceBuilder.setEnabled(distanceRefinementOrNone || isCellZone()); + layersBuilder.setEnabled(distanceRefinementOrNone || isCellZone()); + } + }); + volumesBuilder.getPanel().setBorder(BorderFactory.createTitledBorder("Volumetric")); + return volumesBuilder.getPanel(); + } + + protected boolean isCellZone() { + return false; + } + + protected JPanel getLayersPanel() { + return new JPanel(); + } + + protected JPanel getZonesPanel() { + return new JPanel(); + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } + + @Override + public void save() { + super.save(); + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) treeNodeManager.getSelectedValues()); + model.getGeometry().saveGeometry(model); + } + + @Override + public void stop() { + super.stop(); + geometriesPanel.stop(); + } + + public void saveSurfaces(Surface[] surfaces) { + surfaceRegionsBuilder.buildSurfaces(surfaces); + } + + @Override + public void changeSurface(Surface surface) { + surfaceRegionsBuilder.buildSurfaces(surface); + EventManager.triggerEvent(this, new ChangeSurfaceEvent(surface, false)); + } + + @Override + public void renameSurface(String newName) { + Surface[] selection = treeNodeManager.getSelectedValues(); + if (selection.length == 1) { + Surface surface = selection[0]; + + if (model.getGeometry().contains(newName)) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Name already in use", "Name Error", JOptionPane.ERROR_MESSAGE); + return; + } + + String oldPatchName = surface.getPatchName(); + surface.rename(newName); + + surfaceRegionsBuilder.buildSurfaces(surface); + + treeNodeManager.refreshNode(surface); + + EventManager.triggerEvent(this, new RenameSurfaceEvent(surface, oldPatchName, surface.getPatchName())); + } + } + + @Override + public void clear() { + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) new Surface[0]); + } + + @Action(key = "mesh.stl") + public void addSTL() { + new AddSTL(model, monitor) { + @Override + public void postLoad(List stls) { + addSTL(stls.toArray(new Stl[0])); + } + }.execute(); + } + + @Action(key = "mesh.igs") + public void addIGES() { + new AddIGES(model, monitor) { + @Override + public void postLoad(List stls) { + addSTL(stls.toArray(new Stl[0])); + } + }.execute(); + } + + public void addSTL(Stl... stls) { + if (Util.isVarArgsNotNull(stls)) { + for (Stl stl : stls) { + getModel().getGeometry().addSurface(stl); + getModel().geometryChanged(stl); + } + EventManager.triggerEvent(this, new AddSurfaceEvent(stls)); + } + } + + @Action(key = "mesh.box") + public void addBox() { + treeNodeManager.clear(); + Surface box = model.getGeometry().getABox(); + + getModel().getGeometry().addSurface(box); + getModel().geometryChanged(box); + + EventManager.triggerEvent(this, new AddSurfaceEvent(box)); + } + + @Action(key = "mesh.cylinder") + public void addCylinder() { + treeNodeManager.clear(); + Surface cyl = model.getGeometry().getACylinder(); + + getModel().getGeometry().addSurface(cyl); + getModel().geometryChanged(cyl); + + EventManager.triggerEvent(this, new AddSurfaceEvent(cyl)); + } + + @Action(key = "mesh.sphere") + public void addSphere() { + treeNodeManager.clear(); + Surface sphere = model.getGeometry().getASphere(); + + getModel().getGeometry().addSurface(sphere); + getModel().geometryChanged(sphere); + + EventManager.triggerEvent(this, new AddSurfaceEvent(sphere)); + } + + @Action(key = "mesh.plane") + public void addPlane() { + treeNodeManager.clear(); + Surface plane = model.getGeometry().getAPlane(); + + getModel().getGeometry().addSurface(plane); + getModel().geometryChanged(plane); + + EventManager.triggerEvent(this, new AddSurfaceEvent(plane)); + } + + @Action(key = "mesh.ring") + public void addRing() { + treeNodeManager.clear(); + Surface ring = model.getGeometry().getARing(); + + getModel().getGeometry().addSurface(ring); + getModel().geometryChanged(ring); + + EventManager.triggerEvent(this, new AddSurfaceEvent(ring)); + } + + private boolean hasDistanceRefinementOrNone(Surface surface) { + Dictionary volumeDictionary = surface.getVolumeDictionary(); + if (volumeDictionary.found("mode")) { + String mode = volumeDictionary.lookup("mode"); + return isDistanceRefinementOrNone(mode); + } + return true; + } + + private boolean isDistanceRefinementOrNone(String mode) { + return mode == null || "distance".equals(mode) || "none".equals(mode); + } + + public void selectSurface(Surface[] surfaces) { + if (Util.isVarArgsNotNull(surfaces)) { + geometriesPanel.showPanel(surfaces); + + updateGUIOnSelection(surfaces[0]); + + selectATab(); + + Dictionary surfaceDictionary = surfaces[0].getSurfaceDictionary(); + Dictionary volumeDictionary = surfaces[0].getVolumeDictionary(); + Dictionary layerDictionary = surfaces[0].getLayerDictionary(); + Dictionary zoneDictionary = surfaces[0].getZoneDictionary(); + + // System.out.println("DefaultGeometryPanel.selectSurface() "+surfaceDictionary+volumeDictionary+layerDictionary); + + surfaceModel.setDictionary(new Dictionary(surfaceDictionary)); + volumeModel.setDictionary(new Dictionary(volumeDictionary)); + layerModel.setDictionary(new Dictionary(layerDictionary)); + zoneModel.setDictionary(new Dictionary(zoneDictionary)); + } else { + deselectAll(); + } + } + + public void deselectAll() { + geometriesPanel.showPanel(null); + + surfaceModel.setDictionary(new Dictionary("")); + volumeModel.setDictionary(new Dictionary("")); + layerModel.setDictionary(new Dictionary("")); + zoneModel.setDictionary(new Dictionary("")); + + updateGUIOnSelection(null); + } + + protected void updateGUIOnSelection(Surface surface) { + if (surface == null) { + surfaceBuilder.setEnabled(false); + volumesBuilder.setEnabled(false); + layersBuilder.setEnabled(false); + zonesBuilder.setEnabled(false); + } else { + surfaceBuilder.setEnabled(true); + volumesBuilder.setEnabled(true); + layersBuilder.setEnabled(true); + zonesBuilder.setEnabled(true); + + surfaceBuilder.setEnabled(surface.hasSurfaceRefinement() && hasDistanceRefinementOrNone(surface)); + volumesBuilder.setEnabled(surface.hasVolumeRefinement()); + layersBuilder.setEnabled(surface.hasLayers()); + zonesBuilder.setEnabled(surface.hasZones()); + } + } + + private void selectATab() { + if (tabbedPane.isEnabledAt(tabbedPane.getSelectedIndex())) + return; + for (int i = 0; i < tabbedPane.getTabCount(); i++) { + if (tabbedPane.isEnabledAt(i)) { + tabbedPane.setSelectedIndex(i); + return; + } + } + } + + @Override + public boolean isDemo() { + return false; + } + + public static class Size extends DoubleField { + private Model model; + private IntegerField level; + + public Size(Model model, IntegerField level) { + super(3); + this.model = model; + this.level = level; + setEnabled(false); + PropertyChangeListener listener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + recalculate(); + } + } + }; + level.addPropertyChangeListener(listener); + } + + public void recalculate() { + if (level.getValue() != null) { + double[] d1 = model.getGeometry().getCellSize(level.getIntValue()); + setDoubleValue(d1[0]); + } else { + setValue(null); + } + } + } + +} diff --git a/src/eu/engys/gui/mesh/panels/BaseMeshTreeNodeManager.java b/src/eu/engys/gui/mesh/panels/BaseMeshTreeNodeManager.java new file mode 100644 index 0000000..2dfdddb --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/BaseMeshTreeNodeManager.java @@ -0,0 +1,267 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import java.awt.Component; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; + +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreePath; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Geometry; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.MultiPlane; +import eu.engys.core.project.geometry.surface.PlaneRegion; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.SelectSurfaceEvent; +import eu.engys.gui.tree.AbstractSelectionHandler; +import eu.engys.gui.tree.DefaultTreeNodeManager; +import eu.engys.gui.tree.SelectionHandler; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Geometry3DController; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.Util; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.TreeUtil; +import eu.engys.util.ui.checkboxtree.RootVisibleItem; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class BaseMeshTreeNodeManager extends DefaultTreeNodeManager { + + private static final Logger logger = LoggerFactory.getLogger(BaseMeshTreeNodeManager.class); + + private Map surfaceMap; + private SelectionHandler selectionHandler; + + public BaseMeshTreeNodeManager(Model model, AbstractBaseMeshPanel panel) { + super(model, panel); + this.selectionHandler = new BlockMeshSelectionHandler(panel); + this.surfaceMap = new HashMap<>(); + } + + @Override + public void update(Observable o, final Object arg) { + if (arg instanceof MultiPlane || arg instanceof Geometry) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + loadTree(); + selectVisibleItems(); + expandTree(); + } + }); + } else if (arg instanceof Patches) { + selectVisibleItems(); + } + } + + private void loadTree() { + clear(); + + if (model.getGeometry().hasBlock()) { + MultiPlane block = model.getGeometry().getBlock(); + DefaultMutableTreeNode parentNode = new DefaultMutableTreeNode(new RootVisibleItem(block.getName())); + root.add(parentNode); + + for (Surface region : block.getRegions()) { + addSurface(parentNode, region); + } + treeChanged(root); + } + } + + private void selectVisibleItems() { + if (model.getPatches().isEmpty()) + getTree().getCheckManager().selectNode(getRoot()); + else + getTree().getCheckManager().deselectNode(getRoot()); + } + + private void expandTree() { + if (getTree() != null) { + if (model.getGeometry().hasBlock()) { + getTree().expandNode(getRoot()); + } + } + } + + private void addSurface(DefaultMutableTreeNode parent, Surface surface) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(surface); + parent.add(node); + nodeMap.put(surface, node); + surfaceMap.put(node, surface); + } + + public Surface[] getSelectedValues() { + if (getTree() != null) { + TreePath[] selectionPaths = getTree().getSelectionPaths(); + Surface[] surfaces = new Surface[selectionPaths.length]; + for (int i = 0; i < selectionPaths.length; i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPaths[i].getLastPathComponent(); + Surface surface = surfaceMap.get(node); + surfaces[i] = surface; + } + return surfaces; + } + return new Surface[0]; + } + + public void clear() { + // clear node before selection handler! + clearNode(root); + selectionHandler.clear(); + nodeMap.clear(); + surfaceMap.clear(); + } + + public DefaultMutableTreeNode getRoot() { + return root; + } + + @Override + public Class getRendererClass() { + return PlaneRegion.class; + } + + public DefaultTreeCellRenderer getRenderer() { + return new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObject = node.getUserObject(); + + if (userObject instanceof PlaneRegion) { + PlaneRegion surface = (PlaneRegion) userObject; + setText(surface.getName()); + } + setIcon(null); + return this; + } + }; + } + + @Override + public SelectionHandler getSelectionHandler() { + return selectionHandler; + } + + private final class BlockMeshSelectionHandler extends AbstractSelectionHandler { + private PlaneRegion[] currentSelection; + private AbstractBaseMeshPanel panel; + + public BlockMeshSelectionHandler(AbstractBaseMeshPanel panel) { + this.panel = panel; + } + + @Override + public void handleSelection(boolean fire3DEvent, Object... selection) { + saveCurrentSelection(); + + boolean isValidSelection = TreeUtil.isConsistent(selection, PlaneRegion.class); + if (isValidSelection) { + handleValidSelection(fire3DEvent, selection); + } else { + boolean shouldClearSelection = TreeUtil.isConsistent(currentSelection, PlaneRegion.class); + if(shouldClearSelection){ + clearSelection(fire3DEvent); + } + } + } + + private void saveCurrentSelection() { + if (Util.isVarArgsNotNull(currentSelection)) { + panel.saveSurfaces(currentSelection); + } + } + + private void handleValidSelection(boolean fire3DEvent, Object... selection) { + logger.debug("handleSelection: {} selected, fire3D {} {}", selection.length, fire3DEvent, selection.length == 1 ? ", selection is: " + selection[0] : ""); + + // update current selection + this.currentSelection = Arrays.copyOf(selection, selection.length, PlaneRegion[].class); + panel.selectPlane(currentSelection); + + if (fire3DEvent) { + EventManager.triggerEvent(this, new SelectSurfaceEvent(currentSelection)); + } + } + + private void clearSelection(boolean fire3DEvent) { + clear(); + panel.clear(); + if (fire3DEvent) { + EventManager.triggerEvent(this, new SelectSurfaceEvent(new PlaneRegion[0])); + } + } + + @Override + public void handleVisibility(VisibleItem item) { + if (Util.isVarArgsNotNull(currentSelection) && Arrays.asList(currentSelection).contains(item)) { + panel.selectPlane(currentSelection); + EventManager.triggerEvent(this, new SelectSurfaceEvent(currentSelection)); + } + + } + + @Override + public void process3DSelectionEvent(Picker picker, Actor actor, boolean keep) { + if (getTree() != null && picker instanceof Geometry3DController && actor.getVisibleItem() instanceof Surface) { + Surface surface = (Surface) actor.getVisibleItem(); + DefaultMutableTreeNode selectedNode = nodeMap.get(surface); + if (selectedNode != null) { + getTree().setSelectedNode(selectedNode); + } + } + } + + @Override + public void process3DVisibilityEvent(boolean selected) { + if (getTree() != null) { + if (selected) { + // getTree().getCheckManager().selectNode(getRoot()); + } else { + getTree().getCheckManager().deselectNode(getRoot()); + } + } + } + + public void clear() { + currentSelection = null; + } + } + +} diff --git a/src/eu/engys/gui/mesh/panels/BoundaryMeshTreeNodeManager.java b/src/eu/engys/gui/mesh/panels/BoundaryMeshTreeNodeManager.java new file mode 100644 index 0000000..08dc7e7 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/BoundaryMeshTreeNodeManager.java @@ -0,0 +1,263 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import java.awt.Component; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; + +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.cellzones.CellZones; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.gui.GUIPanel; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.SelectCellZonesEvent; +import eu.engys.gui.events.view3D.SelectPatchesEvent; +import eu.engys.gui.tree.AbstractSelectionHandler; +import eu.engys.gui.tree.DefaultTreeNodeManager; +import eu.engys.gui.tree.SelectionHandler; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.TreeUtil; +import eu.engys.util.ui.checkboxtree.RootVisibleLoadableTreeNode; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class BoundaryMeshTreeNodeManager extends DefaultTreeNodeManager { + + private static final Logger logger = LoggerFactory.getLogger(BoundaryMeshTreeNodeManager.class); + + private Map patchesMap; + private Map cellZonesMap; + + private SelectionHandler selectionHandler; + private DefaultMutableTreeNode patches; + private DefaultMutableTreeNode cellZones; + + public BoundaryMeshTreeNodeManager(Model model, GUIPanel panel) { + super(model, panel); + this.root = new RootVisibleLoadableTreeNode(panel.getTitle()); + this.selectionHandler = new BoundaryMeshSelectionHandler(); + this.patchesMap = new HashMap<>(); + this.cellZonesMap = new HashMap<>(); + + patches = new RootVisibleLoadableTreeNode("Patches"); + cellZones = new RootVisibleLoadableTreeNode("Cell Zones"); + root.add(patches); + root.add(cellZones); + } + + @Override + public void update(Observable o, final Object arg) { + if (arg instanceof Patches || arg instanceof CellZones) { + logger.debug("Observerd a change: arg is " + arg.getClass()); + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + selectionHandler.disable(); + loadTree(); + makeVisibleItemsChecked(); + expandTree(); + selectionHandler.enable(); + } + }); + } + } + + private void loadTree() { + logger.debug("Load 'Mesh' tree"); + clear(); + for (Patch patch : model.getPatches().patchesToDisplay()) { + addPatch(patches, patch); + } + for (CellZone zone : model.getCellZones()) { + addCellZone(cellZones, zone); + } + + treeChanged(root); + } + + private void makeVisibleItemsChecked() { + logger.debug("Make visible items checked: DO NOTHING!"); + } + + private void expandTree() { + getTree().expandNode(getRoot()); + } + + private void addPatch(DefaultMutableTreeNode parent, Patch patch) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(patch); + parent.add(node); + nodeMap.put(patch, node); + patchesMap.put(node, patch); + } + + private void addCellZone(DefaultMutableTreeNode parent, CellZone zone) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(zone); + parent.add(node); + nodeMap.put(zone, node); + cellZonesMap.put(node, zone); + } + + public void setSelectedValue(String name) { + } + + public void clear() { + // clear node before selection handler! + clearNode(patches); + clearNode(cellZones); + selectionHandler.clear(); + nodeMap.clear(); + patchesMap.clear(); + cellZonesMap.clear(); + } + + public DefaultMutableTreeNode getRoot() { + return root; + } + + @Override + public Class getRendererClass() { + return VisibleItem.class; + } + + public DefaultTreeCellRenderer getRenderer() { + return new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObject = node.getUserObject(); + + if (userObject instanceof VisibleItem) { + VisibleItem item = (VisibleItem) userObject; + setText(item.getName()); + } + setIcon(null); + return this; + } + }; + } + + @Override + public SelectionHandler getSelectionHandler() { + return selectionHandler; + } + + private final class BoundaryMeshSelectionHandler extends AbstractSelectionHandler { + + private VisibleItem[] currentSelection; + + @Override + public void handleSelection(boolean fire3DEvent, Object... selection) { + boolean isValidPatchSelection = TreeUtil.isConsistent(selection, Patch.class) && fire3DEvent; + boolean isValidCellZoneSelection = TreeUtil.isConsistent(selection, CellZone.class) && fire3DEvent; + if (isValidPatchSelection) { + handleValidPatchSelection(fire3DEvent, selection); + } else if (isValidCellZoneSelection) { + handleValidZoneSelection(fire3DEvent, selection); + } else { + handleInvalidSelection(); + } + } + + private void handleValidPatchSelection(boolean fire3DEvent, Object... selection) { + logger.debug("handleSelection: {} selected, fire3D {} {}", selection.length, fire3DEvent, selection.length == 1 ? ", selection is: " + selection[0] : ""); + + this.currentSelection = Arrays.copyOf(selection, selection.length, Patch[].class); + EventManager.triggerEvent(this, new SelectPatchesEvent((Patch[]) currentSelection)); + } + + private void handleValidZoneSelection(boolean fire3DEvent, Object... selection) { + logger.debug("handleSelection: {} selected, fire3D {} {}", selection.length, fire3DEvent, selection.length == 1 ? ", selection is: " + selection[0] : ""); + + this.currentSelection = Arrays.copyOf(selection, selection.length, CellZone[].class); + EventManager.triggerEvent(this, new SelectCellZonesEvent((CellZone[]) currentSelection)); + } + + private void handleInvalidSelection() { + boolean shouldClearPatchesSelection = TreeUtil.isConsistent(currentSelection, Patch.class); + boolean shouldClearZoneSelection = TreeUtil.isConsistent(currentSelection, CellZone.class); + + if (shouldClearPatchesSelection) { + EventManager.triggerEvent(this, new SelectPatchesEvent(new Patch[0])); + } else if (shouldClearZoneSelection) { + EventManager.triggerEvent(this, new SelectCellZonesEvent(new CellZone[0])); + } + } + + @Override + public void handleVisibility(VisibleItem item) { + logger.debug("handleVisibility: {}", item); + } + + @Override + public void process3DSelectionEvent(Picker picker, Actor actor, boolean keep) { + if (getTree() != null && picker.canPickMesh()) { + VisibleItem visibleItem = actor.getVisibleItem(); + DefaultMutableTreeNode selectedNode = nodeMap.get(visibleItem); + logger.debug("Handle selection from 3D {}", actor.getName()); + if (selectedNode != null) { + if (keep) { + getTree().addSelectedNode(selectedNode); + } else { + getTree().setSelectedNode(selectedNode); + } + } + } + } + + @Override + public void process3DVisibilityEvent(boolean selected) { + if (getTree() != null) { + if (selected) { + getTree().getCheckManager().selectNode(patches); + getTree().getCheckManager().selectNode(cellZones); + } else { + getTree().getCheckManager().deselectNode(patches); + getTree().getCheckManager().deselectNode(cellZones); + } + } + } + + @Override + public void clear() { + currentSelection = null; + } + } + +} diff --git a/src/eu/engys/gui/mesh/panels/DefaultBoundaryMeshPanel.java b/src/eu/engys/gui/mesh/panels/DefaultBoundaryMeshPanel.java new file mode 100644 index 0000000..d0be45a --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/DefaultBoundaryMeshPanel.java @@ -0,0 +1,232 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh.panels; + +import static eu.engys.util.ui.ComponentsFactory.labelField; + +import java.awt.Dimension; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JTextArea; + +import net.java.dev.designgridlayout.Componentizer; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.gui.AbstractGUIPanel; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.builder.PanelBuilder; + +public class DefaultBoundaryMeshPanel extends AbstractGUIPanel { + + public static final String TITLE = "Mesh"; + private static final DecimalFormat formatter = new DecimalFormat("#.###", new DecimalFormatSymbols(Locale.US)); + + private BoundaryMeshTreeNodeManager treeNodeManager; + + private JLabel name; + private JLabel path; + private JLabel created; + private JLabel cells; + private JLabel points; + private JLabel faces; + private JTextArea cellsPerLevel; + private JLabel memory; + + private JLabel xBounds; + private JLabel yBounds; + private JLabel zBounds; + + private PanelBuilder dataArrays; + + protected PanelBuilder builder; + + @Inject + public DefaultBoundaryMeshPanel(Model model) { + super(TITLE, model); + this.treeNodeManager = new BoundaryMeshTreeNodeManager(model, this); + model.addObserver(treeNodeManager); + } + + protected JComponent layoutComponents() { + PanelBuilder actions = new PanelBuilder(); + actions.getPanel().setBorder(BorderFactory.createTitledBorder("Actions")); + + Action createMesh = ActionManager.getInstance().get("mesh.create"); + Action editCreateMesh = ActionManager.getInstance().get("mesh.create.edit"); + Action checkMesh = ActionManager.getInstance().get("mesh.check"); + Action editCheckMesh = ActionManager.getInstance().get("mesh.check.edit"); + Action deleteMesh = ActionManager.getInstance().get("mesh.delete"); + + JButton runMeshButton = new JButton(createMesh); + JButton editMeshScriptButton = new JButton(editCreateMesh); + JButton checkMeshButton = new JButton(checkMesh); + JButton editCheckMeshButton = new JButton(editCheckMesh); + JButton deleteMeshButton = new JButton(deleteMesh); + + runMeshButton.setPreferredSize(new Dimension(120, runMeshButton.getPreferredSize().height)); + checkMeshButton.setPreferredSize(new Dimension(120, checkMeshButton.getPreferredSize().height)); + deleteMeshButton.setPreferredSize(new Dimension(120, checkMeshButton.getPreferredSize().height)); + + JComponent c1 = Componentizer.create().minToPref(runMeshButton).fixedPref(editMeshScriptButton).minAndMore(new JLabel()).component(); + JComponent c2 = Componentizer.create().minToPref(checkMeshButton).fixedPref(editCheckMeshButton).minAndMore(new JLabel()).component(); + JComponent c3 = Componentizer.create().minToPref(deleteMeshButton).fixedPref(new JLabel()).minAndMore(new JLabel()).component(); + actions.addComponent(c1); + actions.addComponent(c2); + actions.addComponent(c3); + + name = labelField(""); + path = labelField(""); + created = labelField(""); + + cells = labelField(""); + points = labelField(""); + faces = labelField(""); + + cellsPerLevel = ComponentsFactory.labelArea(); + cellsPerLevel.setEditable(false); + + memory = labelField(""); + + xBounds = labelField(""); + yBounds = labelField(""); + zBounds = labelField(""); + + PanelBuilder properties = new PanelBuilder(); + properties.getPanel().setBorder(BorderFactory.createTitledBorder("Properties")); + properties.addComponent("Name", name); + properties.addComponent("Path", path); + properties.addComponent("Created", created); + + PanelBuilder statistics = new PanelBuilder(); + statistics.getPanel().setBorder(BorderFactory.createTitledBorder("Statistics")); + statistics.addComponent("Number of Cells", cells); + statistics.addComponent("Number of Faces", faces); + statistics.addComponent("Number of Points", points); + statistics.addComponent("Cells per Refinement Level", cellsPerLevel); + // statistics.addComponent("Memory [MB]", memory); + + dataArrays = new PanelBuilder(); + dataArrays.getPanel().setBorder(BorderFactory.createTitledBorder("Data Arrays")); + + PanelBuilder bounds = new PanelBuilder(); + bounds.getPanel().setBorder(BorderFactory.createTitledBorder("Bounds")); + bounds.addComponent("X Range", xBounds); + bounds.addComponent("Y Range", yBounds); + bounds.addComponent("Z Range", zBounds); + + builder = new PanelBuilder(); + builder.addComponent(actions.getPanel()); + builder.addComponent(properties.getPanel()); + builder.addComponent(statistics.getPanel()); + builder.addComponent(dataArrays.getPanel()); + builder.addComponent(bounds.getPanel()); + + return builder.removeMargins().getPanel(); + } + + @Override + public void load() { + name.setText(model.getProject().getBaseDir().getName()); + path.setText(model.getProject().getBaseDir().getParent()); + + try { + Path basePath = model.getProject().getBaseDir().toPath(); + long lastModify = Files.getLastModifiedTime(basePath).toMillis(); + created.setText(DateFormat.getDateInstance().format(new Date(lastModify))); + } catch (Exception e) { + created.setText("-"); + } + + if (model.getMesh() != null) { + cells.setText(formatter.format(model.getMesh().getNumberOfCells())); + points.setText(formatter.format(model.getMesh().getNumberOfPoints())); + faces.setText(formatter.format(model.getMesh().getNumberOfFaces())); + + List cellsPerRefinementLevel = model.getMesh().getCellsPerRefinementLevel(); + String text = ""; + for (int i = 0; i < cellsPerRefinementLevel.size(); i++) { + if (i > 0) + text += "\n"; + text += i + "\t" + cellsPerRefinementLevel.get(i); + } + cellsPerLevel.setText(text); + + // memory.setText(formatter.format(model.getMesh().getMemorySize()/1024D)); + + double[] bounds = model.getMesh().getBounds(); + + xBounds.setText(getTextForBounds(bounds[0], bounds[1])); + yBounds.setText(getTextForBounds(bounds[2], bounds[3])); + zBounds.setText(getTextForBounds(bounds[4], bounds[5])); + } else { + cells.setText("-"); + points.setText("-"); + faces.setText("-"); + cellsPerLevel.setText(" - "); + // memory.setText("-"); + xBounds.setText("[- , -]"); + yBounds.setText("[- , -]"); + zBounds.setText("[- , -]"); + } + } + + private String getTextForBounds(double min, double max) { + if (areValid(min, max)) { + return "[" + formatter.format(min) + " , " + formatter.format(max) + "] (Delta " + formatter.format(max - min) + ")"; + } else { + return "[0 , 0]"; + } + } + + private boolean areValid(double min, double max) { + return min < Double.MAX_VALUE && max > -Double.MAX_VALUE; + } + + @Override + public void save() { + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } + +} diff --git a/src/eu/engys/gui/mesh/panels/DefaultGeometryActions.java b/src/eu/engys/gui/mesh/panels/DefaultGeometryActions.java new file mode 100644 index 0000000..f77ce4c --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/DefaultGeometryActions.java @@ -0,0 +1,163 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import static eu.engys.gui.mesh.actions.geometry.ExtractLineAction.EXTRACT_NAME; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JSeparator; + +import com.lowagie.text.Font; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.mesh.actions.geometry.CloneSurfaceAction; +import eu.engys.gui.mesh.actions.geometry.CopySurfaceAction; +import eu.engys.gui.mesh.actions.geometry.ExtractLineAction; +import eu.engys.gui.mesh.actions.geometry.PasteSurfaceAction; +import eu.engys.gui.mesh.actions.geometry.RemoveSurfaceAction; +import eu.engys.gui.tree.TreeNodeManager.PopUpBuilder; +import eu.engys.util.Util; + +public class DefaultGeometryActions implements PopUpBuilder { + + public static final String GENERAL = "General"; + public static final String LINES = "Lines"; + public static final String SURFACES = "Surfaces"; + + protected final Model model; + private final AbstractGeometryPanel panel; + + private final RemoveSurfaceAction remove; + private final CloneSurfaceAction clone; + private final CopySurfaceAction copy; + private final PasteSurfaceAction paste; + + private final ExtractLineAction extractLines; + + private boolean enabled = true; + + public DefaultGeometryActions(AbstractGeometryPanel panel, Controller controller) { + this.panel = panel; + this.model = panel.getModel(); + + this.remove = new RemoveSurfaceAction(model); + this.clone = new CloneSurfaceAction(model, panel); + this.copy = new CopySurfaceAction(panel); + this.paste = new PasteSurfaceAction(panel); + + // Lines + this.extractLines = new ExtractLineAction(model, controller, this); + } + + @Override + public void populate(JPopupMenu popUp) { + populateGeneralActions(popUp); + populateSurfaceActions(popUp); + populateLinesActions(popUp); + } + + private void populateGeneralActions(JPopupMenu popUp) { + popUp.add(new TitledSeparator(GENERAL)); + popUp.add(remove).setName(RemoveSurfaceAction.REMOVE); + popUp.add(clone).setName(CloneSurfaceAction.CLONE); + popUp.add(copy).setName(CopySurfaceAction.COPY); + popUp.add(paste).setName(PasteSurfaceAction.PASTE); + } + + protected void populateSurfaceActions(JPopupMenu popUp) { + } + + protected void populateLinesActions(JPopupMenu popUp) { + popUp.add(new TitledSeparator(LINES)); + popUp.add(extractLines).setName(EXTRACT_NAME); + } + + protected void updateActions(Surface[] surfaces) { + if (Util.isVarArgsNotNull(surfaces)) { + remove.update(isEnabled(), surfaces); + clone.update(isEnabled(), surfaces); + copy.update(isEnabled(), surfaces); + paste.update(isEnabled(), surfaces); + + extractLines.update(isEnabled(), surfaces); + } + } + + public static class TitledSeparator extends JPanel { + public TitledSeparator(String title) { + super(new GridBagLayout()); + setOpaque(false); + JLabel label = new JLabel(title); + label.setOpaque(false); + label.setFont(label.getFont().deriveFont(Font.BOLD)); + add(new JSeparator(), new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + add(label, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + add(new JSeparator(), new GridBagConstraints(2, 0, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + } + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isEnabled() { + return enabled; + } + + public static class Enable implements Runnable { + private DefaultGeometryActions actions; + + public Enable(DefaultGeometryActions actions) { + this.actions = actions; + } + + @Override + public void run() { + actions.setEnabled(true); + } + } + + public static class Disable implements Runnable { + private DefaultGeometryActions actions; + + public Disable(DefaultGeometryActions actions) { + this.actions = actions; + } + + @Override + public void run() { + actions.setEnabled(false); + } + } +} diff --git a/src/eu/engys/gui/mesh/panels/DefaultMeshAdvancedOptionsPanel.java b/src/eu/engys/gui/mesh/panels/DefaultMeshAdvancedOptionsPanel.java new file mode 100644 index 0000000..04e0837 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/DefaultMeshAdvancedOptionsPanel.java @@ -0,0 +1,319 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import static eu.engys.core.project.system.SnappyHexMeshDict.ADD_LAYERS_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.CASTELLATED_MESH_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.ERROR_REDUCTION_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_BOUNDARY_SKEWNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_CONCAVE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_INTERNAL_SKEWNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_NON_ORTHO_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MESH_QUALITY_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_AREA_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_DETERMINANT_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_FACE_WEIGHT_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_FLATNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_TET_QUALITY_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_TRIANGLE_TWIST_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_TWIST_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_VOL_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_VOL_RATIO_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_SMOOTH_SCALE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.SNAP_CONTROLS_KEY; + +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.SnappyHexMeshDict; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.util.TooltipUtils; +import eu.engys.util.ui.builder.PanelBuilder; + +public abstract class DefaultMeshAdvancedOptionsPanel extends DefaultGUIPanel { + + public static final String NAME = "general.options.tabbedPane"; + + public static final String GENERAL_LABEL = "General"; + public static final String CASTELLATED_MESH_CONTROLS_LABEL = "Refinements"; + public static final String SNAP_CONTROLS_LABEL = "Snapping"; + public static final String LAYERS_CONTROLS_LABEL = "Layers"; + public static final String QUALITY_CONTROLS_LABEL = "Quality"; + + // GENERAL + public static final String CASTELLATED_MESH_LABEL = "Castellated Mesh"; + public static final String CASTELLATED_MESH_TOOLTIP = "Generate a refined castellated mesh"; + public static final String SNAPPING_LABEL = "Snapping"; + public static final String SNAPPING_TOOLTIP = "Snap surface mesh points to the geometry and merge boundary faces"; + public static final String LAYERS_ADDITION_LABEL = "Layers Addition"; + public static final String LAYERS_ADDITION_TOOLTIP = "Perform generation of layers"; + public static final String DEBUG_LABEL = "Debug"; + public static final String DEBUG_TOOLTIP = "Control of debug output:" + TooltipUtils.NEW_LINE + "0: Write only final mesh" + TooltipUtils.NEW_LINE + "1: Write intermediate meshes" + TooltipUtils.NEW_LINE + "2: Write cell level information"; + public static final String MERGE_TOLERANCE_LABEL = "Merge Tolerance"; + public static final String MERGE_TOLERANCE_TOOLTIP = "Merge tolerance specified as a function of the initial bounding box size"; + + // CASTELLATED + public static final String MAX_LOCAL_CELLS_LABEL = "Max Local Cells"; + public static final String MAX_LOCAL_CELLS_TOOLTIP = "Termination of refinement if number of cells on processor n exceeds this value"; + public static final String MAX_GLOBAL_CELLS_LABEL = "Max Global Cells"; + public static final String MAX_GLOBAL_CELLS_TOOLTIP = "No further refinement if global number of cells exceeds this value"; + public static final String MIN_REFINEMENT_CELLS_LABEL = "Min Refinement Cells"; + public static final String MIN_REFINEMENT_CELLS_TOOLTIP = "Terminate refinement iteration if number of cells to refine falls below this value"; + public static final String MAX_LOAD_UNBALANCE_LABEL = "Max Load Unbalance"; + public static final String MAX_LOAD_UNBALANCE_TOOLTIP = "When running in parallel allow some imbalance in the number of cells per processor to avoid expensive re-balancing operations. This value is expressed as a fraction of perfect balance (i.e. overall number of cells / number of processors). Set to 0 will always perform balancing"; + public static final String CELLS_BETWEEN_LEVELS_LABEL = "Cells Between Levels"; + public static final String CELLS_BETWEEN_LEVELS_TOOLTIP = "Specify the number of buffer layers between two neighbouring volume refinement levels in the mesh"; + public static final String RESOLVE_FEATURE_ANGLE_LABEL = "Resolve Feature Angle"; + public static final String RESOLVE_FEATURE_ANGLE_TOOLTIP = "The surface is refined to the maximum level if local curvature is greater than this angle. Set to a negative value to disable"; + public static final String ALLOW_FREE_STANDING_ZONE_FACES_LABEL = "Allow Free Standing Zone Faces"; + public static final String ALLOW_FREE_STANDING_ZONE_FACES_TOOLTIP = "Allow free standing zone faces in addition to zone faces in between different cell zones. Can be set globally or on a per zone basis"; + + // SNAP + public static final String RELAX_ITERATIONS_SNAP_LABEL = "Correction Steps"; + public static final String RELAX_ITERATIONS_SNAP_TOOLTIP = "Maximum number of corrections steps to revert mesh back to error free state"; + public static final String TOLERANCE_LABEL = "Tolerance"; + public static final String TOLERANCE_TOOLTIP = "Relative distance for points to be attached by surface feature point"; + public static final String SMOOTH_PATCH_LABEL = "Smooth Patch"; + public static final String SMOOTH_PATCH_TOOLTIP = "Number of patch smoothing iterations performed finding correspondance to surface"; + public static final String SOLVER_ITERATIONS_LABEL = "Solver Iterations"; + public static final String SOLVER_ITERATIONS_TOOLTIP = "Specifies the number of displacement smoothing iterations"; + + // LAYERS + public static final String RELAX_ITERATIONS_LAYERS_LABEL = "Correction Steps"; + public static final String RELAX_ITERATIONS_LAYERS_TOOLTIP = "Number of correction steps to revert mesh back to error free state"; + public static final String RELAXED_ITERATIONS_LABEL = "Relaxed Layer Iterations"; + public static final String RELAXED_ITERATIONS_TOOLTIP = "Number of layer iterations before a set of relaxed mesh quality constraints are applied"; + public static final String MIN_MEDIAL_AXIS_ANGLE_LABEL = "Min Medial Axis Angle"; + public static final String MIN_MEDIAL_AXIS_ANGLE_TOOLTIP = "Angle used to select medial axis points"; + public static final String MAX_THICKNESS_TO_MEDIAL_RATIO_LABEL = "Max Thickness To Medial Ratio"; + public static final String MAX_THICKNESS_TO_MEDIAL_RATIO_TOOLTIP = "Reduce layer thickness where ratio of layer thickness to distance to medial axis is above this value"; + public static final String MAX_FACE_THICKNESS_RATIO_LABEL = "Max Face Thickness Ratio"; + public static final String MAX_FACE_THICKNESS_RATIO_TOOLTIP = "Measure of surface face warp-age. Layer growth is terminated on faces where this value is exceeded"; + public static final String INTERIOR_MESH_SMOOTHING_ITERATIONS_LABEL = "Interior Mesh Smoothing Iterations"; + public static final String INTERIOR_MESH_SMOOTHING_ITERATIONS_TOOLTIP = "Number of interior normals smoothing iterations performed before projecting the mesh"; + public static final String SURFACE_NORMALS_SMOOTHING_ITERATIONS_LABEL = "Surface Normals Smoothing Iterations"; + public static final String SURFACE_NORMALS_SMOOTHING_ITERATIONS_TOOLTIP = "Number of surface normals smoothing iterations performed before projecting the mesh"; + public static final String MIN_THICKNESS_LABEL = "Min Thickness"; + public static final String MIN_THICKNESS_TOOLTIP = "Relative measure of layer thickness, layers terminated if their thickness fall below this value"; +// public static final String RELATIVE_SIZES_LABEL = "Relative Sizes"; +// public static final String RELATIVE_SIZES_TOOLTIP = "Whether to use a relative or absolute sizing for layer control"; + public static final String FINAL_LAYER_THICKNESS_LABEL = "Final Layer Thickness"; + public static final String FINAL_LAYER_THICKNESS_TOOLTIP = "Requested thickness for final cell layer"; + public static final String EXPANSION_RATIO_LABEL = "Expansion Ratio"; + public static final String EXPANSION_RATIO_TOOLTIP = "Global setting of growth factor for layer growth. Can be overwritten locally on each patch"; + + // QUALITY + public static final String ERROR_REDUCTION_LABEL = "Error Reduction"; + public static final String ERROR_REDUCTION_TOOLTIP = "Ratio used for scaling of displacement during each error reduction iteration"; + public static final String SMOOTH_SCALE_LABEL = "Smooth Scale"; + public static final String SMOOTH_SCALE_TOOLTIP = "Number of sub-smoothing iterations during scaling back"; + public static final String MIN_TRIANGLE_TWIST_LABEL = "Min Triangle Twist"; + public static final String MIN_TRIANGLE_TWIST_TOOLTIP = "Minimum triangle twist. Set to a positive value for Fluent compatibility"; + public static final String MIN_VOL_RATIO_LABEL = "Min Vol Ratio"; + public static final String MIN_VOL_RATIO_TOOLTIP = "Minimum volume ratio between adjacent cells. Set to a negative value to disable"; + public static final String MIN_FACE_WEIGHT_LABEL = "Min Face Weight"; + public static final String MIN_FACE_WEIGHT_TOOLTIP = "Face based interpolation weight metric. Set to a negative value to disable"; + public static final String MIN_DETERMINANT_LABEL = "Min Determinant"; + public static final String MIN_DETERMINANT_TOOLTIP = "Minimum normalised cell-determinant. Set to a negative value to disable"; + public static final String MIN_TWIST_LABEL = "Min Twist"; + public static final String MIN_TWIST_TOOLTIP = "Minimum face twist. Set to a negative value to disable"; + public static final String MIN_AREA_LABEL = "Min Area"; + public static final String MIN_AREA_TOOLTIP = "Minimum face area. Set to a negative value to disable"; + public static final String MIN_TET_QUALITY_LABEL = "Min Tetrahedral Quality"; + public static final String MIN_TET_QUALITY_TOOLTIP = "Minimum quality of the tetrahedral elements formed by the face-centre and variable base point minimum decomposition triangles and the cell centre. This has to be a positive number for tracking to work. Set to a very large negative number (e.g. -1E30) to disable"; + public static final String MIN_VOL_LABEL = "Min Vol"; + public static final String MIN_VOL_TOOLTIP = "Minimum pyramid volume (absolute). Set to a very large negative number (e.g. -1E30) to disable"; + public static final String MIN_FLATNESS_LABEL = "Min Flatness"; + public static final String MIN_FLATNESS_TOOLTIP = "Ratio of projected area to actual area. Set to a negative value to disable"; + public static final String MAX_CONCAVE_LABEL = "Max Concave"; + public static final String MAX_CONCAVE_TOOLTIP = "Maximum concavity. Set to 180 to disable"; + public static final String MAX_INTERNAL_SKEWNESS_LABEL = "Max Internal Skewness"; + public static final String MAX_INTERNAL_SKEWNESS_TOOLTIP = "Maximum internal skewness. Set to a negative value to disable"; + public static final String MAX_BOUNDARY_SKEWNESS_LABEL = "Max Boundary Skewness"; + public static final String MAX_BOUNDARY_SKEWNESS_TOOLTIP = "Maximum boundary skewness. Set to a negative value to disable"; + public static final String MAX_NON_ORTHO_LABEL = "Max Non Ortho"; + public static final String MAX_NON_ORTHO_TOOLTIP = "Maximum non-orthogonality allowed. Set to 180 to disable"; + + protected DictionaryModel snappyHexMeshModel; + protected DictionaryModel castellatedMeshControlsModel; + protected DictionaryModel snapControlsModel; + protected DictionaryModel layersControlsModel; + protected DictionaryModel meshQualityControlsModel; + private boolean toDefaults = false; + + protected PanelBuilder qualityBuilder; + + public DefaultMeshAdvancedOptionsPanel(Model model) { + super("", model); + } + + @Override + protected JComponent layoutComponents() { + snappyHexMeshModel = new DictionaryModel(new Dictionary("")); + castellatedMeshControlsModel = new DictionaryModel(new Dictionary("")); + snapControlsModel = new DictionaryModel(new Dictionary("")); + layersControlsModel = new DictionaryModel(new Dictionary("")); + meshQualityControlsModel = new DictionaryModel(new Dictionary("")); + + JTabbedPane tabbedPane = new JTabbedPane(); + tabbedPane.setName(NAME); + tabbedPane.add(GENERAL_LABEL, createGeneralPanel()); + tabbedPane.add(CASTELLATED_MESH_CONTROLS_LABEL, createRefinementsPanel()); + tabbedPane.add(SNAP_CONTROLS_LABEL, createSnappingPanel()); + tabbedPane.add(LAYERS_CONTROLS_LABEL, createLayersPanel()); + tabbedPane.add(QUALITY_CONTROLS_LABEL, createQualityPanel()); + + return tabbedPane; + } + + protected abstract JPanel createGeneralPanel(); + + protected abstract JPanel createRefinementsPanel(); + + protected abstract JPanel createSnappingPanel(); + + protected abstract JPanel createLayersPanel(); + + protected JPanel createQualityPanel() { + qualityBuilder = new PanelBuilder("options.quality.panel"); + qualityBuilder.addComponent(MAX_NON_ORTHO_LABEL, meshQualityControlsModel.bindDoubleAngle_180(MAX_NON_ORTHO_KEY), MAX_NON_ORTHO_TOOLTIP); + qualityBuilder.addComponent(MAX_BOUNDARY_SKEWNESS_LABEL, meshQualityControlsModel.bindInteger(MAX_BOUNDARY_SKEWNESS_KEY), MAX_BOUNDARY_SKEWNESS_TOOLTIP); + qualityBuilder.addComponent(MAX_INTERNAL_SKEWNESS_LABEL, meshQualityControlsModel.bindInteger(MAX_INTERNAL_SKEWNESS_KEY), MAX_INTERNAL_SKEWNESS_TOOLTIP); + qualityBuilder.addComponent(MAX_CONCAVE_LABEL, meshQualityControlsModel.bindDoubleAngle_180(MAX_CONCAVE_KEY), MAX_CONCAVE_TOOLTIP); + qualityBuilder.addComponent(MIN_FLATNESS_LABEL, meshQualityControlsModel.bindDouble(MIN_FLATNESS_KEY), MIN_FLATNESS_TOOLTIP); + qualityBuilder.addComponent(MIN_VOL_LABEL, meshQualityControlsModel.bindDouble(MIN_VOL_KEY), MIN_VOL_TOOLTIP); + qualityBuilder.addComponent(MIN_TET_QUALITY_LABEL, meshQualityControlsModel.bindDouble(MIN_TET_QUALITY_KEY), MIN_TET_QUALITY_TOOLTIP); + qualityBuilder.addComponent(MIN_AREA_LABEL, meshQualityControlsModel.bindDouble(MIN_AREA_KEY), MIN_AREA_TOOLTIP); + qualityBuilder.addComponent(MIN_TWIST_LABEL, meshQualityControlsModel.bindDouble(MIN_TWIST_KEY), MIN_TWIST_TOOLTIP); + qualityBuilder.addComponent(MIN_DETERMINANT_LABEL, meshQualityControlsModel.bindDouble(MIN_DETERMINANT_KEY), MIN_DETERMINANT_TOOLTIP); + qualityBuilder.addComponent(MIN_FACE_WEIGHT_LABEL, meshQualityControlsModel.bindDouble(MIN_FACE_WEIGHT_KEY), MIN_FACE_WEIGHT_TOOLTIP); + qualityBuilder.addComponent(MIN_VOL_RATIO_LABEL, meshQualityControlsModel.bindDouble(MIN_VOL_RATIO_KEY), MIN_VOL_RATIO_TOOLTIP); + qualityBuilder.addComponent(MIN_TRIANGLE_TWIST_LABEL, meshQualityControlsModel.bindDouble(MIN_TRIANGLE_TWIST_KEY), MIN_TRIANGLE_TWIST_TOOLTIP); + qualityBuilder.addComponent(SMOOTH_SCALE_LABEL, meshQualityControlsModel.bindIntegerPositive(N_SMOOTH_SCALE_KEY), SMOOTH_SCALE_TOOLTIP); + qualityBuilder.addComponent(ERROR_REDUCTION_LABEL, meshQualityControlsModel.bindDouble(ERROR_REDUCTION_KEY), ERROR_REDUCTION_TOOLTIP); + return qualityBuilder.getPanel(); + } + + @Override + public void resetToDefaults() { + this.toDefaults = true; + load(); + this.toDefaults = false; + } + + // LOAD + + protected SnappyHexMeshDict getSnappyDict() { + SnappyHexMeshDict snappyDict = null; + if (toDefaults) { + snappyDict = model.getDefaults().getDefaultSnappyHexMeshDict(); + } else { + snappyDict = new SnappyHexMeshDict(model.getProject().getSystemFolder().getSnappyHexMeshDict()); + } + return snappyDict; + } + + protected abstract void loadCastellated(SnappyHexMeshDict snappyDict); + + protected void loadLayers(SnappyHexMeshDict snappyDict) { + if (snappyDict.found(ADD_LAYERS_CONTROLS_KEY)) { + Dictionary layersDict = new Dictionary(snappyDict.subDict(ADD_LAYERS_CONTROLS_KEY)); + snappyDict.remove(ADD_LAYERS_CONTROLS_KEY); + this.layersControlsModel.setDictionary(layersDict); + } + } + + protected void loadQuality(SnappyHexMeshDict snappyDict) { + if (snappyDict.found(MESH_QUALITY_CONTROLS_KEY)) { + Dictionary quality = new Dictionary(snappyDict.subDict(MESH_QUALITY_CONTROLS_KEY)); + snappyDict.remove(MESH_QUALITY_CONTROLS_KEY); + this.meshQualityControlsModel.setDictionary(quality); + } + } + + protected void loadSnap(SnappyHexMeshDict snappyDict) { + if (snappyDict.found(SNAP_CONTROLS_KEY)) { + Dictionary snap = new Dictionary(snappyDict.subDict(SNAP_CONTROLS_KEY)); + snappyDict.remove(SNAP_CONTROLS_KEY); + this.snapControlsModel.setDictionary(snap); + } + } + + // SAVE + + @Override + public void save() { + SnappyHexMeshDict snappyHexMeshDict = model.getProject().getSystemFolder().getSnappyHexMeshDict(); + + saveMisc(snappyHexMeshDict); + saveCastellatedSubDict(snappyHexMeshDict); + saveSnapControlsDict(snappyHexMeshDict); + saveLayersControlsDict(snappyHexMeshDict); + saveMeshQualityControlsDict(snappyHexMeshDict); + saveRepatchDict(snappyHexMeshDict); + + model.getProject().getSystemFolder().setSnappyHexMeshDict(snappyHexMeshDict); + } + + private void saveMisc(SnappyHexMeshDict snappyDict) { + snappyDict.merge(snappyHexMeshModel.getDictionary()); + } + + private void saveCastellatedSubDict(SnappyHexMeshDict snappyDict) { + Dictionary castellated = snappyDict.subDict(CASTELLATED_MESH_CONTROLS_KEY); + castellated.merge(castellatedMeshControlsModel.getDictionary()); + saveWrapperDict(snappyDict, castellated); + } + + private void saveSnapControlsDict(SnappyHexMeshDict snappyDict) { + Dictionary snap = snappyDict.subDict(SNAP_CONTROLS_KEY); + snap.merge(snapControlsModel.getDictionary()); + } + + private void saveLayersControlsDict(SnappyHexMeshDict snappyDict) { + Dictionary snap = snappyDict.subDict(ADD_LAYERS_CONTROLS_KEY); + snap.merge(layersControlsModel.getDictionary()); + } + + private void saveMeshQualityControlsDict(SnappyHexMeshDict snappyDict) { + Dictionary snap = snappyDict.subDict(MESH_QUALITY_CONTROLS_KEY); + snap.merge(meshQualityControlsModel.getDictionary()); + } + + protected void saveWrapperDict(SnappyHexMeshDict snappyDict, Dictionary castellated) { + } + + protected void saveRepatchDict(SnappyHexMeshDict snappyDict) { + } + + public void handleClose() { + } + +} diff --git a/src/eu/engys/gui/mesh/panels/FeatureLinesPanel.java b/src/eu/engys/gui/mesh/panels/FeatureLinesPanel.java new file mode 100644 index 0000000..9fe4d6e --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/FeatureLinesPanel.java @@ -0,0 +1,213 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import net.java.dev.designgridlayout.Componentizer; + +import com.google.inject.Inject; + +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.gui.AbstractGUIPanel; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.RenameSurfaceEvent; +import eu.engys.gui.mesh.panels.lines.ColorFeatureLineAction; +import eu.engys.gui.mesh.panels.lines.FeatureLinesRefinementTable; +import eu.engys.gui.mesh.panels.lines.ImportFeatureLineAction; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.util.Util; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.StringField; + +public class FeatureLinesPanel extends AbstractGUIPanel { + + public static final String LINES = "Lines"; + public static final String COLOR_LABEL = "Color"; + public static final String NAME_LABEL = "Name"; + public static final String REFINE_ONLY_LABEL = "Refine Only"; + public static final String REFINEMENTS_LABEL = "Refinements"; + public static final String REMOVE_LABEL = "Remove"; + + private PanelBuilder builder; + private StringField nameField; + private JCheckBox refineOnly; + private JButton colorButton; + private FeatureLine selectedLine; + private ColorFeatureLineAction colorLineAction; + private FeatureLinesRefinementTable refinementLevels; + private FeatureLinesTreeNodeManager treeNodeManager; + + private PropertyChangeListener renameAction; + + @Inject + public FeatureLinesPanel(Model model) { + super(LINES, model); + this.treeNodeManager = new FeatureLinesTreeNodeManager(model, this); + model.addObserver(treeNodeManager); + } + + @Override + protected JComponent layoutComponents() { + PanelBuilder builder = new PanelBuilder(); + builder.addRight(getButtons()); + builder.addComponent(createFeatureLinesPanel()); + + return builder.removeMargins().getPanel(); + } + + private JPanel createFeatureLinesPanel() { + renameAction = new PropertyChangeListener() { + @Override + public void propertyChange(java.beans.PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value") && evt.getSource() instanceof StringField) { + StringField field = (StringField) evt.getSource(); + renameSurface(field.getText()); + } + } + }; + nameField = ComponentsFactory.stringField(); + nameField.addPropertyChangeListener(renameAction); + + refineOnly = ComponentsFactory.checkField(); + + builder = new PanelBuilder(); + builder.addComponent(NAME_LABEL, nameField); + builder.addComponent(COLOR_LABEL, Componentizer.create().fixedPref(colorButton = new JButton(colorLineAction = new ColorFeatureLineAction(this))).component()); + if (hasRefineOnly()) { + builder.addComponent(REFINE_ONLY_LABEL, refineOnly); + } + builder.addComponent(REFINEMENTS_LABEL, refinementLevels = new FeatureLinesRefinementTable(model, null)); + builder.setEnabled(false); + + return builder.getPanel(); + } + + @Override + public void load() { + } + + @Override + public void save() { + super.save(); + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) treeNodeManager.getSelectedValues()); + } + + private void renameSurface(String newName) { + if (selectedLine != null) { + if (model.getGeometry().contains(newName)) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Name already in use", "Name Error", JOptionPane.ERROR_MESSAGE); + return; + } + + String oldPatchName = selectedLine.getName(); + selectedLine.rename(newName); + + treeNodeManager.refreshNode(selectedLine); + + EventManager.triggerEvent(this, new RenameSurfaceEvent(selectedLine, oldPatchName, selectedLine.getPatchName())); + } + } + + private JButton[] getButtons() { + final JButton fromFile = new JButton(new ImportFeatureLineAction(model)); + fromFile.setName(ImportFeatureLineAction.FROM_FILE_LABEL); + List buttons = new ArrayList<>(); + buttons.add(fromFile); + return buttons.toArray(new JButton[0]); + } + + public void selectLine(FeatureLine[] currentSelection) { + if (Util.isVarArgsNotNull(currentSelection)) { + StringBuilder sb = new StringBuilder(); + for (FeatureLine line : currentSelection) { + sb.append(line.getName()); + sb.append(" "); + } + nameField.setText(sb.toString()); + if (currentSelection.length == 1) { + builder.setEnabled(true); + this.selectedLine = currentSelection[0]; + + refineOnly.setSelected(selectedLine.isRefineOnly()); + + refinementLevels.setRefinements(selectedLine.getRefinements()); + refinementLevels.load(); + + colorLineAction.setCurrentColor(selectedLine.getColor()); + colorButton.setBackground(selectedLine.getColor()); + } else { + builder.setEnabled(false); + } + } else { + deselectAll(); + } + + } + + public void saveLine(FeatureLine[] currentSelection) { + if (currentSelection != null && currentSelection.length == 1) { + FeatureLine line = currentSelection[0]; + line.setRefineOnly(refineOnly.isSelected()); + line.setRefinements(refinementLevels.getRefinements()); + } + } + + public FeatureLine getSelectedLine() { + return selectedLine; + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } + + public void deselectAll() { + nameField.setText(""); + builder.setEnabled(false); + } + + @Override + public void clear() { + treeNodeManager.getSelectionHandler().handleSelection(false, (Object[]) new FeatureLine[0]); + } + + protected boolean hasRefineOnly() { + return true; + } + +} diff --git a/src/eu/engys/gui/mesh/panels/FeatureLinesTreeNodeManager.java b/src/eu/engys/gui/mesh/panels/FeatureLinesTreeNodeManager.java new file mode 100644 index 0000000..e8b8acd --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/FeatureLinesTreeNodeManager.java @@ -0,0 +1,365 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/*--------------------------------*- Java -*---------------------------------*\ + |o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2013 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + |License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ +package eu.engys.gui.mesh.panels; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.JPopupMenu; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreePath; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.core.project.geometry.Geometry; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.RemoveSurfaceEvent; +import eu.engys.gui.events.view3D.SelectSurfaceEvent; +import eu.engys.gui.tree.AbstractSelectionHandler; +import eu.engys.gui.tree.DefaultTreeNodeManager; +import eu.engys.gui.tree.SelectionHandler; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.Util; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.TreeUtil; +import eu.engys.util.ui.checkboxtree.RootVisibleItem; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class FeatureLinesTreeNodeManager extends DefaultTreeNodeManager { + + private static final Logger logger = LoggerFactory.getLogger(FeatureLinesTreeNodeManager.class); + + private final Action removeAction = new RemoveAction(); + + private Map linesMap; + private FeatureLinesSelectionHandler selectionHandler; + + public FeatureLinesTreeNodeManager(Model model, FeatureLinesPanel panel) { + super(model, panel); + this.root = new DefaultMutableTreeNode(new RootVisibleItem(panel.getTitle())); + this.selectionHandler = new FeatureLinesSelectionHandler(panel); + this.linesMap = new HashMap<>(); + } + + @Override + public void update(Observable o, final Object arg) { + if (arg instanceof FeatureLine) { + logger.debug("Observerd a change: arg is " + arg.getClass()); + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + loadTree(); + expandTree(arg); + } + }); + } else if (arg instanceof Geometry) { + logger.debug("Observerd a change: arg is Geometry"); + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + selectionHandler.disable(); + loadTree(); + makeVisibleItemsChecked(); + expandTree(arg); + selectionHandler.enable(); + } + }); + } else if (arg instanceof Patches) { + logger.debug("Observerd a change: arg is Patches"); + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + makeVisibleItemsChecked(); + } + }); + } + } + + private void loadTree() { + logger.debug("Load 'Geometry' tree"); + clear(); + for (FeatureLine line : model.getGeometry().getLines()) { + addLine(root, line); + } + treeChanged(root); + } + + private void addLine(DefaultMutableTreeNode parent, FeatureLine line) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(line); + parent.add(node); + nodeMap.put(line, node); + linesMap.put(node, line); + } + + private void makeVisibleItemsChecked() { + logger.debug("Make visible items checked"); + if (getTree() != null) { + if (model.getPatches() == null || model.getPatches().isEmpty()) + getTree().getCheckManager().selectNode(getRoot()); + else + getTree().getCheckManager().deselectNode(getRoot()); + } + } + + private void expandTree(final Object arg) { + if (getTree() != null) { + if (shouldExpand(arg)) { + logger.debug("Expand the tree"); + getTree().expandNode(getRoot()); + if (arg instanceof Surface) { + Surface surface = (Surface) arg; + setSelectedValue(surface); + } + } + } + } + + private boolean shouldExpand(final Object arg) { + return arg instanceof FeatureLine || arg instanceof Geometry; + } + + private void setSelectedValue(Surface surface) { + DefaultMutableTreeNode selectedNode = nodeMap.get(surface); + if (getTree() != null) { + if (surface.getPatchName() != null) { + getTree().setSelectedNode(selectedNode); + } + } + } + + public FeatureLine[] getSelectedValues() { + if (getTree() != null) { + TreePath[] selectionPaths = getTree().getSelectionPaths(); + if (selectionPaths != null) { + FeatureLine[] surfaces = new FeatureLine[selectionPaths.length]; + for (int i = 0; i < selectionPaths.length; i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPaths[i].getLastPathComponent(); + FeatureLine line = linesMap.get(node); + surfaces[i] = line; + } + return surfaces; + } + } + return new FeatureLine[0]; + } + + public void clear() { + // clear node before selection handler! + clearNode(root); + selectionHandler.clear(); + nodeMap.clear(); + linesMap.clear(); + } + + public DefaultMutableTreeNode getRoot() { + return root; + } + + @Override + public Class getRendererClass() { + return FeatureLine.class; + } + + @Override + public DefaultTreeCellRenderer getRenderer() { + return new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObject = node.getUserObject(); + + if (userObject instanceof Surface) { + Surface surface = (Surface) userObject; + setText(surface.getName()); + } + setIcon(null); + return this; + } + }; + } + + @Override + public SelectionHandler getSelectionHandler() { + return selectionHandler; + } + + @Override + public PopUpBuilder getPopUpBuilder() { + return new PopUpBuilder() { + @Override + public void populate(JPopupMenu popUp) { + popUp.add(removeAction); + } + }; + } + + private void updateActions() { + Surface[] surfaces = selectionHandler.currentSelection; + if (Util.isVarArgsNotNull(surfaces)) { + Type type = surfaces[0].getType(); + removeAction.setEnabled(type != Type.SOLID); + } + } + + private final class RemoveAction extends AbstractAction { + public RemoveAction() { + super("Remove"); + } + + @Override + public void actionPerformed(ActionEvent e) { + FeatureLine[] surfaces = getSelectedValues(); + + model.getGeometry().removeLines(surfaces); + model.geometryChanged(); + + EventManager.triggerEvent(this, new RemoveSurfaceEvent(surfaces)); + } + } + + public final class FeatureLinesSelectionHandler extends AbstractSelectionHandler { + + private final FeatureLinesPanel panel; + private FeatureLine[] currentSelection; + + public FeatureLinesSelectionHandler(FeatureLinesPanel panel) { + this.panel = panel; + } + + @Override + public void handleSelection(boolean fire3DEvent, Object... selection) { + saveCurrentSelection(); + + boolean isValidSelection = TreeUtil.isConsistent(selection, FeatureLine.class); + if (isValidSelection) { + handleValidSelection(fire3DEvent, selection); + } else { + boolean shouldClearSelection = TreeUtil.isConsistent(currentSelection, FeatureLine.class); + if (shouldClearSelection) { + clearSelection(fire3DEvent); + } + } + + } + + private void saveCurrentSelection() { + if (Util.isVarArgsNotNull(currentSelection)) { + panel.saveLine(currentSelection); + } + } + + private void handleValidSelection(boolean fire3DEvent, Object... selection) { + logger.debug("handleSelection: {} selected, fire3D {} {}", selection.length, fire3DEvent, selection.length == 1 ? ", selection is: " + selection[0] : ""); + + this.currentSelection = Arrays.copyOf(selection, selection.length, FeatureLine[].class); + panel.selectLine(currentSelection); + + if (fire3DEvent) { + EventManager.triggerEvent(this, new SelectSurfaceEvent(currentSelection)); + } + + updateActions(); + } + + private void clearSelection(boolean fire3DEvent) { + clear(); + panel.deselectAll(); + if (fire3DEvent) { + EventManager.triggerEvent(this, new SelectSurfaceEvent(new FeatureLine[0])); + } + } + + @Override + public void handleVisibility(VisibleItem item) { + logger.debug("handleVisibility: {}", item); + if (Util.isVarArgsNotNull(currentSelection) && Arrays.asList(currentSelection).contains(item)) { + panel.selectLine(currentSelection); + EventManager.triggerEvent(this, new SelectSurfaceEvent(currentSelection)); + } + } + + @Override + public void process3DSelectionEvent(Picker picker, Actor actor, boolean keep) { + } + + @Override + public void process3DVisibilityEvent(boolean selected) { + logger.debug("handle selection from check box"); + if (getTree() != null) { + if (selected) { + // getTree().getCheckManager().selectNode(getRoot()); + } else { + getTree().getCheckManager().deselectNode(getRoot()); + } + } + } + + public void clear() { + currentSelection = null; + } + } + +} diff --git a/src/eu/engys/gui/mesh/panels/GeometriesPanelBuilder.java b/src/eu/engys/gui/mesh/panels/GeometriesPanelBuilder.java new file mode 100644 index 0000000..27926c7 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/GeometriesPanelBuilder.java @@ -0,0 +1,517 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; + +import net.java.dev.designgridlayout.RowGroup; +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FieldChangeListener; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; +import eu.engys.core.project.geometry.surface.PlaneRegion; +import eu.engys.gui.mesh.GeometryPanel; +import eu.engys.gui.view3D.BoxEventButton; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.StringField; + +public class GeometriesPanelBuilder { + + public static final String BOX_NAME_LABEL = "Box Name"; + public static final String SPHERE_NAME_LABEL = "Sphere Name"; + public static final String CYLINDER_NAME_LABEL = "Cylinder Name"; + public static final String PLANE_NAME_LABEL = "Plane Name"; + public static final String RING_NAME_LABEL = "Ring Name"; + public static final String SURFACE_NAME_LABEL = "Surface Name"; + + public static final String OUTER_RADIUS_LABEL = "Outer Radius"; + public static final String INNER_RADIUS_LABEL = "Inner Radius"; + public static final String PATCH_NAME_LABEL = "Patch Name"; + public static final String NORMAL_LABEL = "Normal"; + public static final String ORIGIN_LABEL = "Origin"; + public static final String POINT_1_LABEL = "Point 1"; + public static final String POINT_2_LABEL = "Point 2"; + public static final String MIN_LABEL = "Min"; + public static final String MAX_LABEL = "Max"; + public static final String RADIUS_LABEL = "Radius"; + public static final String CENTRE_LABEL = "Centre"; + public static final int DECIMAL_PLACES = 4; + + private StringField stlNameField; + private StringField boxNameField; + private StringField cylinderNameField; + private StringField sphereNameField; + private StringField ringNameField; + private StringField planeNameField; + private StringField regionNameField; + + private DictionaryModel boxModel; + private DictionaryModel cylinderModel; + private DictionaryModel sphereModel; + private DictionaryModel ringModel; + private DictionaryModel planeModel; + private DictionaryModel planePointAndNormalModel; + + private PanelBuilder boxBuilder; + private PanelBuilder cylinderBuilder; + private PanelBuilder sphereBuilder; + private PanelBuilder ringBuilder; + private PanelBuilder planeBuilder; + private PanelBuilder regionBuilder; + private DictionaryModel stlModel; + PanelBuilder stlBuilder; + + private RowGroup boxGroup; + private RowGroup sphereGroup; + private RowGroup ringGroup; + private RowGroup planeGroup; + private RowGroup cylinderGroup; + private RowGroup stlGroup; + private RowGroup regionGroup; + private RowGroup noneGroup; + + private GeometryPanel meshPanel; + + private RowGroup selected; + Surface selectedSurface; + private PropertyChangeListener renameAction; + + private BoxEventButton showBoxButton; + + public GeometriesPanelBuilder(GeometryPanel panel) { + super(); + this.meshPanel = panel; + } + + public void addComponents(PanelBuilder builder) { + FieldChangeListener listener = new FieldChangeListener() { + + boolean adjusting = false; + + @Override + public void actionPerformed(ActionEvent e) { + } + + @Override + public void setAdjusting(boolean b) { + this.adjusting = b; + } + + @Override + public boolean isAdjusting() { + return adjusting; + } + + @Override + public void fieldChanged() { + if (!isAdjusting() && selectedSurface != null) { + meshPanel.changeSurface(selectedSurface); + } + } + }; + + addSTLComponent(builder, listener); + addBoxComponent(builder, listener); + addCylinderComponent(builder, listener); + addPlaneComponent(builder, listener); + addSphereComponent(builder, listener); + addRingComponent(builder, listener); + addNoneComponent(builder, listener); + + renameAction = new PropertyChangeListener() { + @Override + public void propertyChange(java.beans.PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value") && evt.getSource() instanceof StringField) { + StringField field = (StringField) evt.getSource(); + meshPanel.renameSurface(field.getText()); + } + } + }; + addRenameAction(); + + selected = noneGroup; + } + + private void addSTLComponent(PanelBuilder builder, FieldChangeListener listener) { + stlModel = new DictionaryModel(new Dictionary("")); + + stlBuilder = new PanelBuilder(); + stlBuilder.addComponent(SURFACE_NAME_LABEL, stlNameField = stringField()); + stlBuilder.getPanel().setBorder(BorderFactory.createTitledBorder("")); + + stlGroup = new RowGroup(); + builder.addComponentToGroup(stlGroup, stlBuilder.getPanel()); + stlGroup.hide(); + } + + private void addBoxComponent(PanelBuilder builder, FieldChangeListener listener) { + boxModel = new DictionaryModel(new Dictionary("")); + + DoubleField[] boxMin = boxModel.bindPoint(Surface.MIN_KEY, DECIMAL_PLACES, listener); + DoubleField[] boxMax = boxModel.bindPoint(Surface.MAX_KEY, DECIMAL_PLACES, listener); + showBoxButton = new BoxEventButton(boxMin, boxMax); + + boxBuilder = new PanelBuilder(); + boxBuilder.addComponent(BOX_NAME_LABEL, boxNameField = stringField()); + // boxBuilder.addComponent("", labelField("X"), labelField("Y"), labelField("Z")); + boxBuilder.addComponent(MIN_LABEL, boxMin[0], boxMin[1], boxMin[2], showBoxButton); + boxBuilder.addComponentAndSpan(MAX_LABEL, boxMax); + boxBuilder.getPanel().setBorder(BorderFactory.createTitledBorder("")); + + boxGroup = new RowGroup(); + builder.addComponentToGroup(boxGroup, boxBuilder.getPanel()); + boxGroup.hide(); + } + + private void addCylinderComponent(PanelBuilder builder, FieldChangeListener listener) { + cylinderModel = new DictionaryModel(new Dictionary("")); + + cylinderBuilder = new PanelBuilder(); + cylinderBuilder.addComponent(CYLINDER_NAME_LABEL, cylinderNameField = stringField()); + cylinderBuilder.addComponent(POINT_1_LABEL, cylinderModel.bindPoint(Surface.POINT1_KEY, DECIMAL_PLACES, listener)); + cylinderBuilder.addComponent(POINT_2_LABEL, cylinderModel.bindPoint(Surface.POINT2_KEY, DECIMAL_PLACES, listener)); + cylinderBuilder.addComponent(RADIUS_LABEL, cylinderModel.bindDouble(Surface.RADIUS_KEY, DECIMAL_PLACES, listener)); + cylinderBuilder.getPanel().setBorder(BorderFactory.createTitledBorder("")); + + cylinderGroup = new RowGroup(); + builder.addComponentToGroup(cylinderGroup, cylinderBuilder.getPanel()); + cylinderGroup.hide(); + } + + private void addPlaneComponent(PanelBuilder builder, FieldChangeListener listener) { + planeModel = new DictionaryModel(new Dictionary("")); + planePointAndNormalModel = new DictionaryModel(new Dictionary("")); + + planeBuilder = new PanelBuilder(); + planeBuilder.addComponent(PLANE_NAME_LABEL, planeNameField = stringField()); + planeBuilder.addComponent(ORIGIN_LABEL, planePointAndNormalModel.bindPoint(Surface.BASE_POINT_KEY, DECIMAL_PLACES, listener)); + planeBuilder.addComponent(NORMAL_LABEL, planePointAndNormalModel.bindPoint(Surface.NORMAL_VECTOR_KEY, DECIMAL_PLACES, listener)); + planeBuilder.getPanel().setBorder(BorderFactory.createTitledBorder("")); + + regionBuilder = new PanelBuilder(); + regionBuilder.addComponent(PATCH_NAME_LABEL, regionNameField = stringField()); + regionBuilder.getPanel().setBorder(BorderFactory.createTitledBorder("")); + + planeGroup = new RowGroup(); + builder.addComponentToGroup(planeGroup, planeBuilder.getPanel()); + planeGroup.hide(); + + regionGroup = new RowGroup(); + builder.addComponentToGroup(regionGroup, regionBuilder.getPanel()); + regionGroup.hide(); + } + + private void addSphereComponent(PanelBuilder builder, FieldChangeListener listener) { + sphereModel = new DictionaryModel(new Dictionary("")); + + sphereBuilder = new PanelBuilder(); + sphereBuilder.addComponent(SPHERE_NAME_LABEL, sphereNameField = stringField()); + sphereBuilder.addComponent(CENTRE_LABEL, sphereModel.bindPoint(Surface.CENTRE_KEY, DECIMAL_PLACES, listener)); + sphereBuilder.addComponent(RADIUS_LABEL, sphereModel.bindDouble(Surface.RADIUS_KEY, DECIMAL_PLACES, listener)); + sphereBuilder.getPanel().setBorder(BorderFactory.createTitledBorder("")); + + sphereGroup = new RowGroup(); + builder.addComponentToGroup(sphereGroup, sphereBuilder.getPanel()); + sphereGroup.hide(); + } + + private void addRingComponent(PanelBuilder builder, FieldChangeListener listener) { + ringModel = new DictionaryModel(new Dictionary("")); + + ringBuilder = new PanelBuilder(); + ringBuilder.addComponent(RING_NAME_LABEL, ringNameField = stringField()); + ringBuilder.addComponent(POINT_1_LABEL, ringModel.bindPoint(Surface.POINT1_KEY, DECIMAL_PLACES, listener)); + ringBuilder.addComponent(POINT_2_LABEL, ringModel.bindPoint(Surface.POINT2_KEY, DECIMAL_PLACES, listener)); + ringBuilder.addComponent(INNER_RADIUS_LABEL, ringModel.bindDouble(Surface.INNER_RADIUS_KEY, DECIMAL_PLACES, listener)); + ringBuilder.addComponent(OUTER_RADIUS_LABEL, ringModel.bindDouble(Surface.OUTER_RADIUS_KEY, DECIMAL_PLACES, listener)); + ringBuilder.getPanel().setBorder(BorderFactory.createTitledBorder("")); + + ringGroup = new RowGroup(); + builder.addComponentToGroup(ringGroup, ringBuilder.getPanel()); + ringGroup.hide(); + } + + private void addNoneComponent(PanelBuilder builder, FieldChangeListener listener) { + noneGroup = new RowGroup(); + builder.addComponentToGroup(noneGroup, new JLabel("Select or Add a geometry")); + noneGroup.show(); + } + + void addRenameAction() { + stlNameField.addPropertyChangeListener(renameAction); + boxNameField.addPropertyChangeListener(renameAction); + cylinderNameField.addPropertyChangeListener(renameAction); + sphereNameField.addPropertyChangeListener(renameAction); + ringNameField.addPropertyChangeListener(renameAction); + planeNameField.addPropertyChangeListener(renameAction); + regionNameField.addPropertyChangeListener(renameAction); + } + + void remRenameAction() { + stlNameField.removePropertyChangeListener(renameAction); + boxNameField.removePropertyChangeListener(renameAction); + cylinderNameField.removePropertyChangeListener(renameAction); + sphereNameField.removePropertyChangeListener(renameAction); + ringNameField.removePropertyChangeListener(renameAction); + planeNameField.removePropertyChangeListener(renameAction); + regionNameField.removePropertyChangeListener(renameAction); + } + + private void showSTL() { + hideSelectedInEDT(); + showInEDT(stlGroup); + } + + private void showBox() { + hideSelectedInEDT(); + showInEDT(boxGroup); + } + + private void showCylinder() { + hideSelectedInEDT(); + showInEDT(cylinderGroup); + } + + private void showSphere() { + hideSelectedInEDT(); + showInEDT(sphereGroup); + } + + private void showRing() { + hideSelectedInEDT(); + showInEDT(ringGroup); + } + + private void showPlane() { + hideSelectedInEDT(); + showInEDT(planeGroup); + } + + private void showRegion() { + hideSelectedInEDT(); + showInEDT(regionGroup); + } + + private void showNone() { + hideSelectedInEDT(); + showInEDT(noneGroup); + } + + private void showInEDT(final RowGroup group) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + group.show(); + selected = group; + } + }); + } + + private void hideSelectedInEDT() { + if (selected != null) + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + selected.hide(); + } + }); + } + + public void showPanel(Surface[] surfaces) { + stop(); + if (surfaces == null || surfaces.length == 0) { + showNone(); + selectedSurface = null; + return; + } + boolean singleSelection = surfaces.length == 1; + + Type type = surfaces[0].getType(); + String name; + boolean visible = true; + if (singleSelection) { + name = surfaces[0].getName(); + visible = surfaces[0].isVisible(); + } else { + StringBuilder sb = new StringBuilder(); + for (Surface surface : surfaces) { + sb.append(surface.getName()); + sb.append(" "); + visible = visible && surface.isVisible(); + } + name = sb.toString(); + } + + selectedSurface = surfaces[0]; + + Dictionary dict = surfaces[0].getGeometryDictionary(); + switch (type) { + case BOX: + showBox(); + boxModel.setDictionary(dict); + updatePanel(singleSelection, visible, name, boxNameField, boxBuilder); + break; + + case CYLINDER: + showCylinder(); + cylinderModel.setDictionary(dict); + updatePanel(singleSelection, visible, name, cylinderNameField, cylinderBuilder); + break; + + case SPHERE: + showSphere(); + sphereModel.setDictionary(dict); + updatePanel(singleSelection, visible, name, sphereNameField, sphereBuilder); + break; + case RING: + showRing(); + ringModel.setDictionary(dict); + updatePanel(singleSelection, visible, name, ringNameField, ringBuilder); + break; + + case STL: + showSTL(); + stlModel.setDictionary(dict); + updatePanel(singleSelection, visible, name, stlNameField, stlBuilder); + break; + + case PLANE: + showPlane(); + planePointAndNormalModel.setDictionary(dict.subDict("pointAndNormalDict")); + Dictionary copyDict = new Dictionary(dict); + copyDict.remove("pointAndNormalDict"); + planeModel.setDictionary(copyDict); + updatePanel(singleSelection, visible, name, planeNameField, planeBuilder); + break; + + case SOLID: + case REGION: + showRegion(); + updatePanel(singleSelection, visible, name, regionNameField, regionBuilder); + regionNameField.setEnabled(singleSelection && selectedSurface instanceof PlaneRegion); + break; + + case MULTI: + case LINE: + break; + } + } + + private void updatePanel(boolean singleSelection, boolean visible, String name, StringField nameField, PanelBuilder builder) { + remRenameAction(); + nameField.setValue(name); + if (visible) { + builder.setEnabled(true); + if (singleSelection) { + nameField.setEnabled(true); + builder.setEnabled(true); + } else { + nameField.setEnabled(false); + builder.setEnabled(false); + } + } else { + builder.setEnabled(false); + } + addRenameAction(); + } + + public Dictionary getBoxDictionary() { + Dictionary dict = boxModel.getDictionary(); + if (boxNameField.isEnabled()) { + String name = boxNameField.getText(); + dict.setName(name); + } + + return dict; + } + + public Dictionary getCylinderDictionary() { + Dictionary dict = cylinderModel.getDictionary(); + if (cylinderNameField.isEnabled()) { + String name = cylinderNameField.getText(); + dict.setName(name); + } + + return dict; + } + + public Dictionary getSphereDictionary() { + Dictionary dict = sphereModel.getDictionary(); + if (sphereNameField.isEnabled()) { + String name = sphereNameField.getText(); + dict.setName(name); + } + + return dict; + } + + public Dictionary getRingDictionary() { + Dictionary dict = ringModel.getDictionary(); + if (ringNameField.isEnabled()) { + String name = ringNameField.getText(); + dict.setName(name); + } + + return dict; + } + + public Dictionary getPlaneDictionary() { + Dictionary dict = planeModel.getDictionary(); + Dictionary subDict = planePointAndNormalModel.getDictionary(); + if (planeNameField.isEnabled()) { + String name = planeNameField.getText(); + dict.setName(name); + } + dict.add(subDict); + return dict; + } + + public Dictionary getSTLDictionary() { + Dictionary dict = stlModel.getDictionary(); + if (stlNameField.isEnabled()) + dict.add("name", stlNameField.getText()); + return dict; + } + + public String getRegionName() { + return regionNameField.getText(); + } + + public void stop() { + if (showBoxButton.isSelected()) { + showBoxButton.doClick(); + } + } +} diff --git a/src/eu/engys/gui/mesh/panels/GeometryBuilder.java b/src/eu/engys/gui/mesh/panels/GeometryBuilder.java new file mode 100644 index 0000000..071ca06 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/GeometryBuilder.java @@ -0,0 +1,182 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh.panels; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; +import eu.engys.util.Util; +import eu.engys.util.ui.TreeUtil; + +public class GeometryBuilder { + + private static final Logger logger = LoggerFactory.getLogger(GeometryBuilder.class); + + private GeometriesPanelBuilder geometriesPanel; + private DictionaryModel surfaceModel; + private DictionaryModel volumeModel; + private DictionaryModel layerModel; + private DictionaryModel zoneModel; + private boolean changeSurface; + private boolean changeVolume; + private boolean changeLayer; + private boolean changeZone; + + public GeometryBuilder(GeometriesPanelBuilder geometriesPanel, DictionaryModel surfaceModel, DictionaryModel volumeModel, DictionaryModel layerModel, DictionaryModel zoneModel) { + this.geometriesPanel = geometriesPanel; + this.surfaceModel = surfaceModel; + this.volumeModel = volumeModel; + this.layerModel = layerModel; + this.zoneModel = zoneModel; + } + + public void buildSurfaces(Surface... surfaces) { + if (Util.isVarArgsNotNull(surfaces)) { + Type type = surfaces[0].getType(); + Class typeClass = surfaces[0].getClass(); + + if (TreeUtil.isConsistent(surfaces, typeClass)) { + _buildSurfaces(type, surfaces); + } else { + logger.warn("Inconsistent selection"); + } + } + } + + private void _buildSurfaces(Type type, Surface... surfaces) { + changeSurface = !surfaces[0].getSurfaceDictionary().equals(surfaceModel.getDictionary()); + changeVolume = !surfaces[0].getVolumeDictionary().equals(volumeModel.getDictionary()); + changeLayer = !surfaces[0].getLayerDictionary().equals(layerModel.getDictionary()); + changeZone = !surfaces[0].getZoneDictionary().equals(zoneModel.getDictionary()); + + switch (type) { + case BOX: + buildBox(surfaces); + break; + case CYLINDER: + buildCylinder(surfaces); + break; + case SPHERE: + buildSphere(surfaces); + break; + case RING: + buildRing(surfaces); + break; + case PLANE: + buildPlane(surfaces); + break; + case STL: + buildSTL(surfaces); + break; + case REGION: + case SOLID: + buildRegion(surfaces); + break; + + default: + break; + } + } + + private void buildSTL(Surface... surfaces) { + for (Surface surface : surfaces) { + if (surfaces.length == 1) + surface.buildGeometryDictionary(geometriesPanel.getSTLDictionary()); + if (changeSurface) surface.buildSurfaceDictionary(surfaceModel.getDictionary()); + if (changeVolume) surface.buildVolumeDictionary(volumeModel.getDictionary()); + if (changeLayer) surface.buildLayerDictionary(layerModel.getDictionary()); + if (changeZone) surface.buildZoneDictionary(zoneModel.getDictionary()); + } + } + + private void buildRegion(Surface... surfaces) { + for (Surface surface : surfaces) { + if (changeSurface) surface.buildSurfaceDictionary(surfaceModel.getDictionary()); + if (changeVolume) surface.buildVolumeDictionary(volumeModel.getDictionary()); + if (changeLayer) surface.buildLayerDictionary(layerModel.getDictionary()); +// if (changeZone) surface.buildZoneDictionary(zoneModel.getDictionary()); + } + } + + private void buildBox(Surface... surfaces) { + for (Surface surface : surfaces) { + if (surfaces.length == 1) + surface.buildGeometryDictionary(geometriesPanel.getBoxDictionary()); + if (changeSurface) surface.buildSurfaceDictionary(surfaceModel.getDictionary()); + if (changeVolume) surface.buildVolumeDictionary(volumeModel.getDictionary()); + if (changeLayer) surface.buildLayerDictionary(layerModel.getDictionary()); + if (changeZone) surface.buildZoneDictionary(zoneModel.getDictionary()); + } + } + + private void buildCylinder(Surface... surfaces) { + for (Surface surface : surfaces) { + if (surfaces.length == 1) + surface.buildGeometryDictionary(geometriesPanel.getCylinderDictionary()); + if (changeSurface) surface.buildSurfaceDictionary(surfaceModel.getDictionary()); + if (changeVolume) surface.buildVolumeDictionary(volumeModel.getDictionary()); + if (changeLayer) surface.buildLayerDictionary(layerModel.getDictionary()); + if (changeZone) surface.buildZoneDictionary(zoneModel.getDictionary()); + } + } + + private void buildSphere(Surface... surfaces) { + for (Surface surface : surfaces) { + if (surfaces.length == 1) + surface.buildGeometryDictionary(geometriesPanel.getSphereDictionary()); + if (changeSurface) surface.buildSurfaceDictionary(surfaceModel.getDictionary()); + if (changeVolume) surface.buildVolumeDictionary(volumeModel.getDictionary()); + if (changeLayer) surface.buildLayerDictionary(layerModel.getDictionary()); + if (changeZone) surface.buildZoneDictionary(zoneModel.getDictionary()); + } + } + + private void buildRing(Surface... surfaces) { + for (Surface surface : surfaces) { + if (surfaces.length == 1) + surface.buildGeometryDictionary(geometriesPanel.getRingDictionary()); + if (changeSurface) surface.buildSurfaceDictionary(surfaceModel.getDictionary()); + if (changeVolume) surface.buildVolumeDictionary(volumeModel.getDictionary()); + if (changeLayer) surface.buildLayerDictionary(layerModel.getDictionary()); + if (changeZone) surface.buildZoneDictionary(zoneModel.getDictionary()); + } + } + + private void buildPlane(Surface... surfaces) { + for (Surface surface : surfaces) { + if (surfaces.length == 1) + surface.buildGeometryDictionary(geometriesPanel.getPlaneDictionary()); + if (changeSurface) surface.buildSurfaceDictionary(surfaceModel.getDictionary()); + if (changeVolume) surface.buildVolumeDictionary(volumeModel.getDictionary()); + if (changeLayer) surface.buildLayerDictionary(layerModel.getDictionary()); + if (changeZone) surface.buildZoneDictionary(zoneModel.getDictionary()); + } + } +} diff --git a/src/eu/engys/gui/mesh/panels/GeometryTreeNodeManager.java b/src/eu/engys/gui/mesh/panels/GeometryTreeNodeManager.java new file mode 100644 index 0000000..ab835f0 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/GeometryTreeNodeManager.java @@ -0,0 +1,353 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import java.awt.Component; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; + +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreePath; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.core.project.geometry.Geometry; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.BaseSurface; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.SelectSurfaceEvent; +import eu.engys.gui.tree.AbstractSelectionHandler; +import eu.engys.gui.tree.DefaultTreeNodeManager; +import eu.engys.gui.tree.SelectionHandler; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.Util; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.TreeUtil; +import eu.engys.util.ui.checkboxtree.RootVisibleItem; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class GeometryTreeNodeManager extends DefaultTreeNodeManager { + + private static final Logger logger = LoggerFactory.getLogger(GeometryTreeNodeManager.class); + + private Map surfaceMap; + private GeometrySelectionHandler selectionHandler; + private DefaultGeometryActions geometryActions; + + public GeometryTreeNodeManager(Model model, Controller controller, AbstractGeometryPanel panel, DefaultGeometryActions geometryActions) { + super(model, panel); + this.root = new DefaultMutableTreeNode(new RootVisibleItem(panel.getTitle())); + this.selectionHandler = new GeometrySelectionHandler(panel); + this.geometryActions = geometryActions; + this.surfaceMap = new HashMap<>(); + } + + @Override + public void update(Observable o, final Object arg) { + if (!(arg instanceof FeatureLine) && (arg instanceof Stl || arg instanceof BaseSurface)) { + logger.debug("Observerd a change: arg is " + arg.getClass()); + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + selectionHandler.disable(); + loadTree(); + expandTree(arg); + selectionHandler.enable(); + selectArgument(arg); + } + }); + } else if (arg instanceof Geometry) { + logger.debug("Observerd a change: arg is Geometry"); + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + selectionHandler.disable(); + loadTree(); + makeVisibleItemsChecked(); + expandTree(arg); + selectionHandler.enable(); + } + }); + } else if (arg instanceof Patches) { + logger.debug("Observerd a change: arg is Patches"); + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + makeVisibleItemsChecked(); + } + }); + } + } + + private void selectArgument(Object arg) { + if (arg instanceof Surface) { + Surface surface = (Surface) arg; + setSelectedValue(surface); + } + } + + private void loadTree() { + logger.debug("Load 'Geometry' tree"); + clear(); + for (Surface surface : model.getGeometry().getSurfaces()) { + addSurface(root, surface); + if (surface.getType().isStl()) { + if (surface.isSingleton()) { + // do nothing + } else { + Stl stl = (Stl) surface; + DefaultMutableTreeNode parentNode = nodeMap.get(stl); + for (Surface region : stl.getRegions()) { + addSurface(parentNode, region); + } + } + } + } + treeChanged(root); + } + + private void addSurface(DefaultMutableTreeNode parent, Surface surface) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(surface); + parent.add(node); + nodeMap.put(surface, node); + surfaceMap.put(node, surface); + } + + private void makeVisibleItemsChecked() { + logger.debug("Make visible items checked"); + if (getTree() != null) { + if (model.getPatches() == null || model.getPatches().isEmpty()) + getTree().getCheckManager().selectNode(getRoot()); + else + getTree().getCheckManager().deselectNode(getRoot()); + } + } + + private void expandTree(final Object arg) { + if (getTree() != null) { + if (shouldExpand(arg)) { + logger.debug("Expand the tree"); + getTree().expandNode(getRoot()); + } + } + } + + private boolean shouldExpand(final Object arg) { + return arg instanceof Stl || arg instanceof BaseSurface || arg instanceof Geometry; + } + + private void setSelectedValue(Surface surface) { + DefaultMutableTreeNode selectedNode = nodeMap.get(surface); + if (getTree() != null) { + if (selectedNode != null) { + getTree().setSelectedNode(selectedNode); + } else { + getTree().setSelectedNode(getRoot()); + } + } + } + + public Surface[] getSelectedValues() { + if (getTree() != null) { + TreePath[] selectionPaths = getTree().getSelectionPaths(); + if (selectionPaths != null) { + Surface[] surfaces = new Surface[selectionPaths.length]; + for (int i = 0; i < selectionPaths.length; i++) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPaths[i].getLastPathComponent(); + Surface surface = surfaceMap.get(node); + surfaces[i] = surface; + } + return surfaces; + } + } + return new Surface[0]; + } + + public void clear() { + // clear node before selection handler! + clearNode(root); + selectionHandler.clear(); + nodeMap.clear(); + surfaceMap.clear(); + } + + public DefaultMutableTreeNode getRoot() { + return root; + } + + @Override + public Class getRendererClass() { + return Surface.class; + } + + @Override + public DefaultTreeCellRenderer getRenderer() { + return new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObject = node.getUserObject(); + + if (userObject instanceof Surface) { + Surface surface = (Surface) userObject; + setText(surface.getName()); + } + setIcon(null); + return this; + } + }; + } + + @Override + public SelectionHandler getSelectionHandler() { + return selectionHandler; + } + + @Override + public PopUpBuilder getPopUpBuilder() { + return geometryActions; + } + + public final class GeometrySelectionHandler extends AbstractSelectionHandler { + + private final AbstractGeometryPanel panel; + private Surface[] currentSelection; + + public GeometrySelectionHandler(AbstractGeometryPanel panel) { + this.panel = panel; + } + + @Override + public void handleSelection(boolean fire3DEvent, Object... selection) { + saveCurrentSelection(); + + boolean isValidSelection = TreeUtil.isConsistent(selection, Surface.class); + if (isValidSelection) { + handleValidSelection(fire3DEvent, selection); + } else { + boolean shouldClearSelection = TreeUtil.isConsistent(currentSelection, Surface.class); + if (shouldClearSelection) { + clearSelection(fire3DEvent); + } + } + } + + private void saveCurrentSelection() { + if (Util.isVarArgsNotNull(currentSelection)) { + panel.saveSurfaces(currentSelection); + } + } + + private void handleValidSelection(boolean fire3DEvent, Object... selection) { + logger.debug("handleSelection: {} selected, fire3D {} {}", selection.length, fire3DEvent, selection.length == 1 ? ", selection is: " + selection[0] : ""); + + this.currentSelection = Arrays.copyOf(selection, selection.length, Surface[].class); + panel.selectSurface(currentSelection); + + if (fire3DEvent) { + EventManager.triggerEvent(this, new SelectSurfaceEvent(currentSelection)); + } + + geometryActions.updateActions(currentSelection); + } + + private void clearSelection(boolean fire3DEvent) { + clear(); + panel.deselectAll(); + if (fire3DEvent) { + EventManager.triggerEvent(this, new SelectSurfaceEvent(new Surface[0])); + } + } + + @Override + public void handleVisibility(VisibleItem item) { + if (Util.isVarArgsNotNull(currentSelection) && Arrays.asList(currentSelection).contains(item)) { + logger.debug("handleVisibility: {}", item); + panel.selectSurface(currentSelection); + EventManager.triggerEvent(this, new SelectSurfaceEvent(currentSelection)); + } + } + + @Override + public void process3DSelectionEvent(Picker picker, Actor actor, boolean keep) { + if (getTree() != null && actor != null && actor.getVisibleItem() instanceof Surface) { + Surface surface = (Surface) actor.getVisibleItem(); + if (surface instanceof Solid && ((Solid) surface).getParent().isSingleton()) { + surface = ((Solid) surface).getParent(); + } + DefaultMutableTreeNode selectedNode = nodeMap.get(surface); + logger.debug("Handle selection from 3D {}", surface); + if (selectedNode != null) { + boolean alreadySelected = getTree().isAlreadySelected(selectedNode); + if(alreadySelected){ + logger.debug("Handle selection from 3D REM"); + getTree().removeSelectedNode(selectedNode); + } else { + if (keep) { + logger.debug("Handle selection from 3D ADD"); + getTree().addSelectedNode(selectedNode); + } else { + logger.debug("Handle selection from 3D SET"); + getTree().setSelectedNode(selectedNode); + } + } + + } + } + } + + @Override + public void process3DVisibilityEvent(boolean selected) { + logger.debug("handle selection from check box"); + if (getTree() != null) { + if (selected) { + // getTree().getCheckManager().selectNode(getRoot()); + } else { + getTree().getCheckManager().deselectNode(getRoot()); + } + } + } + + @Override + public void clear() { + currentSelection = null; + } + } + +} diff --git a/src/eu/engys/gui/mesh/panels/MaterialPointsPanel.java b/src/eu/engys/gui/mesh/panels/MaterialPointsPanel.java new file mode 100644 index 0000000..49e11fb --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/MaterialPointsPanel.java @@ -0,0 +1,124 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh.panels; + +import static eu.engys.core.project.system.SnappyHexMeshDict.CASTELLATED_MESH_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.LOCATION_IN_MESH; +import static eu.engys.core.project.system.SnappyHexMeshDict.REFINEMENTS_REGIONS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.REFINEMENTS_SURFACES_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.WRAPPER_KEY; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.JComponent; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.PointInfo; +import eu.engys.core.dictionary.model.ShowLocationAdapter; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.SnappyHexMeshDict; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.PointEvent; +import eu.engys.util.ui.builder.PanelBuilder; + +public class MaterialPointsPanel extends DefaultGUIPanel { + + public static final String TITLE = "Material Point"; + + private DictionaryModel castellatedModel; + private ShowLocationAdapter locationPanel; + + @Inject + public MaterialPointsPanel(Model model) { + super(TITLE, model); + } + + @Override + public void start() { + super.start(); + locationPanel.turnMaterialPointsOn(); + } + + @Override + public void stop() { + super.stop(); + locationPanel.turnMaterialPointsOff(); + } + + @Override + protected JComponent layoutComponents() { + castellatedModel = new DictionaryModel(new Dictionary("")); + + PanelBuilder builder = new PanelBuilder(); + locationPanel = castellatedModel.bindLocation(LOCATION_IN_MESH, 4); + builder.addComponent(locationPanel); + locationPanel.addPropertyChangeListener(PointInfo.PROPERTY_NAME, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(PointInfo.PROPERTY_NAME)) { + PointInfo pi = (PointInfo) evt.getNewValue(); + EventManager.triggerEvent(this, new PointEvent(pi.getPoint(), pi.getKey(), pi.getAction(), pi.getColor())); + } + } + }); + + return builder.removeMargins().getPanel(); + + } + + @Override + public void load() { + SnappyHexMeshDict snappyDict = model.getProject().getSystemFolder().getSnappyHexMeshDict(); + if (snappyDict != null) { + if (snappyDict.found(CASTELLATED_MESH_CONTROLS_KEY)) { + Dictionary castellated = snappyDict.subDict(CASTELLATED_MESH_CONTROLS_KEY); + + Dictionary castellatedCopy = new Dictionary(castellated); + castellatedCopy.remove(REFINEMENTS_SURFACES_KEY); + castellatedCopy.remove(REFINEMENTS_REGIONS_KEY); + castellatedCopy.remove(WRAPPER_KEY); + this.castellatedModel.setDictionary(castellatedCopy); + } + } + } + + @Override + public void save() { + SnappyHexMeshDict snappyDict = model.getProject().getSystemFolder().getSnappyHexMeshDict(); + if (snappyDict != null) { + Dictionary castellated = snappyDict.subDict(CASTELLATED_MESH_CONTROLS_KEY); + String locations = castellatedModel.getDictionary().lookup(LOCATION_IN_MESH); + castellated.add(LOCATION_IN_MESH, locations); + } + } + +} diff --git a/src/eu/engys/gui/mesh/panels/SolverBoundaryMeshPanel.java b/src/eu/engys/gui/mesh/panels/SolverBoundaryMeshPanel.java new file mode 100644 index 0000000..5d216e0 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/SolverBoundaryMeshPanel.java @@ -0,0 +1,207 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh.panels; + +import static eu.engys.util.ui.ComponentsFactory.labelField; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JTextArea; + +import eu.engys.core.project.Model; +import eu.engys.gui.AbstractGUIPanel; +import eu.engys.gui.tree.TreeNodeManager; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.builder.PanelBuilder; + +public class SolverBoundaryMeshPanel extends AbstractGUIPanel { + + public static final String TITLE = "Mesh"; + private static final DecimalFormat formatter = new DecimalFormat("#.###", new DecimalFormatSymbols(Locale.US)); + + private BoundaryMeshTreeNodeManager treeNodeManager; + + private JLabel name; + private JLabel path; + private JLabel created; + private JLabel cells; + private JLabel points; + private JLabel faces; + private JTextArea cellsPerLevel; + private JLabel memory; + + private JLabel xBounds; + private JLabel yBounds; + private JLabel zBounds; + + private PanelBuilder dataArrays; + + @Inject + public SolverBoundaryMeshPanel(Model model) { + super(TITLE, model); + this.treeNodeManager = new BoundaryMeshTreeNodeManager(model, this); + model.addObserver(treeNodeManager); + } + + protected JComponent layoutComponents() { + name = labelField(""); + path = labelField(""); + created = labelField(""); + + cells = labelField(""); + points = labelField(""); + faces = labelField(""); + + cellsPerLevel = ComponentsFactory.labelArea(); + cellsPerLevel.setEditable(false); + + memory = labelField(""); + + xBounds = labelField(""); + yBounds = labelField(""); + zBounds = labelField(""); + + PanelBuilder properties = new PanelBuilder(); + properties.getPanel().setBorder(BorderFactory.createTitledBorder("Properties")); + properties.addComponent("Name", name); + properties.addComponent("Path", path); + properties.addComponent("Created", created); + + PanelBuilder statistics = new PanelBuilder(); + statistics.getPanel().setBorder(BorderFactory.createTitledBorder("Statistics")); + statistics.addComponent("Number of Cells", cells); + statistics.addComponent("Number of Faces", faces); + statistics.addComponent("Number of Points", points); + statistics.addComponent("Cells per Refinement Level", cellsPerLevel); + // statistics.addComponent("Memory [MB]", memory); + + dataArrays = new PanelBuilder(); + dataArrays.getPanel().setBorder(BorderFactory.createTitledBorder("Data Arrays")); + + PanelBuilder bounds = new PanelBuilder(); + bounds.getPanel().setBorder(BorderFactory.createTitledBorder("Bounds")); + bounds.addComponent("X Range", xBounds); + bounds.addComponent("Y Range", yBounds); + bounds.addComponent("Z Range", zBounds); + + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(properties.getPanel()); + builder.addComponent(statistics.getPanel()); + builder.addComponent(dataArrays.getPanel()); + builder.addComponent(bounds.getPanel()); + return builder.removeMargins().getPanel(); + } + + @Override + public void start() { + super.start(); + } + + @Override + public void load() { + name.setText(model.getProject().getBaseDir().getName()); + path.setText(model.getProject().getBaseDir().getParent()); + + try { + Path basePath = model.getProject().getBaseDir().toPath(); + long lastModify = Files.getLastModifiedTime(basePath).toMillis(); + created.setText(DateFormat.getDateInstance().format(new Date(lastModify))); + } catch (Exception e) { + created.setText("-"); + } + + if (model.getMesh() != null) { + cells.setText(formatter.format(model.getMesh().getNumberOfCells())); + points.setText(formatter.format(model.getMesh().getNumberOfPoints())); + faces.setText(formatter.format(model.getMesh().getNumberOfFaces())); + + List cellsPerRefinementLevel = model.getMesh().getCellsPerRefinementLevel(); + String text = ""; + for (int i = 0; i < cellsPerRefinementLevel.size(); i++) { + if (i > 0) + text += "\n"; + text += i + "\t" + cellsPerRefinementLevel.get(i); + } + cellsPerLevel.setText(text); + + // memory.setText(formatter.format(model.getMesh().getMemorySize()/1024D)); + + double[] bounds = model.getMesh().getBounds(); + + xBounds.setText(getTextForBounds(bounds[0], bounds[1])); + yBounds.setText(getTextForBounds(bounds[2], bounds[3])); + zBounds.setText(getTextForBounds(bounds[4], bounds[5])); + } else { + cells.setText("-"); + points.setText("-"); + faces.setText("-"); + cellsPerLevel.setText(" - "); + // memory.setText("-"); + xBounds.setText("[- , -]"); + yBounds.setText("[- , -]"); + zBounds.setText("[- , -]"); + } + } + + private String getTextForBounds(double min, double max) { + if (areValid(min, max)) { + return "[" + formatter.format(min) + " , " + formatter.format(max) + "] (Delta " + formatter.format(max - min) + ")"; + } else { + return "[0 , 0]"; + } + } + + private boolean areValid(double min, double max) { + return min < Double.MAX_VALUE && max > -Double.MAX_VALUE; + } + + @Override + public void save() { + } + + @Override + public void stop() { + super.stop(); + } + + @Override + public TreeNodeManager getTreeNodeManager() { + return treeNodeManager; + } + +} diff --git a/src/eu/engys/gui/mesh/panels/StandardBaseMeshPanel.java b/src/eu/engys/gui/mesh/panels/StandardBaseMeshPanel.java new file mode 100644 index 0000000..e911afd --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/StandardBaseMeshPanel.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import static eu.engys.core.project.system.BlockMeshDict.SPACING_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.AUTO_BLOCK_MESH_KEY; + +import com.google.inject.Inject; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.BlockMeshDict; +import eu.engys.core.project.system.SnappyHexMeshDict; + +public class StandardBaseMeshPanel extends AbstractBaseMeshPanel { + + @Inject + public StandardBaseMeshPanel(Model model, Controller controller) { + super(model, controller); + } + + @Override + protected void loadSpacing() { + BlockMeshDict blockMeshDict = model.getProject().getSystemFolder().getBlockMeshDict(); + if (blockMeshDict != null && blockMeshDict.found(SPACING_KEY)) { + setBaseMeshSpacing(blockMeshDict.lookupDouble(SPACING_KEY)); + } + } + + @Override + public void save() { + super.save(); + fixSpacing(); + fixAutoBlockMesh(); + } + + private void fixAutoBlockMesh() { + SnappyHexMeshDict snappyDict = model.getProject().getSystemFolder().getSnappyHexMeshDict(); + if (snappyDict != null) { + if (model.getGeometry().isAutoBoundingBox()) { + snappyDict.add(AUTO_BLOCK_MESH_KEY, String.valueOf(true)); + } else { + snappyDict.add(AUTO_BLOCK_MESH_KEY, String.valueOf(false)); + } + } + } + + private void fixSpacing() { + BlockMeshDict blockMeshDict = model.getProject().getSystemFolder().getBlockMeshDict(); + if (blockMeshDict != null) { + if (isUserDefined() || isFromFile()) { + blockMeshDict.remove(SPACING_KEY); + } else if (isAutomatic()) { + blockMeshDict.add(SPACING_KEY, Double.toString(getBaseMeshSpacing())); + } + } + } +} diff --git a/src/eu/engys/gui/mesh/panels/StandardFeatureLinesPanel.java b/src/eu/engys/gui/mesh/panels/StandardFeatureLinesPanel.java new file mode 100644 index 0000000..d851cd5 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/StandardFeatureLinesPanel.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import com.google.inject.Inject; + +import eu.engys.core.project.Model; + +public class StandardFeatureLinesPanel extends FeatureLinesPanel { + + @Inject + public StandardFeatureLinesPanel(Model model) { + super(model); + } + + @Override + protected boolean hasRefineOnly() { + return false; + } + +} diff --git a/src/eu/engys/gui/mesh/panels/StandardGeometryPanel.java b/src/eu/engys/gui/mesh/panels/StandardGeometryPanel.java new file mode 100644 index 0000000..f1a9d78 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/StandardGeometryPanel.java @@ -0,0 +1,169 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels; + +import static eu.engys.core.project.system.SnappyHexMeshDict.BAFFLE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.BOUNDARY_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.EXPANSION_RATIO_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_TYPE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_ZONE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FINAL_LAYER_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.GAP_LEVEL_INCREMENT_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.INTERNAL_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.IS_CELL_ZONE; +import static eu.engys.core.project.system.SnappyHexMeshDict.LEVEL_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.NONE_KEY; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JPanel; + +import com.google.inject.Inject; + +import eu.engys.core.controller.Controller; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.SnappyHexMeshDict; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.IntegerField; +import eu.engys.util.ui.textfields.StringField; + +public class StandardGeometryPanel extends AbstractGeometryPanel { + + private static final String LAYER_MIN_THICKNESS_LABEL = "Layer Min Thickness"; + + @Inject + public StandardGeometryPanel(Model model, Controller controller) { + super(model, controller); + } + + @Override + protected DefaultGeometryActions getGeometryActions(Controller controller) { + return new DefaultGeometryActions(this, controller); + } + + @Override + protected JPanel getSurfacesPanel() { + surfaceBuilder = new PanelBuilder(); + surfaceBuilder.addComponent(LEVEL_LABEL, surfaceModel.bindIntegerArray(LEVEL_KEY, 2)); + surfaceBuilder.addComponent(PROXIMITY_REFINEMENT_LABEL, surfaceModel.bindIntegerPositive(GAP_LEVEL_INCREMENT_KEY)); + surfaceBuilder.getPanel().setBorder(BorderFactory.createTitledBorder(SURFACE_LABEL)); + return surfaceBuilder.getPanel(); + } + + @Override + protected JPanel getLayersPanel() { + layersBuilder = new PanelBuilder(); + layersBuilder.addComponent(NUMBER_OF_LAYERS_LABEL, layerModel.bindIntegerPositive(SnappyHexMeshDict.N_SURFACE_LAYERS_KEY)); + layersBuilder.addComponent(FINAL_LAYER_THICKNESS_LABEL, layerModel.bindDouble(FINAL_LAYER_THICKNESS_KEY, (Double) null)); + layersBuilder.addComponent(LAYER_MIN_THICKNESS_LABEL, layerModel.bindDouble(MIN_THICKNESS_KEY, (Double) null)); + layersBuilder.addComponent(LAYER_STRETCHING_LABEL, layerModel.bindDouble(EXPANSION_RATIO_KEY, (Double) null)); + return layersBuilder.getPanel(); + } + + @Override + protected JPanel getZonesPanel() { + zonesBuilder = new PanelBuilder(); + String[] TYPE_KEYS = { NONE_KEY, INTERNAL_KEY, BOUNDARY_KEY, BAFFLE_KEY }; + String[] TYPE_LABELS = { NONE_LABEL, INTERNAL_LABEL, BOUNDARY_LABEL, BAFFLE_LABEL }; + final JComboBox zoneType = zoneModel.bindSelection(FACE_TYPE_KEY, TYPE_KEYS, TYPE_LABELS); + final StringField zoneName = zoneModel.bindLabel(FACE_ZONE_KEY, true); + final JCheckBox isCellZone = zoneModel.bindBoolean(IS_CELL_ZONE); + final IntegerField[] zoneLevel = zoneModel.bindIntegerArray(LEVEL_KEY, 2); + + zonesBuilder.addComponent(TYPE_LABEL, zoneType); + zonesBuilder.addComponent(NAME_LABEL, zoneName); + zonesBuilder.addComponent(CELL_ZONE_LABEL, isCellZone); + zonesBuilder.addComponent(LEVEL_LABEL, zoneLevel); + + zoneName.setEnabled(false); + isCellZone.setEnabled(false); + zoneLevel[0].setEnabled(false); + zoneLevel[1].setEnabled(false); + + zoneType.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + boolean enabled = zoneType.getSelectedIndex() > 0; + zoneName.setEnabled(enabled); + zoneLevel[0].setEnabled(enabled); + zoneLevel[1].setEnabled(enabled); + isCellZone.setEnabled(enabled); + } + }); + return zonesBuilder.getPanel(); + } + + // public static void main(String[] args) { + // SwingUtilities.invokeLater(new Runnable() { + // + // @Override + // public void run() { + // new HelyxOSLookAndFeel().init(); + // StandardGeometryPanel panel = new StandardGeometryPanel(new Model()); + // panel.layoutPanel(); + // UiUtil.show("Prova", panel); + // panel.layerModel.setDictionary(new Dictionary("pippo")); + // } + // }); + // } + + @Override + protected JButton[] getShapeButtons() { + JButton[] buttons = new JButton[5]; + + JButton stlButton = new JButton(ActionManager.getInstance().get("mesh.stl")); + stlButton.setName("add.stl.button"); + buttons[0] = stlButton; + + JButton boxButton = new JButton(ActionManager.getInstance().get("mesh.box")); + boxButton.setName("add.box.button"); + buttons[1] = boxButton; + + stlButton.setPreferredSize(boxButton.getPreferredSize()); + + JButton sphereButton = new JButton(ActionManager.getInstance().get("mesh.sphere")); + sphereButton.setName("add.sphere.button"); + buttons[2] = sphereButton; + + JButton cylinderButton = new JButton(ActionManager.getInstance().get("mesh.cylinder")); + cylinderButton.setName("add.cylinder.button"); + buttons[3] = cylinderButton; + + JButton planeButton = new JButton(ActionManager.getInstance().get("mesh.plane")); + planeButton.setName("add.plane.button"); + buttons[4] = planeButton; + + return buttons; + } + +} diff --git a/src/eu/engys/gui/mesh/panels/StandardMeshAdvancedOptionsPanel.java b/src/eu/engys/gui/mesh/panels/StandardMeshAdvancedOptionsPanel.java new file mode 100644 index 0000000..4e3e063 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/StandardMeshAdvancedOptionsPanel.java @@ -0,0 +1,199 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.mesh.panels; + +import static eu.engys.core.project.system.SnappyHexMeshDict.ADD_LAYERS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.ALLOW_FREE_STANDING_ZONE_FACES_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.CASTELLATED_MESH_CONTROLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.CASTELLATED_MESH_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.DEBUG_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.EXPANSION_RATIO_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.EXPLICIT_FEATURE_SNAP_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FEATURE_ANGLE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FINAL_LAYER_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.IMPLICIT_FEATURE_SNAP_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_FACE_THICKNESS_RATIO_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_GLOBAL_CELLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_LOAD_UNBALANCE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_LOCAL_CELLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_THICKNESS_TO_MEDIAL_RATIO_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MERGE_TOLERANCE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_MEDIAL_AXIS_ANGLE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_REFINEMENT_CELLS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MIN_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MULTI_REGION_FEATURE_SNAP_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_BUFFER_CELLS_NO_EXTRUDE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_CELLS_BETWEEN_LEVELS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_FEATURE_SNAP_ITER_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_GROW_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_LAYER_ITER_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_RELAXED_ITER_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_RELAX_ITER_LAYERS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_RELAX_ITER_SNAP_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_SMOOTH_NORMALS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_SMOOTH_PATCH_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_SMOOTH_SURFACE_NORMALS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_SMOOTH_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_SOLVER_ITER_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.PLANAR_ANGLE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.RESOLVE_FEATURE_ANGLE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.SLIP_FEATURE_ANGLE_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.SNAP_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.TOLERANCE_KEY; + +import javax.swing.JPanel; + +import com.google.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.SnappyHexMeshDict; +import eu.engys.util.ui.builder.PanelBuilder; + +public class StandardMeshAdvancedOptionsPanel extends DefaultMeshAdvancedOptionsPanel { + + + // CASTELLATED + public static final String PLANAR_ANGLE_LABEL = "Planar Angle"; + public static final String PLANAR_ANGLE_TOOLTIP = "Planar angle"; + + //SNAP + public static final String SNAP_FEATURE_ITERATIONS_LABEL = "Snap Feature Iterations"; + public static final String SNAP_FEATURE_ITERATIONS_TOOLTIP = "Number of feature edge snapping iterations"; + public static final String EXPLICIT_SNAP_FEATURE_LABEL = "Explicit Snap Feature"; + public static final String EXPLICIT_SNAP_FEATURE_TOOLTIP = "Use features in castellatedMeshControls"; + public static final String IMPLICIT_SNAP_FEATURE_LABEL = "Implicit Snap Feature"; + public static final String IMPLICIT_SNAP_FEATURE_TOOLTIP = "Detects (geometric only) features by sampling the surface"; + public static final String MULTI_REGION_FEATURE_LABEL = "Multi Region Feature"; + public static final String MULTI_REGION_FEATURE_TOOLTIP = "For explicitFeatureSnap, detect features between multiple surfaces"; + + //LAYERS + public static final String NUMBER_OF_LAYERS_NOT_GROWN_LABEL = "Layers Not Grown"; + public static final String NUMBER_OF_LAYERS_NOT_GROWN_TOOLTIP = "Number of layers of connected faces that are not grown if points get not extruded; helps convergence of layer addition close to features"; + public static final String LAYER_ADDITION_ITERATIONS_LABEL = "Layer Addition Iterations"; + public static final String LAYER_ADDITION_ITERATIONS_TOOLTIP = "Overall maximum number of layer addition iterations"; + public static final String NUMBER_OF_BUFFER_CELLS_LABEL = "Number of Buffer Cells"; + public static final String NUMBER_OF_BUFFER_CELLS_TOOLTIP = "Create buffer region for new layer terminations"; + public static final String SMOOTH_LAYER_THICKNESS_LABEL = "Smooth Layer Thickness"; + public static final String SMOOTH_LAYER_THICKNESS_TOOLTIP = "Smooth layer thickness over surface patches"; + public static final String SLIP_FEATURE_ANGLE_LABEL = "Slip Feature Angle"; + public static final String SLIP_FEATURE_ANGLE_TOOLTIP = "Sliding of vertices along a boundary will occur when the angle between the patch on which layers are added and its neighbouring patch is larger than that specified by this value"; + public static final String FEATURE_ANGLE_LABEL = "Feature Angle"; + public static final String FEATURE_ANGLE_TOOLTIP = "Angle above which surface is not extruded"; + + @Inject + public StandardMeshAdvancedOptionsPanel(Model model) { + super(model); + } + + @Override + protected JPanel createGeneralPanel() { + PanelBuilder builder = new PanelBuilder("options.general.panel"); + + builder.addComponent(CASTELLATED_MESH_LABEL, snappyHexMeshModel.bindBoolean(CASTELLATED_MESH_KEY), CASTELLATED_MESH_TOOLTIP); + builder.addComponent(SNAPPING_LABEL, snappyHexMeshModel.bindBoolean(SNAP_KEY), SNAPPING_TOOLTIP); + builder.addComponent(LAYERS_ADDITION_LABEL, snappyHexMeshModel.bindBoolean(ADD_LAYERS_KEY), LAYERS_ADDITION_TOOLTIP); + + builder.addComponent(DEBUG_LABEL, snappyHexMeshModel.bindInteger(DEBUG_KEY, 0, 2), DEBUG_TOOLTIP); + builder.addComponent(MERGE_TOLERANCE_LABEL, snappyHexMeshModel.bindDouble(MERGE_TOLERANCE_KEY), MERGE_TOLERANCE_TOOLTIP); + + return builder.getPanel(); + } + + @Override + protected JPanel createRefinementsPanel() { + PanelBuilder builder = new PanelBuilder("options.geometry.panel"); + builder.addComponent(MAX_LOCAL_CELLS_LABEL, castellatedMeshControlsModel.bindIntegerPositive(MAX_LOCAL_CELLS_KEY), MAX_LOCAL_CELLS_TOOLTIP); + builder.addComponent(MAX_GLOBAL_CELLS_LABEL, castellatedMeshControlsModel.bindIntegerPositive(MAX_GLOBAL_CELLS_KEY), MAX_GLOBAL_CELLS_TOOLTIP); + builder.addComponent(MIN_REFINEMENT_CELLS_LABEL, castellatedMeshControlsModel.bindIntegerPositive(MIN_REFINEMENT_CELLS_KEY), MIN_REFINEMENT_CELLS_TOOLTIP); + builder.addComponent(CELLS_BETWEEN_LEVELS_LABEL, castellatedMeshControlsModel.bindInteger(N_CELLS_BETWEEN_LEVELS_KEY, 1, Integer.MAX_VALUE), CELLS_BETWEEN_LEVELS_TOOLTIP); + builder.addComponent(RESOLVE_FEATURE_ANGLE_LABEL, castellatedMeshControlsModel.bindDoubleAngle_360(RESOLVE_FEATURE_ANGLE_KEY), RESOLVE_FEATURE_ANGLE_TOOLTIP); + builder.addComponent(ALLOW_FREE_STANDING_ZONE_FACES_LABEL, castellatedMeshControlsModel.bindBoolean(ALLOW_FREE_STANDING_ZONE_FACES_KEY), ALLOW_FREE_STANDING_ZONE_FACES_TOOLTIP); + builder.addComponent(PLANAR_ANGLE_LABEL, castellatedMeshControlsModel.bindDoubleAngle_360(PLANAR_ANGLE_KEY), PLANAR_ANGLE_TOOLTIP); + builder.addComponent(MAX_LOAD_UNBALANCE_LABEL, castellatedMeshControlsModel.bindDoublePositive(MAX_LOAD_UNBALANCE_KEY), MAX_LOAD_UNBALANCE_TOOLTIP); + return builder.getPanel(); + } + + @Override + protected JPanel createLayersPanel() { + PanelBuilder builder = new PanelBuilder("options.layers.panel"); + builder.addComponent(EXPANSION_RATIO_LABEL, layersControlsModel.bindDouble(EXPANSION_RATIO_KEY), EXPANSION_RATIO_TOOLTIP); + builder.addComponent(FINAL_LAYER_THICKNESS_LABEL, layersControlsModel.bindDouble(FINAL_LAYER_THICKNESS_KEY), FINAL_LAYER_THICKNESS_TOOLTIP); +// builder.addComponent(RELATIVE_SIZES_LABEL, layersControlsModel.bindBoolean(RELATIVE_SIZES_KEY), RELATIVE_SIZES_TOOLTIP); + builder.addComponent(MIN_THICKNESS_LABEL, layersControlsModel.bindDouble(MIN_THICKNESS_KEY), MIN_THICKNESS_TOOLTIP); + builder.addComponent(FEATURE_ANGLE_LABEL, layersControlsModel.bindDoubleAngle_360(FEATURE_ANGLE_KEY), FEATURE_ANGLE_TOOLTIP); + builder.addComponent(SLIP_FEATURE_ANGLE_LABEL, layersControlsModel.bindDoubleAngle_360(SLIP_FEATURE_ANGLE_KEY), SLIP_FEATURE_ANGLE_TOOLTIP); + builder.addComponent(RELAX_ITERATIONS_LAYERS_LABEL, layersControlsModel.bindIntegerPositive(N_RELAX_ITER_LAYERS_KEY), RELAX_ITERATIONS_LAYERS_TOOLTIP); + builder.addComponent(RELAXED_ITERATIONS_LABEL, layersControlsModel.bindIntegerPositive(N_RELAXED_ITER_KEY), RELAXED_ITERATIONS_TOOLTIP); + builder.addComponent(SURFACE_NORMALS_SMOOTHING_ITERATIONS_LABEL, layersControlsModel.bindIntegerPositive(N_SMOOTH_SURFACE_NORMALS_KEY), SURFACE_NORMALS_SMOOTHING_ITERATIONS_TOOLTIP); + builder.addComponent(INTERIOR_MESH_SMOOTHING_ITERATIONS_LABEL, layersControlsModel.bindIntegerPositive(N_SMOOTH_NORMALS_KEY), INTERIOR_MESH_SMOOTHING_ITERATIONS_TOOLTIP); + builder.addComponent(SMOOTH_LAYER_THICKNESS_LABEL, layersControlsModel.bindIntegerPositive(N_SMOOTH_THICKNESS_KEY), SMOOTH_LAYER_THICKNESS_TOOLTIP); + builder.addComponent(MAX_FACE_THICKNESS_RATIO_LABEL, layersControlsModel.bindDouble(MAX_FACE_THICKNESS_RATIO_KEY), MAX_FACE_THICKNESS_RATIO_TOOLTIP); + builder.addComponent(MAX_THICKNESS_TO_MEDIAL_RATIO_LABEL, layersControlsModel.bindDouble(MAX_THICKNESS_TO_MEDIAL_RATIO_KEY), MAX_THICKNESS_TO_MEDIAL_RATIO_TOOLTIP); + builder.addComponent(MIN_MEDIAL_AXIS_ANGLE_LABEL, layersControlsModel.bindIntegerAngle_360(MIN_MEDIAL_AXIS_ANGLE_KEY), MIN_MEDIAL_AXIS_ANGLE_TOOLTIP); + builder.addComponent(NUMBER_OF_BUFFER_CELLS_LABEL, layersControlsModel.bindIntegerPositive(N_BUFFER_CELLS_NO_EXTRUDE_KEY), NUMBER_OF_BUFFER_CELLS_TOOLTIP); + builder.addComponent(LAYER_ADDITION_ITERATIONS_LABEL, layersControlsModel.bindIntegerPositive(N_LAYER_ITER_KEY), LAYER_ADDITION_ITERATIONS_TOOLTIP); + builder.addComponent(NUMBER_OF_LAYERS_NOT_GROWN_LABEL, layersControlsModel.bindIntegerPositive(N_GROW_KEY), NUMBER_OF_LAYERS_NOT_GROWN_TOOLTIP); + return builder.getPanel(); + } + + @Override + protected JPanel createSnappingPanel() { + PanelBuilder builder = new PanelBuilder("options.snapping.panel"); + builder.addComponent(SOLVER_ITERATIONS_LABEL, snapControlsModel.bindIntegerPositive(N_SOLVER_ITER_KEY), SOLVER_ITERATIONS_TOOLTIP); + builder.addComponent(SMOOTH_PATCH_LABEL, snapControlsModel.bindIntegerPositive(N_SMOOTH_PATCH_KEY), SMOOTH_PATCH_TOOLTIP); + builder.addComponent(TOLERANCE_LABEL, snapControlsModel.bindDoublePositive(TOLERANCE_KEY), TOLERANCE_TOOLTIP); + builder.addComponent(RELAX_ITERATIONS_SNAP_LABEL, snapControlsModel.bindIntegerPositive(N_RELAX_ITER_SNAP_KEY), RELAX_ITERATIONS_SNAP_TOOLTIP); + builder.addComponent(SNAP_FEATURE_ITERATIONS_LABEL, snapControlsModel.bindIntegerPositive(N_FEATURE_SNAP_ITER_KEY), SNAP_FEATURE_ITERATIONS_TOOLTIP); + builder.addComponent(IMPLICIT_SNAP_FEATURE_LABEL, snapControlsModel.bindBoolean(IMPLICIT_FEATURE_SNAP_KEY), IMPLICIT_SNAP_FEATURE_TOOLTIP); + builder.addComponent(EXPLICIT_SNAP_FEATURE_LABEL, snapControlsModel.bindBoolean(EXPLICIT_FEATURE_SNAP_KEY), EXPLICIT_SNAP_FEATURE_TOOLTIP); + builder.addComponent(MULTI_REGION_FEATURE_LABEL, snapControlsModel.bindBoolean(MULTI_REGION_FEATURE_SNAP_KEY), MULTI_REGION_FEATURE_TOOLTIP); + return builder.getPanel(); + } + + @Override + public void load() { + SnappyHexMeshDict snappyDict = getSnappyDict(); + if (snappyDict != null) { + loadCastellated(snappyDict); + loadLayers(snappyDict); + loadQuality(snappyDict); + loadSnap(snappyDict); + this.snappyHexMeshModel.setDictionary(new SnappyHexMeshDict(snappyDict)); + } + } + + @Override + protected void loadCastellated(SnappyHexMeshDict snappyDict) { + if (snappyDict.found(CASTELLATED_MESH_CONTROLS_KEY)) { + Dictionary castellated = new Dictionary(snappyDict.subDict(CASTELLATED_MESH_CONTROLS_KEY)); + snappyDict.remove(CASTELLATED_MESH_CONTROLS_KEY); + this.castellatedMeshControlsModel.setDictionary(castellated); + } + } + +} diff --git a/src/eu/engys/gui/mesh/panels/lines/AutomaticBaseMeshPanel.java b/src/eu/engys/gui/mesh/panels/lines/AutomaticBaseMeshPanel.java new file mode 100644 index 0000000..b93b5d2 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/lines/AutomaticBaseMeshPanel.java @@ -0,0 +1,84 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels.lines; + +import static eu.engys.util.ui.ComponentsFactory.doubleField; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Geometry; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.RemoveSurfaceEvent; +import eu.engys.util.ui.textfields.DoubleField; + +public class AutomaticBaseMeshPanel { + + public static final String AUTOMATIC_LABEL = "Automatic"; + public static final String BASE_MESHSPACING_LABEL = "Base Mesh Spacing"; + + private DictionaryPanelBuilder builder; + + protected DoubleField meshSpacing; + + private Model model; + + public AutomaticBaseMeshPanel(Model model, DictionaryPanelBuilder builder) { + this.model = model; + this.builder = builder; + + builder.startGroup(AUTOMATIC_LABEL); + layoutComponents(); + builder.endGroup(); + } + + private void layoutComponents() { + meshSpacing = doubleField(1.0); + builder.addComponent(BASE_MESHSPACING_LABEL, meshSpacing); + } + + public void save() { + model.getProject().getSystemFolder().getBlockMeshDict().setFromFile(false); + model.getGeometry().setAutoBoundingBox(true); + model.getGeometry().setCellSize(new double[] { meshSpacing.getDoubleValue(), meshSpacing.getDoubleValue(), meshSpacing.getDoubleValue() }); + model.getGeometry().saveAutoBlock(model); + } + + public void updateBlock() { + if (model.getGeometry().hasBlock()) { + EventManager.triggerEvent(this, new RemoveSurfaceEvent(model.getGeometry().getBlock())); + model.getGeometry().setBlock(Geometry.FAKE_BLOCK); + model.blockChanged(); + } + } + + public void setBaseMeshSpacing(double baseMeshSpacing) { + meshSpacing.setDoubleValue(baseMeshSpacing); + } + + public double getBaseMeshSpacing() { + return meshSpacing.getDoubleValue(); + } + +} diff --git a/src/eu/engys/gui/mesh/panels/lines/BoundingBoxFacesPanel.java b/src/eu/engys/gui/mesh/panels/lines/BoundingBoxFacesPanel.java new file mode 100644 index 0000000..32d3770 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/lines/BoundingBoxFacesPanel.java @@ -0,0 +1,131 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels.lines; + +import static eu.engys.core.project.system.SnappyHexMeshDict.EXPANSION_RATIO_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FCH_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.FINAL_LAYER_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.MAX_LAYER_THICKNESS_KEY; +import static eu.engys.core.project.system.SnappyHexMeshDict.N_SURFACE_LAYERS_KEY; +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.beans.PropertyChangeListener; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.project.geometry.surface.PlaneRegion; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.StringField; + +public class BoundingBoxFacesPanel { + + public static final String NUMBER_OF_LAYERS_LABEL = "Number of Layers"; + public static final String FIRST_CELL_HEIGHT_LABEL = "First Cell Height"; + public static final String LAYER_STRETCHING_LABEL = "Layer Stretching"; + public static final String FINAL_LAYER_THICKNESS_LABEL = "Final Layer Thickness"; + public static final String TOTAL_LAYER_THICKNESS_LABEL = "Total Layer Thickness"; + public static final String FACE_NAME_LABEL = "Face Name"; + public static final String BOUNDING_BOX_FACES_LABEL = "Bounding Box Faces"; + + private PanelBuilder planeBuilder; + private DictionaryModel planeModel; + private StringField planeName; + private PropertyChangeListener listener; + + public BoundingBoxFacesPanel(PropertyChangeListener listener) { + this.listener = listener; + this.planeModel = new DictionaryModel(); + this.planeBuilder = new PanelBuilder(); + layoutComponents(); + addNameListener(); + } + + private void layoutComponents() { + planeModel = new DictionaryModel(); + + planeBuilder = new DictionaryPanelBuilder(); + planeBuilder.addComponent(FACE_NAME_LABEL, planeName = stringField()); + planeBuilder.addComponent(NUMBER_OF_LAYERS_LABEL, planeModel.bindIntegerPositive(N_SURFACE_LAYERS_KEY)); + planeBuilder.addComponent(TOTAL_LAYER_THICKNESS_LABEL, planeModel.bindDouble(MAX_LAYER_THICKNESS_KEY, (Double) null)); + planeBuilder.addComponent(FINAL_LAYER_THICKNESS_LABEL, planeModel.bindDouble(FINAL_LAYER_THICKNESS_KEY, (Double) null)); + planeBuilder.addComponent(LAYER_STRETCHING_LABEL, planeModel.bindDouble(EXPANSION_RATIO_KEY, (Double) null)); + planeBuilder.addComponent(FIRST_CELL_HEIGHT_LABEL, planeModel.bindDouble(FCH_KEY, (Double) null)); + planeBuilder.setEnabled(false); + } + + public JPanel getPanel() { + JPanel panel = planeBuilder.getPanel(); + panel.setBorder(BorderFactory.createTitledBorder(BOUNDING_BOX_FACES_LABEL)); + panel.setName("plane.panel"); + return panel; + } + + public void save(PlaneRegion... planes) { + for (PlaneRegion plane : planes) { + plane.setLayerDictionary(new Dictionary(planeModel.getDictionary())); + } + } + + public void selectPlane(PlaneRegion[] selection) { + setEnabled(true); + + PlaneRegion plane = selection[0]; + planeModel.setDictionary(plane.getLayerDictionary()); + setPlaneName(plane.getName()); + } + + public void setEnabled(boolean enabled) { + planeName.setEnabled(enabled); + planeBuilder.setEnabled(enabled); + } + + public void disableNameField() { + planeName.setEnabled(false); + } + + public void setPlaneName(String name) { + removeNameListener(); + planeName.setValue(name); + addNameListener(); + } + + public String getPlaneName() { + return planeName.getText(); + } + + public void addNameListener() { + planeName.addPropertyChangeListener(listener); + } + + public void removeNameListener() { + planeName.removePropertyChangeListener(listener); + } + +} diff --git a/src/eu/engys/gui/mesh/panels/lines/ColorFeatureLineAction.java b/src/eu/engys/gui/mesh/panels/lines/ColorFeatureLineAction.java new file mode 100644 index 0000000..fef37d4 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/lines/ColorFeatureLineAction.java @@ -0,0 +1,73 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels.lines; + +import java.awt.Color; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JColorChooser; +import javax.swing.SwingUtilities; + +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.ColorSurfaceEvent; +import eu.engys.gui.mesh.panels.FeatureLinesPanel; + +public class ColorFeatureLineAction extends AbstractAction { + + // private static final Icon PICK_ICON = ResourcesUtil.getIcon("color.pick.icon"); + + private Color currentColor = Color.WHITE; + private FeatureLinesPanel linesPanel; + + public ColorFeatureLineAction(FeatureLinesPanel engysLinesPanel) { + // super("", PICK_ICON); + super("Choose"); + this.linesPanel = engysLinesPanel; + } + + @Override + public void actionPerformed(ActionEvent e) { + this.currentColor = JColorChooser.showDialog(SwingUtilities.getWindowAncestor(linesPanel), "Select a color", currentColor); + changeColor(currentColor, (JButton) e.getSource()); + } + + private void changeColor(Color currentColor, JButton sourceButton) { + if (linesPanel.getSelectedLine() != null) { + FeatureLine selectedLine = linesPanel.getSelectedLine(); + selectedLine.setColor(currentColor); + sourceButton.setBackground(currentColor); + EventManager.triggerEvent(this, new ColorSurfaceEvent(selectedLine, currentColor)); + } + } + + public void setCurrentColor(Color currentColor) { + this.currentColor = currentColor; + } + +} diff --git a/src/eu/engys/gui/mesh/panels/lines/FeatureLinesRefinementTable.java b/src/eu/engys/gui/mesh/panels/lines/FeatureLinesRefinementTable.java new file mode 100644 index 0000000..22fee06 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/lines/FeatureLinesRefinementTable.java @@ -0,0 +1,176 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels.lines; + +import java.awt.BorderLayout; +import java.awt.Dialog.ModalityType; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; + +import eu.engys.core.dictionary.model.AbstractTableAdapter; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.FeatureLine.Refinement; +import eu.engys.gui.mesh.panels.AbstractGeometryPanel.Size; +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; + +public class FeatureLinesRefinementTable extends AbstractTableAdapter { + + public static final String REFINEMENTS_LEVELS_KEY = "feature.lines.refinements.levels"; + public static final String LEVEL_LABEL = "Level"; + public static final String DISTANCE_M_LABEL = "Distance [m]"; + public static final String CELL_SIZE_LABEL = "Cell Size [m]"; + + private static final String[] COLUMN_NAMES = { DISTANCE_M_LABEL, LEVEL_LABEL, CELL_SIZE_LABEL}; + + private List refinements; + private Model model; + + public FeatureLinesRefinementTable(Model model, List refinements) { + super(COLUMN_NAMES); + setName(REFINEMENTS_LEVELS_KEY); + this.model = model; + this.refinements = refinements; +// System.out.println("FeatureLinesRefinementTable.FeatureLinesRefinementTable() size: " + refinements.size()); +// fixOldStyleLevels(); + } + + public JButton getButton() { + JButton b = new JButton(new AbstractAction("Edit") { + @Override + public void actionPerformed(ActionEvent e) { + getDialog().setVisible(true); + } + + }); + return b; + } + + private JDialog getDialog() { + final JDialog dialog = new JDialog(UiUtil.getActiveWindow(), "Refinement Level", ModalityType.MODELESS); + dialog.setName("line.adapter.dialog"); + + JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + JButton okButton = new JButton(new AbstractAction("OK") { + @Override + public void actionPerformed(ActionEvent e) { + save(); + dialog.setVisible(false); + } + }); + okButton.setName("OK"); + buttonsPanel.add(okButton); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(new JScrollPane(this), BorderLayout.CENTER); + mainPanel.add(buttonsPanel, BorderLayout.SOUTH); + + dialog.add(mainPanel); + dialog.setSize(600, 400); + dialog.setLocationRelativeTo(null); + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.getRootPane().setDefaultButton(okButton); + return dialog; + } + +// private void fixOldStyleLevels() { +// if (lineDictionary.found(LEVEL)) { +// Dictionary clone = new Dictionary(lineDictionary); +// String levelValue = clone.lookup(LEVEL); +// clone.remove(LEVEL); +// clone.add(LEVELS, "( ( 0.0 " + levelValue + " ) )"); +// this.lineDictionary = clone; +// } +// } + + protected void addRow() { + DoubleField d = ComponentsFactory.doubleField(); + IntegerField i = ComponentsFactory.intField(); + Size s = new Size(model, i); + s.recalculate(); + JTextField[] row = new JTextField[] {d, i, s}; + addRow(row); + } + + @Override + public void load() { + clear(); + for (Refinement ref : refinements) { + + DoubleField d = ComponentsFactory.doubleField(); + d.setDoubleValue(ref.getDistance()); + + IntegerField i = ComponentsFactory.intField(); + i.setIntValue(ref.getLevel()); + + Size s = new Size(model, i); + s.recalculate(); + + JTextField[] row = new JTextField[] {d, i, s}; + addRow(row, false); + } + +// if (getRowsMap().isEmpty()) { +// addRow(); +// } + } + + @Override + protected void save() { + refinements.clear(); + if (getRowsMap().isEmpty()) { + return; + } + + for (Integer index : getRowsMap().keySet()) { + JComponent[] row = getRowsMap().get(index); + int level = ((IntegerField) row[1]).getIntValue(); + double distance = ((DoubleField) row[0]).getDoubleValue(); + + refinements.add(new Refinement(distance, level)); + } + } + + public List getRefinements() { + return refinements; + } + + public void setRefinements(List refinements) { + this.refinements = refinements; + } + +} diff --git a/src/eu/engys/gui/mesh/panels/lines/FromFileBaseMeshPanel.java b/src/eu/engys/gui/mesh/panels/lines/FromFileBaseMeshPanel.java new file mode 100644 index 0000000..8e318ba --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/lines/FromFileBaseMeshPanel.java @@ -0,0 +1,192 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels.lines; + +import java.awt.HeadlessException; +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.IOException; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.SwingUtilities; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.Controller; +import eu.engys.core.dictionary.FileEditor; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Geometry; +import eu.engys.core.project.system.BlockMeshDict; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.RemoveSurfaceEvent; +import eu.engys.gui.mesh.actions.RunBlockMeshAction; +import eu.engys.util.LineSeparator; +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.ResourcesUtil; + +public class FromFileBaseMeshPanel { + + private static final Logger logger = LoggerFactory.getLogger(FromFileBaseMeshPanel.class); + + public static final HelyxFileFilter BLOCKMESHDICT_FILE_FILTER = new HelyxFileFilter("Block Mesh Dictionary", BlockMeshDict.BLOCK_DICT); + + public static final String FROM_FILE_LABEL = "From File"; + + public static final String EDIT_LABEL = "Edit"; + public static final String IMPORT_LABEL = "Import"; + public static final String CREATE_LABEL = "Create"; + + private Model model; + private Controller controller; + private DictionaryPanelBuilder builder; + private JButton editButton, previewButton, importButton; + + public FromFileBaseMeshPanel(Model model, Controller controller, DictionaryPanelBuilder builder) { + this.model = model; + this.controller = controller; + this.builder = builder; + builder.startGroup(FROM_FILE_LABEL); + layoutComponents(); + builder.endGroup(); + } + + private void layoutComponents() { + previewButton = new JButton(new RunBlockMeshAction(model, controller)); + previewButton.setName(CREATE_LABEL); + + editButton = new JButton(new AbstractAction(EDIT_LABEL, ResourcesUtil.getIcon("mesh.create.edit.icon")) { + @Override + public void actionPerformed(ActionEvent e) { + try { + showEditor(); + } catch (IOException ex) { + logger.error("Unable to open blockMeshDict editor", ex.getMessage()); + } + } + }); + editButton.setName(EDIT_LABEL); + + importButton = new JButton(new AbstractAction(IMPORT_LABEL, ResourcesUtil.getIcon("mesh.import.icon")) { + @Override + public void actionPerformed(ActionEvent e) { + HelyxFileChooser fc = createFileChooser(); + fc.showOpenDialog(); + } + }); + importButton.setName(IMPORT_LABEL); + builder.addSeparator(""); + builder.addComponent(importButton, editButton, previewButton); + } + + public void save(){ + model.getProject().getSystemFolder().getBlockMeshDict().setFromFile(true); + model.getGeometry().setAutoBoundingBox(false); + } + + public void updateBlock(){ + if (model.getGeometry().hasBlock()) { + EventManager.triggerEvent(this, new RemoveSurfaceEvent(model.getGeometry().getBlock())); + model.getGeometry().setBlock(Geometry.FAKE_BLOCK); + model.blockChanged(); + } + } + + private HelyxFileChooser createFileChooser() { + String initialPath = PrefUtil.getWorkDir(PrefUtil.LAST_IMPORT_DIR).getAbsolutePath(); + HelyxFileChooser chooser = new HelyxFileChooser(initialPath) { + @Override + public ReturnValue showOpenDialog() throws HeadlessException { + ReturnValue retVal = super.showOpenDialog(BLOCKMESHDICT_FILE_FILTER); + if (retVal.isApprove()) { + File newBlockDictFile = getSelectedFile(); + PrefUtil.putFile(PrefUtil.LAST_IMPORT_DIR, newBlockDictFile.getParentFile()); + try { + importBlockMeshDict(newBlockDictFile); + } catch (IOException e) { + logger.error("Error importing blockMeshDict from file" + e.getMessage()); + } + } + return retVal; + } + + }; + chooser.setSelectionMode(SelectionMode.FILES_ONLY); + chooser.setTitle("Select " + BlockMeshDict.BLOCK_DICT + " File"); + chooser.setParent(SwingUtilities.getWindowAncestor(builder.getPanel())); + return chooser; + } + + private void importBlockMeshDict(File toImportBlockMeshDict) throws IOException { + List newBlockMeshDictContent = FileUtils.readLines(toImportBlockMeshDict); + File currentBlockMeshDict = new File(model.getProject().getSystemFolder().getFileManager().getFile(), BlockMeshDict.BLOCK_DICT); + newBlockMeshDictContent.add(BlockMeshDict.FROM_FILE_LINE); + + String lineEnding = Util.isWindowsScriptStyle() ? LineSeparator.DOS.getSeparator() : LineSeparator.UNIX.getSeparator(); + FileUtils.writeLines(currentBlockMeshDict, null, newBlockMeshDictContent, lineEnding); + + showEditor(); + } + + private void showEditor() throws IOException { + final File blockMeshDictFile = new File(model.getProject().getSystemFolder().getFileManager().getFile(), BlockMeshDict.BLOCK_DICT); + final List lines = FileUtils.readLines(blockMeshDictFile); + + Runnable onShowRunnable = new Runnable() { + @Override + public void run() { + importButton.setEnabled(false); + editButton.setEnabled(false); + previewButton.setEnabled(false); + } + }; + Runnable onDisposeRunnable = new Runnable() { + @Override + public void run() { + importButton.setEnabled(true); + editButton.setEnabled(true); + previewButton.setEnabled(true); + try { + String lineEnding = Util.isWindowsScriptStyle() ? LineSeparator.DOS.getSeparator() : LineSeparator.UNIX.getSeparator(); + FileUtils.writeLines(blockMeshDictFile, null, lines, lineEnding); + } catch (IOException e) { + logger.error("Error saving blockMeshDict" + e.getMessage()); + } + } + }; + + FileEditor.getInstance().show(SwingUtilities.getWindowAncestor(builder.getPanel()), lines, BlockMeshDict.BLOCK_DICT, onShowRunnable, onDisposeRunnable, null); + } + +} diff --git a/src/eu/engys/gui/mesh/panels/lines/ImportFeatureLineAction.java b/src/eu/engys/gui/mesh/panels/lines/ImportFeatureLineAction.java new file mode 100644 index 0000000..6fa7158 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/lines/ImportFeatureLineAction.java @@ -0,0 +1,117 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels.lines; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.io.File; + +import javax.swing.AbstractAction; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.AddSurfaceEvent; +import eu.engys.util.ColorUtil; +import eu.engys.util.PrefUtil; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.ExecUtil; + +public class ImportFeatureLineAction extends AbstractAction { + + private static final Logger logger = LoggerFactory.getLogger(ImportFeatureLineAction.class); + + public static final String FROM_FILE_LABEL = "Open"; + private Model model; + + public ImportFeatureLineAction(Model model) { + super(FROM_FILE_LABEL); + this.model = model; + } + + @Override + public void actionPerformed(ActionEvent e) { + HelyxFileChooser fc = getFeatureLinesFileChooser(); + HelyxFileFilter filter = new HelyxFileFilter("EMesh File (*.eMesh, *.eMesh.gz)", "eMesh", "eMesh.gz"); + fc.setSelectionMode(SelectionMode.FILES_ONLY); + fc.setMultiSelectionEnabled(true); + + ReturnValue returnedValue = fc.showOpenDialog(filter); + + if (returnedValue.isApprove()) { + importFiles(fc.getSelectedFiles()); + } + } + + private HelyxFileChooser getFeatureLinesFileChooser() { + File lastDir = PrefUtil.getWorkDir(PrefUtil.LAST_IMPORT_DIR); + HelyxFileChooser fc = new HelyxFileChooser(lastDir.getAbsolutePath()); + fc.setMultiSelectionEnabled(true); + fc.setSelectionMode(SelectionMode.FILES_ONLY); + return fc; + } + + private void importFiles(File[] files) { + if (files != null && files.length > 0) { + PrefUtil.putFile(PrefUtil.LAST_IMPORT_DIR, files[0].getParentFile()); + + for (File file : files) { + importFile(file); + } + } + } + + public void importFile(final File file) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + // if (!alreadyImported(file)) { + FeatureLine line = model.getGeometry().getFactory().readLine(file); + addLine(line); + // } + } + }); + } + + public void addLine(FeatureLine line) { + logger.debug("ADD LINE " + line); + line.setColor(nextColor()); + model.getGeometry().addLine(line); + model.geometryChanged(line); + + EventManager.triggerEvent(this, new AddSurfaceEvent(line)); + } + + private Color nextColor() { + return ColorUtil.getColor(model.getGeometry().getLines().size()); + } +} diff --git a/src/eu/engys/gui/mesh/panels/lines/UserDefinedBaseMeshPanel.java b/src/eu/engys/gui/mesh/panels/lines/UserDefinedBaseMeshPanel.java new file mode 100644 index 0000000..a0544b1 --- /dev/null +++ b/src/eu/engys/gui/mesh/panels/lines/UserDefinedBaseMeshPanel.java @@ -0,0 +1,240 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.mesh.panels.lines; + +import static eu.engys.core.project.geometry.Surface.MAX_KEY; +import static eu.engys.core.project.geometry.Surface.MIN_KEY; +import static eu.engys.core.project.system.BlockMeshDict.ELEMENTS_KEY; +import static eu.engys.util.ui.ComponentsFactory.doublePointField; +import static eu.engys.util.ui.ComponentsFactory.labelField; + +import java.awt.Dimension; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JToggleButton; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FieldChangeListener; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.dictionary.model.DictionaryPanelBuilder; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.core.project.geometry.surface.MultiPlane; +import eu.engys.core.project.system.SystemFolder; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.ChangeSurfaceEvent; +import eu.engys.gui.view3D.BoxEventButton; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; + +public class UserDefinedBaseMeshPanel { + + public static final String USER_DEFINED_LABEL = "User Defined"; + + public static final String CELL_SIZE_LABEL = "Cell Size [m]"; + public static final String N_ELEMENTS_LABEL = "Elements"; + public static final String MAX_LABEL = "Max"; + public static final String MIN_LABEL = "Min"; + + private final static Icon FIT_ICON = ResourcesUtil.getIcon("fit.boundingbox.icon"); + + private DictionaryPanelBuilder builder; + + private DoubleField[] boxMin; + private DoubleField[] boxMax; + private DoubleField[] cellSize; + private JToggleButton showBoxButton; + + private Model model; + + private DictionaryModel minMaxModel; + private UpdateBlockListener blockListener; + + public UserDefinedBaseMeshPanel(Model model, DictionaryPanelBuilder builder) { + this.model = model; + this.builder = builder; + + minMaxModel = new DictionaryModel(new Dictionary(defaultBoxModelDict)); + builder.startDictionary(USER_DEFINED_LABEL, minMaxModel); + layoutComponents(); + builder.endDictionary(); + } + + private void layoutComponents() { + blockListener = new UpdateBlockListener(); + + boxMin = minMaxModel.bindPoint(MIN_KEY, 4, blockListener); + boxMax = minMaxModel.bindPoint(MAX_KEY, 4, blockListener); + showBoxButton = new BoxEventButton(boxMin, boxMax); + + builder.addComponent("", labelField("X"), labelField("Y"), labelField("Z")); + builder.addComponent(MIN_LABEL, boxMin[0], boxMin[1], boxMin[2], showBoxButton); + builder.addComponentAndSpan(MAX_LABEL, boxMax); + + IntegerField[] elements = minMaxModel.bindIntegerArray(ELEMENTS_KEY, 3, blockListener); + JButton fitButton = new JButton(new FitBoundingBoxAction()); + fitButton.setPreferredSize(new Dimension(36, 48)); + + builder.addComponent(N_ELEMENTS_LABEL, elements[0], elements[1], elements[2], fitButton); + cellSize = doublePointField(3); + cellSize[0].setEnabled(false); + cellSize[1].setEnabled(false); + cellSize[2].setEnabled(false); + builder.addComponentAndSpan(CELL_SIZE_LABEL, cellSize); + } + + public void load() { + blockListener.setAdjusting(true); + + MultiPlane block = model.getGeometry().getBlock(); + minMaxModel.setDictionary(block.getGeometryDictionary()); + updateDelta(); + + blockListener.setAdjusting(false); + } + + public void save() { + model.getProject().getSystemFolder().getBlockMeshDict().setFromFile(false); + model.getGeometry().setAutoBoundingBox(false); + model.getGeometry().setCellSize(new double[] { cellSize[0].getDoubleValue(), cellSize[1].getDoubleValue(), cellSize[2].getDoubleValue() }); + model.getGeometry().saveUserDefinedBlock(model, minMaxModel.getDictionary()); + } + + public void updateBlock() { + if (model.getGeometry().hasBlock()) { + editBlock(); + } else { + addBlock(); + } + updateDelta(); + save(); + } + + private void editBlock() { + MultiPlane block = model.getGeometry().getBlock(); + block.setGeometryDictionary(minMaxModel.getDictionary()); + + EventManager.triggerEvent(this, new ChangeSurfaceEvent(block, false)); + } + + private void addBlock() { + SystemFolder systemFolder = model.getProject().getSystemFolder(); + model.getGeometry().loadBlock(systemFolder.getBlockMeshDict(), systemFolder.getSnappyHexMeshDict()); + model.blockChanged(); + minMaxModel.setDictionary(model.getGeometry().getBlock().getGeometryDictionary()); + EventManager.triggerEvent(this, new ChangeSurfaceEvent(model.getGeometry().getBlock(), true)); + } + + private void updateDelta() { + double[] d = model.getGeometry().getBlock().getDelta(); + for (int i = 0; i < d.length; i++) { + cellSize[i].setDoubleValue(d[i]); + } + } + + public void turnOffShowBoxButton() { + if (showBoxButton.isSelected()) { + showBoxButton.doClick(); + } + } + + public void resetToDefault() { + minMaxModel.setDictionary(new Dictionary(defaultBoxModelDict)); + } + + private Dictionary defaultBoxModelDict = new Dictionary("block") { + { + add(MIN_KEY, new String[] { "-1.0", "-1.0", "-1.0" }); + add(MAX_KEY, new String[] { "1.0", "1.0", "1.0" }); + add("patch0", "ffminx"); + add("patch1", "ffminx"); + add("patch2", "ffminx"); + add("patch3", "ffmaxx"); + add("patch4", "ffminz"); + add("patch5", "ffmaxz"); + add(ELEMENTS_KEY, new String[] { "10", "10", "10" }); + } + }; + + private class UpdateBlockListener implements FieldChangeListener { + + boolean adjusting = false; + + @Override + public void actionPerformed(ActionEvent e) { + } + + @Override + public void setAdjusting(boolean b) { + this.adjusting = b; + } + + @Override + public boolean isAdjusting() { + return adjusting; + } + + @Override + public void fieldChanged() { + if (!isAdjusting()) { + updateBlock(); + } + } + } + + private class FitBoundingBoxAction extends AbstractAction { + + public FitBoundingBoxAction() { + super("", FIT_ICON); + putValue(SHORT_DESCRIPTION, "Fit Bounding Box"); + } + + @Override + public void actionPerformed(ActionEvent e) { + BoundingBox bb = model.getGeometry().computeBoundingBox(); + + blockListener.setAdjusting(true); + + boxMin[0].setDoubleValue(bb.getXmin()); + boxMin[1].setDoubleValue(bb.getYmin()); + boxMin[2].setDoubleValue(bb.getZmin()); + + boxMax[0].setDoubleValue(bb.getXmax()); + boxMax[1].setDoubleValue(bb.getYmax()); + boxMax[2].setDoubleValue(bb.getZmax()); + + blockListener.setAdjusting(false); + + updateBlock(); + } + + } + +} diff --git a/src/eu/engys/gui/solver/DefaultRunOptionsPanel.java b/src/eu/engys/gui/solver/DefaultRunOptionsPanel.java new file mode 100644 index 0000000..4f0fae9 --- /dev/null +++ b/src/eu/engys/gui/solver/DefaultRunOptionsPanel.java @@ -0,0 +1,168 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver; + +import static eu.engys.util.ui.ComponentsFactory.labelField; +import static eu.engys.util.ui.ComponentsFactory.stringField; + +import java.awt.Dimension; +import java.io.File; +import java.nio.file.Paths; + +import javax.inject.Inject; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import net.java.dev.designgridlayout.Componentizer; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.StringField; + +public class DefaultRunOptionsPanel extends DefaultGUIPanel { + + private static final String RUN = "Run Options"; + public static final String SOLVER_LABEL = "Solver"; + public static final String LOG_FILE_LABEL = "Log File"; + public static final String PROPERTIES_LABEL = "Properties"; + + private JLabel solverName; + // private IntegerField nProcessors; + // private JCheckBox parallel; + private StringField log; + + @Inject + public DefaultRunOptionsPanel(Model model) { + super(RUN, model); + } + + protected JComponent layoutComponents() { + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(getActionsPanel()); + builder.addComponent(getPropertiesPanel()); + builder.addComponent(getServerPanel()); + builder.addComponent(getQueuePanel()); + return builder.removeMargins().getPanel(); + } + + protected JComponent getServerPanel() { + return new JPanel(); + } + + protected JComponent getQueuePanel() { + return new JPanel(); + } + + protected JComponent getPropertiesPanel() { + PanelBuilder properties = new PanelBuilder(); + properties.getPanel().setBorder(BorderFactory.createTitledBorder(PROPERTIES_LABEL)); + properties.addComponent(SOLVER_LABEL, solverName); + // properties.addComponent("Parallel Run", parallel); + // properties.addComponent("Number Of Processors", nProcessors); + properties.addComponent(LOG_FILE_LABEL, log); + return properties.getPanel(); + } + + protected JComponent getActionsPanel() { + solverName = labelField(""); + // parallel = checkField(); + // nProcessors = intField(); + log = stringField(); + + solverName.setEnabled(false); + // parallel.setEnabled(false); + // nProcessors.setEnabled(false); + + PanelBuilder actions = new PanelBuilder(); + actions.getPanel().setBorder(BorderFactory.createTitledBorder("Actions")); + + Action runSolverAction = ActionManager.getInstance().get("solver.run"); + Action editRunSolverAction = ActionManager.getInstance().get("solver.run.edit"); + + JButton runSolverButton = new JButton(runSolverAction); + JButton editRunSolverButton = new JButton(editRunSolverAction); + + runSolverButton.setPreferredSize(new Dimension(120, runSolverButton.getPreferredSize().height)); + + JComponent c1 = Componentizer.create().minToPref(runSolverButton).fixedPref(editRunSolverButton).minAndMore(new JLabel()).component(); + actions.addComponent(c1); + + JComponent[] cs = getExtraButtons(); + for (JComponent c : cs) { + actions.addComponent(c); + } + return actions.getPanel(); + } + + protected JComponent[] getExtraButtons() { + return new JComponent[0]; + } + + @Override + public void load() { + if (model.getSolverModel().getLogFile() != null) { + File logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), "log", model.getSolverModel().getLogFile()).toFile(); + if (logFile == null || !logFile.exists() || !logFile.isFile()) { + setDefaultLogName(); + } else { + log.setText(logFile.getName()); + solverName.setText(model.getState().getSolver().getName()); + } + } else { + setDefaultLogName(); + } + // parallel.setSelected(model.getProject().isParallel()); + // nProcessors.setValue(model.getProject().getProcessors()); + } + + @Override + public void save() { + super.save(); + model.getSolverModel().setLogFile(log.getText()); + } + + @Override + public void stateChanged() { + setDefaultLogName(); + } + + @Override + public void solverChanged() { + setDefaultLogName(); + } + + public void setDefaultLogName() { + String application = model.getState().getSolver().getName(); + solverName.setText(application); + log.setText(application + ".log"); + } + +} diff --git a/src/eu/engys/gui/solver/ReloadOnFinish.java b/src/eu/engys/gui/solver/ReloadOnFinish.java new file mode 100644 index 0000000..3ae8610 --- /dev/null +++ b/src/eu/engys/gui/solver/ReloadOnFinish.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver; + +import eu.engys.core.controller.Command; +import eu.engys.core.controller.Controller; +import eu.engys.core.project.state.ServerState; +import eu.engys.gui.solver.postprocessing.ServerListener; + +public class ReloadOnFinish implements ServerListener { + + private Controller controller; + + public ReloadOnFinish(Controller controller) { + this.controller = controller; + } + + @Override + public void serverChanged(ServerState serverState) { + if (serverState.getCommand().equals(Command.RUN_CASE) || serverState.getCommand().equals(Command.RUN_ALL)) { + if (serverState.getSolverState().isFinished() || serverState.getSolverState().isError()) { + if (controller.getListener() != null) { + controller.getListener().afterRunCase(); + } + } + } + } +} diff --git a/src/eu/engys/gui/solver/ReopenOnInitialised.java b/src/eu/engys/gui/solver/ReopenOnInitialised.java new file mode 100644 index 0000000..6565ef3 --- /dev/null +++ b/src/eu/engys/gui/solver/ReopenOnInitialised.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver; + +import eu.engys.core.controller.Command; +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.Controller.OpenOptions; +import eu.engys.core.project.state.ServerState; +import eu.engys.gui.solver.postprocessing.ServerListener; + +public class ReopenOnInitialised implements ServerListener { + + private Controller controller; + + public ReopenOnInitialised(Controller controller) { + this.controller = controller; + } + + @Override + public void serverChanged(ServerState serverState) { + if (serverState.getCommand().equals(Command.INITIALISE_FIELDS)) { + if (serverState.getSolverState().isInitialised()) { + if (controller.getListener() != null) { + controller.reopenCase(OpenOptions.MESH_ONLY); + } + } + } + } + +} diff --git a/src/eu/engys/gui/solver/ReopenOnMeshed.java b/src/eu/engys/gui/solver/ReopenOnMeshed.java new file mode 100644 index 0000000..04199e0 --- /dev/null +++ b/src/eu/engys/gui/solver/ReopenOnMeshed.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver; + +import eu.engys.core.controller.Command; +import eu.engys.core.controller.Controller; +import eu.engys.core.controller.Controller.OpenOptions; +import eu.engys.core.project.state.ServerState; +import eu.engys.gui.solver.postprocessing.ServerListener; + +public class ReopenOnMeshed implements ServerListener { + + private Controller controller; + + public ReopenOnMeshed(Controller controller) { + this.controller = controller; + } + + @Override + public void serverChanged(ServerState serverState) { + if (serverState.getCommand().equals(Command.CREATE_MESH)) { + if (serverState.getSolverState().isMeshed()) { + if (controller.getListener() != null) { + controller.reopenCase(OpenOptions.MESH_ONLY); + } + } + } + } + +} diff --git a/src/eu/engys/gui/solver/Solver.java b/src/eu/engys/gui/solver/Solver.java new file mode 100644 index 0000000..fe1cdcf --- /dev/null +++ b/src/eu/engys/gui/solver/Solver.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.solver; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import com.google.inject.BindingAnnotation; + +@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME) +public @interface Solver { + +} diff --git a/src/eu/engys/gui/solver/Solver3DElement.java b/src/eu/engys/gui/solver/Solver3DElement.java new file mode 100644 index 0000000..1c29c4c --- /dev/null +++ b/src/eu/engys/gui/solver/Solver3DElement.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.solver; + +import java.util.Set; + +import javax.inject.Inject; + +import eu.engys.gui.GUIPanel; +import eu.engys.gui.view.AbstractView3DElement; +import eu.engys.gui.view3D.CanvasPanel; + +public class Solver3DElement extends AbstractView3DElement { + + @Inject + public Solver3DElement(@Solver Set panels) { + super(panels); + } + +// @Override +// public void start(CanvasPanel view3D) { +// view3D.applyContext(CaseSetup3DElement.class); +// } +// +// @Override +// public void save(CanvasPanel view3d) { +// view3d.dumpContext(CaseSetup3DElement.class); +// } + + @Override + public void load(CanvasPanel view3D) { + view3D.getMeshController().newContext(getClass()); + view3D.getGeometryController().newEmptyContext(getClass()); + } + +} diff --git a/src/eu/engys/gui/solver/SolverElement.java b/src/eu/engys/gui/solver/SolverElement.java new file mode 100644 index 0000000..170f83d --- /dev/null +++ b/src/eu/engys/gui/solver/SolverElement.java @@ -0,0 +1,114 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver; + +import java.util.Observable; +import java.util.Observer; +import java.util.Set; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.Model; +import eu.engys.core.project.ProjectReader; +import eu.engys.core.project.ProjectWriter; +import eu.engys.gui.Actions; +import eu.engys.gui.GUIPanel; +import eu.engys.gui.view.AbstractViewElement; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view.ViewElementPanel; +import eu.engys.util.plaf.ILookAndFeel; + +public class SolverElement extends AbstractViewElement { + + private static final Logger logger = LoggerFactory.getLogger(SolverElement.class); + + private ViewElementPanel viewElementPanel; + private Model model; + + private Observer solverModelObserver; + + @Inject + public SolverElement(Model model, @Solver String title, @Solver Set panels, Set modules, @Solver View3DElement view3DElement, @Solver Actions actions, ILookAndFeel lookAndFeel) { + super(title, panels, modules, view3DElement, actions, lookAndFeel); + this.model = model; + } + + @Override + public void layoutComponents() { + viewElementPanel = new ViewElementPanel(this); + solverModelObserver = new Observer() { + @Override + public void update(Observable o, Object arg) { + //arg is null, see SolverModel.setState +// logger.debug("Observerd a change"); + actions.update(); + } + }; + super.layoutComponents(); + } + + @Override + public int getPreferredWidth() { + return 800; + } + + @Override + public ViewElementPanel getPanel() { + return viewElementPanel; + } + + @Override + public void start() { + super.start(); + model.getSolverModel().addObserver(solverModelObserver); + } + + @Override + public void stop() { + super.stop(); + model.getSolverModel().deleteObserver(solverModelObserver); + } + + @Override + public void load(Model model) { + super.load(model); + } + + @Override + public ProjectReader getReader() { + return null; + } + + @Override + public ProjectWriter getWriter() { + return null; + } + +} diff --git a/src/eu/engys/gui/solver/SolverRuntimeControlsPanel.java b/src/eu/engys/gui/solver/SolverRuntimeControlsPanel.java new file mode 100644 index 0000000..4ca6b13 --- /dev/null +++ b/src/eu/engys/gui/solver/SolverRuntimeControlsPanel.java @@ -0,0 +1,373 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver; + +import static eu.engys.core.project.system.ControlDict.ADJUSTABLE_RUN_TIME_KEY; +import static eu.engys.core.project.system.ControlDict.ADJUST_TIME_STEP_KEY; +import static eu.engys.core.project.system.ControlDict.DELTA_T_KEY; +import static eu.engys.core.project.system.ControlDict.END_TIME_KEY; +import static eu.engys.core.project.system.ControlDict.FUNCTIONS_KEY; +import static eu.engys.core.project.system.ControlDict.GRAPH_FORMAT_KEY; +import static eu.engys.core.project.system.ControlDict.GRAPH_FORMAT_VALUE; +import static eu.engys.core.project.system.ControlDict.MAX_ALPHA_CO_KEY; +import static eu.engys.core.project.system.ControlDict.MAX_CO_KEY; +import static eu.engys.core.project.system.ControlDict.MAX_DELTA_T_KEY; +import static eu.engys.core.project.system.ControlDict.PURGE_WRITE_KEY; +import static eu.engys.core.project.system.ControlDict.RUN_TIME_VALUE; +import static eu.engys.core.project.system.ControlDict.START_FROM_KEY; +import static eu.engys.core.project.system.ControlDict.START_FROM_VALUES; +import static eu.engys.core.project.system.ControlDict.START_TIME_KEY; +import static eu.engys.core.project.system.ControlDict.START_TIME_VALUE; +import static eu.engys.core.project.system.ControlDict.STOP_AT_KEY; +import static eu.engys.core.project.system.ControlDict.TIME_FORMAT_KEY; +import static eu.engys.core.project.system.ControlDict.TIME_FORMAT_VALUES; +import static eu.engys.core.project.system.ControlDict.TIME_PRECISION_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_COMPRESSION_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_COMPRESSION_VALUES; +import static eu.engys.core.project.system.ControlDict.WRITE_CONTROL_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_CONTROL_VALUES; +import static eu.engys.core.project.system.ControlDict.WRITE_FORMAT_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_FORMAT_VALUES; +import static eu.engys.core.project.system.ControlDict.WRITE_INTERVAL_KEY; +import static eu.engys.core.project.system.ControlDict.WRITE_PRECISION_KEY; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.ADJUSTABLE_TIME_STEP_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.DATA_WRITING_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.DELTA_T_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.END_TIME_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.GRAPH_FORMAT_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.GRAPH_FORMAT_LABELS; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.MAX_COURANT_ALPHA_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.MAX_COURANT_NUMBER_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.MAX_TIME_STEP_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.PURGE_WRITE_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.RUNTIME_CONTROLS; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.START_FROM_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.START_FROM_LABELS; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.TIME_FORMAT_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.TIME_FORMAT_LABELS; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.TIME_PRECISION_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.TIME_SETTINGS_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.WRITE_COMPRESSION_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.WRITE_COMPRESSION_LABELS; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.WRITE_CONTROL_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.WRITE_CONTROL_LABELS; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.WRITE_FORMAT_LABEL; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.WRITE_FORMAT_LABELS; +import static eu.engys.gui.casesetup.RuntimeControlsPanel.WRITE_PRECISION_LABEL; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JPanel; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.Time; +import eu.engys.core.project.system.ControlDict; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.util.progress.SilentMonitor; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.SelectionValueConfigurator; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.DoubleField; + +public class SolverRuntimeControlsPanel extends DefaultGUIPanel { + + private static final ImageIcon APPLY_ICON = new ImageIcon(SolverRuntimeControlsPanel.class.getClassLoader().getResource("eu/engys/resources/images/tick16.png")); + + private DictionaryModel dictionaryModel; + private JCheckBox adjustableTime; + private JComponent maxCourantNumber; + private JComponent maxAlphaCourant; + private JComponent maxTimeStep; + private DoubleField deltaT; + private Time time = null; + + private JComboBox startFrom; + private DoubleField startTime; + private PropertyChangeListener startFromListener; + + private boolean isSaving = false; + + private ActionListener adjustableTimeListener; + + @Inject + public SolverRuntimeControlsPanel(Model model) { + super(RUNTIME_CONTROLS, model); + } + + @Override + public String getName() { + return "Solver " + RUNTIME_CONTROLS; + } + + @Override + public void start() { + super.start(); + if (model.getSolverModel().getServerState().getSolverState().isRunning()) { + fixGUI(); + UiUtil.enable(this); + } else { + UiUtil.disable(this); + } + } + + protected JComponent layoutComponents() { + dictionaryModel = new DictionaryModel(new Dictionary("")); + PanelBuilder timeBuilder = new PanelBuilder(); + + startFrom = dictionaryModel.bindSelection(START_FROM_KEY, START_FROM_VALUES, START_FROM_LABELS); + startTime = dictionaryModel.bindDouble(START_TIME_KEY); + DoubleField endTime = dictionaryModel.bindDouble(END_TIME_KEY); + + timeBuilder.addComponent(START_FROM_LABEL, startFrom, startTime); + timeBuilder.addComponent(END_TIME_LABEL, endTime); + + startTime.setEnabled(false); + startFromListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + startTime.setEnabled(START_TIME_VALUE.equals(evt.getNewValue())); + } + }; + startFrom.addPropertyChangeListener("value", startFromListener); + + timeBuilder.addComponent(DELTA_T_LABEL, deltaT = dictionaryModel.bindDouble(DELTA_T_KEY)); + + timeBuilder.addComponent(ADJUSTABLE_TIME_STEP_LABEL, adjustableTime = dictionaryModel.bindBoolean(ADJUST_TIME_STEP_KEY)); + timeBuilder.addComponent(MAX_COURANT_NUMBER_LABEL, maxCourantNumber = dictionaryModel.bindDouble(MAX_CO_KEY)); + timeBuilder.addComponent(MAX_COURANT_ALPHA_LABEL, maxAlphaCourant = dictionaryModel.bindDouble(MAX_ALPHA_CO_KEY)); + timeBuilder.addComponent(MAX_TIME_STEP_LABEL, maxTimeStep = dictionaryModel.bindDouble(MAX_DELTA_T_KEY)); + + adjustableTimeListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + maxCourantNumber.setEnabled(adjustableTime.isSelected()); + maxAlphaCourant.setEnabled(adjustableTime.isSelected() && model.getState().getMultiphaseModel().isMultiphase()); + maxTimeStep.setEnabled(adjustableTime.isSelected()); + } + }; + adjustableTime.setSelected(false); + adjustableTime.addActionListener(adjustableTimeListener); + + maxCourantNumber.setEnabled(false); + maxAlphaCourant.setEnabled(false); + maxTimeStep.setEnabled(false); + + PanelBuilder dataWriteBuilder = new PanelBuilder(); + SelectionValueConfigurator conf = new SelectionValueConfigurator() { + @Override + public String write(String value) { + if (value != null && value.equals(RUN_TIME_VALUE) && adjustableTime.isSelected()) + return ADJUSTABLE_RUN_TIME_KEY; + return value; + } + + @Override + public String read(String value) { + if (value != null && value.equals(ADJUSTABLE_RUN_TIME_KEY)) + return RUN_TIME_VALUE; + return value; + } + }; + dataWriteBuilder.addComponent(WRITE_CONTROL_LABEL, dictionaryModel.bindSelection(WRITE_CONTROL_KEY, WRITE_CONTROL_VALUES, WRITE_CONTROL_LABELS, conf), dictionaryModel.bindDouble(WRITE_INTERVAL_KEY)); + dataWriteBuilder.addComponent(PURGE_WRITE_LABEL, dictionaryModel.bindIntegerPositive(PURGE_WRITE_KEY)); + dataWriteBuilder.addComponent(WRITE_FORMAT_LABEL, dictionaryModel.bindSelection(WRITE_FORMAT_KEY, WRITE_FORMAT_VALUES, WRITE_FORMAT_LABELS)); + dataWriteBuilder.addComponent(WRITE_PRECISION_LABEL, dictionaryModel.bindIntegerPositive(WRITE_PRECISION_KEY)); + dataWriteBuilder.addComponent(WRITE_COMPRESSION_LABEL, dictionaryModel.bindSelection(WRITE_COMPRESSION_KEY, WRITE_COMPRESSION_VALUES, WRITE_COMPRESSION_LABELS)); + dataWriteBuilder.addComponent(TIME_FORMAT_LABEL, dictionaryModel.bindSelection(TIME_FORMAT_KEY, TIME_FORMAT_VALUES, TIME_FORMAT_LABELS)); + dataWriteBuilder.addComponent(TIME_PRECISION_LABEL, dictionaryModel.bindIntegerPositive(TIME_PRECISION_KEY)); + dataWriteBuilder.addComponent(GRAPH_FORMAT_LABEL, dictionaryModel.bindSelection(GRAPH_FORMAT_KEY, GRAPH_FORMAT_VALUE, GRAPH_FORMAT_LABELS)); + + JPanel timePanel = timeBuilder.margins(.5, .5, .5, .5).getPanel(); + timePanel.setBorder(BorderFactory.createTitledBorder(TIME_SETTINGS_LABEL)); + timePanel.setName(TIME_SETTINGS_LABEL); + + JPanel dataWritePanel = dataWriteBuilder.margins(.5, .5, .5, .5).getPanel(); + dataWritePanel.setBorder(BorderFactory.createTitledBorder(DATA_WRITING_LABEL)); + dataWritePanel.setName(DATA_WRITING_LABEL); + + PanelBuilder builder = new PanelBuilder(); + builder.addComponent(timePanel); + builder.addComponent(dataWritePanel); + + List actionsList = new ArrayList(); + JButton applyButton = new JButton(new WriteControlDictAction()); + applyButton.setName("Apply"); + actionsList.add(applyButton); + + JComponent buttonsPanel = UiUtil.getCommandRow(actionsList); + buttonsPanel.setBorder(BorderFactory.createEmptyBorder()); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(buttonsPanel, BorderLayout.NORTH); + mainPanel.add(builder.removeMargins().getPanel(), BorderLayout.CENTER); + + return mainPanel; + } + + @Override + public void load() { + this.time = model.getState().getTime(); + loadControlDict(); + fixGUI(); + } + + @Override + public void save() { + ControlDict controlDict = getModel().getProject().getSystemFolder().getControlDict(); + if (controlDict != null) { + boolean changed = hasControlDictChanged(controlDict); + controlDict.merge(dictionaryModel.getDictionary()); + controlDict.add(STOP_AT_KEY, END_TIME_KEY); + if (changed) { + isSaving = true; + model.projectChanged(); + isSaving = false; + } + } + } + + private boolean hasControlDictChanged(ControlDict controlDict) { + ControlDict d = new ControlDict(controlDict); + d.remove(ControlDict.FUNCTIONS_KEY); + return !d.toString().equals(dictionaryModel.getDictionary().toString()); + } + + @Override + public void stateChanged() { + super.stateChanged(); + State state = model.getState(); + if (this.time == null || state.getTime() != this.time) { + this.time = state.getTime(); + loadControlDict(); + } else { + /* + * Il file controlDict ora contiene i valori di default. Lo mergio con i valori della GUI per non perdere i cambiamenti fatti. Ovviamente questo significa che quello che ce nella GUI...rimane! + */ + Dictionary controlDict = model.getProject().getSystemFolder().getControlDict(); + if (controlDict != null) { + controlDict.merge(dictionaryModel.getDictionary()); + } + } + } + + @Override + public void projectChanged() { + if (!isSaving) { + loadControlDict(); + } + } + + private void loadControlDict() { + removeListeners(); + + ControlDict controlDict = getModel().getProject().getSystemFolder().getControlDict(); + if (controlDict != null) { + Dictionary dictionary = new Dictionary(controlDict); + dictionary.remove(FUNCTIONS_KEY); + dictionaryModel.setDictionary(dictionary); + } + + addListeners(); + } + + private void removeListeners() { + startFrom.removePropertyChangeListener("value", startFromListener); + adjustableTime.removeActionListener(adjustableTimeListener); + } + + private void addListeners() { + startFrom.addPropertyChangeListener("value", startFromListener); + adjustableTime.addActionListener(adjustableTimeListener); + } + + public void fixGUI() { + if (model.getSolverModel().getServerState().getSolverState().isRunning()) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + _fixGUI(); + } + }); + } + } + + private void _fixGUI() { + startTime.setEnabled(START_TIME_VALUE.equals(startFrom.getSelectedItem())); + + State state = model.getState(); + boolean isTransient = state.isTransient(); + boolean isSteadyMultiphase = state.isSteady() && state.getMultiphaseModel().isMultiphase(); + boolean isSteadyCoupled = state.isSteady() && state.getSolverType().isCoupled(); + + if (isTransient || isSteadyMultiphase || isSteadyCoupled) { + deltaT.setEnabled(true); + } else { + deltaT.setEnabled(false); + deltaT.setDoubleValue(1); + } + + adjustableTime.setEnabled((isTransient || isSteadyMultiphase) && !isSonic(state)); + maxCourantNumber.setEnabled((isTransient || isSteadyMultiphase) && adjustableTime.isSelected()); + maxAlphaCourant.setEnabled((isTransient || isSteadyMultiphase) && adjustableTime.isSelected() && state.getMultiphaseModel().isMultiphase()); + maxTimeStep.setEnabled((isTransient || isSteadyMultiphase) && adjustableTime.isSelected()); + } + + private boolean isSonic(State state) { + return state.isHighMach() && state.getSolverFamily().isPimple(); + } + + private class WriteControlDictAction extends AbstractAction { + + public WriteControlDictAction() { + super("Apply", APPLY_ICON); + } + + @Override + public void actionPerformed(ActionEvent e) { + // TODO check remote case + save(); + model.getProject().getSystemFolder().writeControlDict(new SilentMonitor()); + } + } +} diff --git a/src/eu/engys/gui/solver/UpdateClientState.java b/src/eu/engys/gui/solver/UpdateClientState.java new file mode 100644 index 0000000..84a88f6 --- /dev/null +++ b/src/eu/engys/gui/solver/UpdateClientState.java @@ -0,0 +1,45 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver; + +import eu.engys.core.project.Model; +import eu.engys.core.project.state.ServerState; +import eu.engys.gui.solver.postprocessing.ServerListener; + +public class UpdateClientState implements ServerListener { + + private Model model; + + public UpdateClientState(Model model) { + this.model = model; + } + + @Override + public void serverChanged(ServerState serverState) { + model.getSolverModel().setServerState(serverState); + } + +} diff --git a/src/eu/engys/gui/solver/actions/DefaultSolverActions.java b/src/eu/engys/gui/solver/actions/DefaultSolverActions.java new file mode 100644 index 0000000..640d140 --- /dev/null +++ b/src/eu/engys/gui/solver/actions/DefaultSolverActions.java @@ -0,0 +1,86 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.actions; + +import static eu.engys.util.ui.UiUtil.createToolBarButton; + +import javax.inject.Inject; +import javax.swing.Action; +import javax.swing.Box; +import javax.swing.JToolBar; + +import eu.engys.core.controller.Controller; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.gui.Actions; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; + +public abstract class DefaultSolverActions implements Actions { + + private final Action launchAction; + + private JToolBar toolbar; + protected Model model; + + @Inject + public DefaultSolverActions(Model model, Controller controller) { + this.model = model; + this.launchAction = ActionManager.getInstance().get("solver.run"); + } + + @Override + public JToolBar toolbar() { + toolbar = UiUtil.getToolbar("view.element.toolbar"); + + toolbar.add(createToolBarButton(launchAction)); + toolbar.addSeparator(); + addExtraActions(); + toolbar.add(Box.createHorizontalGlue()); + return toolbar; + } + + public JToolBar getToolbar() { + return toolbar; + } + + protected abstract void addExtraActions(); + + @Override + public void update() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + boolean isRemote = model.getSolverModel().isRemote(); + boolean hasMesh = !model.getPatches().isEmpty(); + boolean isRunning = model.getSolverModel() != null && model.getSolverModel().getServerState() != null && model.getSolverModel().getServerState().getSolverState().isRunning(); + boolean isSolutionSet = model.getState().areTimeAndFlowAndTurbulenceChoosen(); + launchAction.setEnabled(hasMesh && !isRunning && isSolutionSet); + } + }); + } + +} diff --git a/src/eu/engys/gui/solver/actions/EditRunSolverAction.java b/src/eu/engys/gui/solver/actions/EditRunSolverAction.java new file mode 100644 index 0000000..dfe61de --- /dev/null +++ b/src/eu/engys/gui/solver/actions/EditRunSolverAction.java @@ -0,0 +1,46 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.solver.actions; + + +//public class EditRunSolverAction extends ViewAction { +// +// private static final String EDIT_RUN_SOLVER_LABEL = ResourcesUtil.getString("solver.run.edit.label"); +// private static final String EDIT_RUN_SOLVER_TOOLTIP = ResourcesUtil.getString("solver.run.edit.tooltip"); +// private static final Icon EDIT_RUN_SOLVER_ICON = ResourcesUtil.getIcon("solver.run.edit.icon"); +// +// private Controller controller; +// +// public EditRunSolverAction(Controller controller) { +// super(EDIT_RUN_SOLVER_LABEL, EDIT_RUN_SOLVER_ICON, EDIT_RUN_SOLVER_TOOLTIP); +// this.controller = controller; +// } +// +// public void actionPerformed(ActionEvent e) { +// controller.editRunCaseScript(); +// } +//} diff --git a/src/eu/engys/gui/solver/actions/OpenParaviewAction.java b/src/eu/engys/gui/solver/actions/OpenParaviewAction.java new file mode 100644 index 0000000..985e864 --- /dev/null +++ b/src/eu/engys/gui/solver/actions/OpenParaviewAction.java @@ -0,0 +1,108 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.actions; + +import static eu.engys.core.OpenFOAMEnvironment.getEnvironment; + +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.FilenameFilter; + +import javax.swing.Icon; +import javax.swing.JOptionPane; + +import eu.engys.core.OpenFOAMEnvironment; +import eu.engys.core.executor.Executor; +import eu.engys.core.project.Model; +import eu.engys.util.OpenFOAMCommands; +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class OpenParaviewAction extends ViewAction { + + private static final String FOAM_EXTENSION = ".foam"; + + private Model model; + + public OpenParaviewAction(Model model) { + super(PARAVIEW_LABEL, PARAVIEW_ICON, PARAVIEW_TOOLTIP); + this.model = model; + } + + @Override + public void actionPerformed(ActionEvent e) { + launchParaView(); + } + + private void launchParaView() { + File paraView = PrefUtil.getParaViewEntry(); + if (OpenFOAMEnvironment.isParaviewPathSet()) { + String foamFile = getCaseFoamFile(); + if (foamFile != null) { + Executor.command(paraView, "--data=" + foamFile).inFolder(model.getProject().getBaseDir()).description(PARAVIEW_LABEL).exec(); + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "No .foam file found!", "Missing file", JOptionPane.ERROR_MESSAGE); + } + } else { + if(Util.isWindows()){ + UiUtil.showEnvironmentNotLoadedWarning(PARAVIEW_LABEL); + } else { + if(OpenFOAMEnvironment.isEnvironementLoaded()){ + Executor.command(OpenFOAMCommands.PARA_FOAM).inFolder(model.getProject().getBaseDir()).withOpenFoamEnv().env(getEnvironment(model)).description(PARAVIEW_LABEL).exec(); + } else { + UiUtil.showCoreEnvironmentNotLoadedWarning(); + } + } + } + } + + private String getCaseFoamFile() { + File baseDir = model.getProject().getBaseDir(); + String[] foamFiles = baseDir.list(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(FOAM_EXTENSION); + } + }); + if (foamFiles.length == 0) { + return null; + } else { + return baseDir.toPath().resolve(foamFiles[0]).toAbsolutePath().toString(); + } + } + + /** + * Resources + */ + + private static final Icon PARAVIEW_ICON = ResourcesUtil.getIcon("paraview.icon"); + + private static final String PARAVIEW_LABEL = ResourcesUtil.getString("paraview.label"); + private static final String PARAVIEW_TOOLTIP = ResourcesUtil.getString("paraview.tooltip"); +} diff --git a/src/eu/engys/gui/solver/actions/RunSolverAction.java b/src/eu/engys/gui/solver/actions/RunSolverAction.java new file mode 100644 index 0000000..b135eb0 --- /dev/null +++ b/src/eu/engys/gui/solver/actions/RunSolverAction.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.solver.actions; + + +//public class RunSolverAction extends ViewAction { +// +// private static final String RUN_SOLVER_LABEL = ResourcesUtil.getString("solver.run.label"); +// private static final String RUN_SOLVER_TOOLTIP = ResourcesUtil.getString("solver.run.tooltip"); +// private static final Icon RUN_SOLVER_ICON = ResourcesUtil.getIcon("solver.run.icon"); +// +// private Controller controller; +// +// public RunSolverAction(Controller controller) { +// super(RUN_SOLVER_LABEL, RUN_SOLVER_ICON, RUN_SOLVER_TOOLTIP); +// this.controller = controller; +// } +// +// @Override +// public void actionPerformed(ActionEvent e) { +// if (controller.isDemo()) { +// controller.showDemoMessage(); +// } else { +// if (PrefUtil.isEnvironementLoaded()) { +//// controller.launch(); +// } else { +// UiUtil.showCoreEnvironmentNotLoadedWarning(); +// } +// } +// } +//} diff --git a/src/eu/engys/gui/solver/actions/StandardSolverActions.java b/src/eu/engys/gui/solver/actions/StandardSolverActions.java new file mode 100644 index 0000000..8639c1f --- /dev/null +++ b/src/eu/engys/gui/solver/actions/StandardSolverActions.java @@ -0,0 +1,47 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.actions; + +import static eu.engys.util.ui.UiUtil.createToolBarButton; + +import javax.inject.Inject; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; + +public class StandardSolverActions extends DefaultSolverActions { + + @Inject + public StandardSolverActions(Model model, Controller controller) { + super(model, controller); + } + + @Override + protected void addExtraActions() { + getToolbar().add(createToolBarButton(new OpenParaviewAction(model))); + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/ParsersHandler.java b/src/eu/engys/gui/solver/postprocessing/ParsersHandler.java new file mode 100644 index 0000000..4f73861 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/ParsersHandler.java @@ -0,0 +1,182 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.Model; +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObject; +import eu.engys.core.project.system.monitoringfunctionobjects.Parser; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.gui.solver.postprocessing.parsers.ResidualsParser; +import eu.engys.gui.solver.postprocessing.parsers.ResidualsUtils; + +public class ParsersHandler { + + private static final Logger logger = LoggerFactory.getLogger(ParsersHandler.class); + + private final Model model; + + private Map> parsersMap; + + public ParsersHandler(Model model) { + this.model = model; + this.parsersMap = Collections.synchronizedMap(new HashMap>()); + // this will syncro add/remove/indexof/size BUT iterating should be + // sync'd manually! + } + + public void deleteUselessLogFiles() { + ResidualsUtils.clearLogFile(model); + for (MonitoringFunctionObject fo : model.getMonitoringFunctionObjects()) { + fo.getType().getFactory().deleteUselessLogFiles(fo); + } + } + + /* + * Register + */ + private void registerParsersForFunctionObject(String foName) { + if (foName.equals(ResidualsParser.KEY)) { + ResidualsParser residualsParser = new ResidualsParser(ResidualsUtils.fileToParse(model)); + register(residualsParser); + } + for (MonitoringFunctionObject fo : model.getMonitoringFunctionObjects()) { + if (fo.getName().equals(foName)) { + List parsers = fo.getType().getFactory().createParsers(fo); + for (Parser parser : parsers) { + register(parser); + } + } + } + } + + private void register(Parser parser) { + if (parser != null && !isAlreadyRegistered(parser)) { + logger.debug("ADDING PARSER FOR {}", parser.getFile()); + if (!parsersMap.containsKey(parser.getKey())) { + parsersMap.put(parser.getKey(), new ArrayList()); + } + parsersMap.get(parser.getKey()).add(parser); + parser.init(); + parser.clear(); + } + } + + private boolean isAlreadyRegistered(Parser parser) { + if (parsersMap.containsKey(parser.getKey())) { + List parsersForKey = parsersMap.get(parser.getKey()); + for (Parser p : parsersForKey) { + if (p.getFile().getAbsolutePath().equals(parser.getFile().getAbsolutePath())) { + return true; + } + } + } + return false; + } + + /* + * Refresh + */ + + public List refreshOnceForFunctionObject(String foName) { + logger.info("REFRESH ONCE {}", foName); + List list = refreshParsersForFunctionObject(foName); + endParsersForFunctionObject(foName); + return list; + } + + public List refreshParsersForFunctionObject(String foName) { + // If new files are created at runtime + registerParsersForFunctionObject(foName); + + List blocks = new ArrayList<>(); + if (parsersMap.containsKey(foName)) { + for (Parser parser : parsersMap.get(foName)) { + try { + TimeBlocks newTimeBlocks = parser.updateParsing(); + if (!newTimeBlocks.isEmpty()) { + logger.debug("{} ADDED {} BLOCKS [{} - {}] FROM FILE {}", foName, newTimeBlocks.size(), newTimeBlocks.get(0).getTime(), newTimeBlocks.getLast().getTime(), parser.getFile()); + } else { + logger.debug("{} ADDED {} BLOCKS FROM FILE {}", foName, newTimeBlocks.size(), parser.getFile()); + } + blocks.add(newTimeBlocks); + } catch (Exception e) { + logger.error("ERROR WHILE PARSING", e); + } + } + + printTimeBlocksInfo(blocks, foName); + + } else { + logger.warn("CANNOT FIND PARSER {} AMONG {}", foName, parsersMap.keySet()); + } + + return blocks; + } + + private void printTimeBlocksInfo(List blocks, String functionObjectName) { + if (!blocks.isEmpty()) { + TimeBlocks allTimeBlocks = new TimeBlocks(); + for (TimeBlocks bs : blocks) { + allTimeBlocks.addAll(bs); + } + if (!allTimeBlocks.isEmpty()) { + logger.debug("{} TOTAL BLOCKS: [{} - {}]", functionObjectName, allTimeBlocks.get(0).getTime(), allTimeBlocks.getLast().getTime()); + } else { + logger.debug("{} PARSER BLOCKS: NO TIMES", functionObjectName); + } + } else { + logger.debug("{} PARSER BLOCKS: NO BLOCKS", functionObjectName); + } + } + + /* + * End + */ + + public void endParsers() { + for (String parserName : parsersMap.keySet()) { + endParsersForFunctionObject(parserName); + } + } + + private void endParsersForFunctionObject(String functionObjectName) { + if(parsersMap.containsKey(functionObjectName)){ + for (Parser parser : parsersMap.get(functionObjectName)) { + parser.end(); + } + } + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/ParsersViewHandler.java b/src/eu/engys/gui/solver/postprocessing/ParsersViewHandler.java new file mode 100644 index 0000000..21d7bc8 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/ParsersViewHandler.java @@ -0,0 +1,232 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing; + +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ThreadPoolExecutor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.ParsersManager; +import eu.engys.core.executor.Executor; +import eu.engys.core.project.Model; +import eu.engys.core.project.state.ServerState; +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObject; +import eu.engys.core.project.system.monitoringfunctionobjects.ParserView; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.gui.solver.postprocessing.panels.residuals.ResidualsView; +import eu.engys.util.ui.ExecUtil; + +public class ParsersViewHandler implements ServerListener { + + private static final Logger logger = LoggerFactory.getLogger(ParsersViewHandler.class); + + private final Model model; + + private List views; + private ResidualsView residualsView; + private ThreadPoolExecutor executor; + + private ParsersManager parserManager; + + public ParsersViewHandler(Model model, ParsersManager parserManager, ResidualsView residualsView) { + this.model = model; + this.parserManager = parserManager; + this.residualsView = residualsView; + this.views = Collections.synchronizedList(new ArrayList()); + this.executor = Executor.newExecutor("ParserViewHandler"); + registerViews(); + } + + private void registerViews() { + register(residualsView); + for (MonitoringFunctionObject fo : model.getMonitoringFunctionObjects()) { + ParserView view = fo.getView(); + register(view); + } + } + + private void register(ParserView view) { + if (view != null) { + logger.debug("REGISTERING {} VIEW", view.getKey()); + views.add(view); + } + } + + @Override + public void serverChanged(ServerState serverState) { + switch (serverState.getSolverState()) { + case STARTED: + started(); + break; + case RUNNING: + running(); + break; + case ERROR: + error(); + break; + case FINISHED: + running();// Needed by OS + finished(); + break; + + default: + break; + } + } + + private void started() { + logger.debug("STARTED"); + for (ParserView view : views) { + view.setParsingEnabled(true); + view.handleSolverStarted(); + } + } + + private void finished() { + logger.debug("FINISHED"); + executor.submit(new Runnable() { + @Override + public void run() { + try { + logger.debug("ENDING PARSERS"); + parserManager.endParsers(); + } catch (RemoteException e) { + logger.error("ERROR ENDING PARSERS", e); + } + } + }); + executor.shutdown(); + } + + private void running() { + for (final ParserView view : views) { + if (view.isParsingEnabled()) { + if (notInQueue(view)) { + executor.submit(new ParserUpdateTask(view)); + } + } + } + } + + private boolean notInQueue(ParserView view) { + for (Runnable r : executor.getQueue()) { + if (r instanceof ParserUpdateTask) { + ParserUpdateTask task = (ParserUpdateTask) r; + if (task.getView() == view) { + return false; + } + } + } + + return true; + } + + public void refreshOnce() { + logger.info("REFRESH ONCE"); + for (final ParserView view : views) { + if (view.isParsingEnabled()) { + executor.submit(new Runnable() { + @Override + public void run() { + view.showLoading(); + List timeBlocks = updateParserOnce(parserManager, view.getKey()); + logger.debug("RETRIVED {} TIME BLOCKS FOR {}", timeBlocks.size(), view.getKey()); + updateView(view, timeBlocks); + view.stopLoading(); + } + }); + } + } + executor.shutdown(); + } + + private List updateParser(ParsersManager parsersManager, String key) { + logger.debug("REFRESH PARSER {}", key); + try { + return parsersManager.updateParser(key); + } catch (RemoteException e) { + logger.error("ERROR ON REFRESH", e); + } + return Collections.emptyList(); + } + + private List updateParserOnce(ParsersManager parsersManager, String key) { + logger.debug("REFRESH PARSER ONCE {}", key); + try { + return parsersManager.updateParserOnce(key); + } catch (RemoteException e) { + logger.error("ERROR ON REFRESH ONCE", e); + } + return Collections.emptyList(); + } + + private void updateView(final ParserView view, final List newTimeBlocks) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + if (newTimeBlocks != null) { + view.updateParsing(newTimeBlocks); + } else { + logger.warn("EMPTY TIME BLOCK"); + } + } + }); + } + + private void error() { + logger.debug("ERROR"); + executor.shutdown(); + } + + class ParserUpdateTask implements Runnable { + + private ParserView view; + + public ParserUpdateTask(ParserView view) { + this.view = view; + } + + @Override + public void run() { + view.showLoading(); + List timeBlocks = updateParser(parserManager, view.getKey()); + logger.debug("RETRIVED {} TIME BLOCKS FOR {}", timeBlocks.size(), view.getKey()); + updateView(view, timeBlocks); + view.stopLoading(); + } + + public ParserView getView() { + return view; + } + + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/ServerListener.java b/src/eu/engys/gui/solver/postprocessing/ServerListener.java new file mode 100644 index 0000000..b9cf5c2 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/ServerListener.java @@ -0,0 +1,34 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing; + +import eu.engys.core.project.state.ServerState; + +public interface ServerListener { + + void serverChanged(ServerState serverState); + +} diff --git a/src/eu/engys/gui/solver/postprocessing/ServerStateMonitor.java b/src/eu/engys/gui/solver/postprocessing/ServerStateMonitor.java new file mode 100644 index 0000000..3b2beca --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/ServerStateMonitor.java @@ -0,0 +1,279 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing; + +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ThreadPoolExecutor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.Command; +import eu.engys.core.controller.Server; +import eu.engys.core.executor.Executor; +import eu.engys.core.executor.ExecutorError; +import eu.engys.core.project.SolverState; +import eu.engys.core.project.state.ServerState; +import eu.engys.util.PrefUtil; + +public class ServerStateMonitor { + + private static final Logger logger = LoggerFactory.getLogger(ServerStateMonitor.class); + + private static final long TIMER_INITIAL_DELAY = 500L; + private static final long TIMER_REFRESH_RATE = 1000L; + + private Timer timer; + private Server server; + + private Map> listeners = new HashMap<>(); + private Map>> hooks = new HashMap<>(); + + private ServerState endState; + + private ThreadPoolExecutor executor; + + public ServerStateMonitor() { + } + + public void startMonitor(Server server) { + logger.info(">>> START MONITOR"); + this.server = server; + startTimer(); + } + + public void waitForFinished() { + int wait_for_running_refresh_time = PrefUtil.getInt(PrefUtil.SERVER_WAIT_FOR_RUN_REFRESH_TIME, 2000); + while (timer != null) { + try { + Thread.sleep(wait_for_running_refresh_time); + } catch (InterruptedException e) { + } finally { + } + } + } + + private void startTimer() { + executor = Executor.newExecutor("ServerStateMonitor"); + if (timer == null) { + timer = new Timer("- Server Monitor -", true); + } + timer.schedule(new TimerTask() { + @Override + public void run() { + if (executor.getQueue().isEmpty()) { + executor.submit(new Runnable() { + @Override + public void run() { + runTimer(); + } + }); + } else { + logger.debug("Timer running..."); + } + } + }, TIMER_INITIAL_DELAY, TIMER_REFRESH_RATE); + } + + private void runTimer() { + if (server == null) { + handleNoServer(); + } else { + handleServerIsRunning(); + } + } + + private void handleNoServer() { + logger.info(">>> ERROR: NO SERVER"); + notifyServerStateChanged(new ServerState(Command.ANY, SolverState.ERROR)); + } + + private void handleServerIsRunning() { + try { + List remoteStates = server.getStates(); + if (remoteStates.isEmpty()) { + logger.info(">>> NO SERVER STATES"); + } + + for (ServerState remoteState : remoteStates) { + logger.info(">>> SERVER STATE: " + remoteState); + + if (remoteState.getSolverState().isStarted()) { + notifyServerStateChanged(remoteState); + } else if (remoteState.getSolverState().isMeshing()) { + notifyServerStateChanged(remoteState); + } else if (remoteState.getSolverState().isInitialising()) { + notifyServerStateChanged(remoteState); + } else if (remoteState.getSolverState().isRunning()) { + notifyServerStateChanged(remoteState); + } else if (remoteState.getSolverState().isFinished()) { + notifyServerStateChanged(remoteState); + } else if (remoteState.getSolverState().isMeshed()) { + notifyServerStateChanged(remoteState); + } else if (remoteState.getSolverState().isInitialised()) { + notifyServerStateChanged(remoteState); + } else if (remoteState.getSolverState().isError()) { + notifyServerStateChanged(remoteState); + } else { + logger.error(">>> UNKOWN STATE {]", remoteState.getSolverState()); + } + + // try { Thread.sleep(1000); } catch (InterruptedException e) {} + } + } catch (RemoteException e) { + logger.info(">>> SERVER: ERROR (SERVER EXITED)"); + ServerState errorState = new ServerState(Command.ANY, SolverState.ERROR, new ExecutorError(-1, "Server Exited")); + notifyServerStateChanged(errorState); + stopTimer(); + } + } + + private void notifyServerStateChanged(ServerState state) { + // logger.info(">>> NOTIFY: {} ", state); + Command command = state.getCommand(); + SolverState solverState = state.getSolverState(); + + if (listeners.containsKey(command)) { + for (ServerListener listener : listeners.get(command)) { + listener.serverChanged(state); + } + } else if (command.equals(Command.ANY)) { + for (Command c : listeners.keySet()) { + for (ServerListener listener : listeners.get(c)) { + listener.serverChanged(state); + } + } + } else if (listeners.containsKey(Command.ANY)) { + for (ServerListener listener : listeners.get(Command.ANY)) { + listener.serverChanged(state); + } + } + + if (hooks.containsKey(command)) { + if (hooks.get(command).containsKey(solverState)) { + for (ServerListener listener : hooks.get(command).get(solverState)) { + listener.serverChanged(state); + } + } + } else if (command.equals(Command.ANY)) { + for (Command c : hooks.keySet()) { + if (hooks.get(c).containsKey(solverState)) { + for (ServerListener listener : hooks.get(c).get(solverState)) { + listener.serverChanged(state); + } + } + } + } else if (hooks.containsKey(Command.ANY)) { + if (hooks.get(Command.ANY).containsKey(solverState)) { + for (ServerListener listener : hooks.get(Command.ANY).get(solverState)) { + listener.serverChanged(state); + } + } + } + + if (endState != null) { + if (endState.equals(state) || state.getSolverState().isError()) { + logger.info("STATE IS {}, END STATE IS {}", state.getSolverState(), endState); + stopTimer(); + } + } + } + + public void stopTimer() { + logger.debug("STOP TIMER"); + if (executor != null) { + executor.shutdown(); + executor = null; + } + if (timer != null) { + timer.cancel(); + timer.purge(); + timer = null; + } + } + + public CommandHook forCommand(Command command) { + return new CommandHook(command); + } + + /* + * For test purposes only + */ + public boolean isRunning() { + return timer != null; + } + + public class CommandHook { + private Command command; + + public CommandHook(Command command) { + this.command = command; + if (!hooks.containsKey(command)) { + hooks.put(command, new HashMap>()); + } + if (!listeners.containsKey(command)) { + listeners.put(command, new ArrayList()); + } + } + + public SolverHook when(SolverState state) { + return new SolverHook(command, state); + } + + public void forEachState(ServerListener listener) { + listeners.get(command).add(listener); + } + } + + public class SolverHook { + + private SolverState state; + private Command command; + + public SolverHook(Command command, SolverState state) { + this.command = command; + this.state = state; + if (!hooks.get(command).containsKey(state)) { + hooks.get(command).put(state, new ArrayList()); + } + } + + public void execute(ServerListener listener) { + hooks.get(command).get(state).add(listener); + } + + public void endTimer() { + ServerStateMonitor.this.endState = new ServerState(command, state); + } + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/data/DoubleListTimeBlockUnit.java b/src/eu/engys/gui/solver/postprocessing/data/DoubleListTimeBlockUnit.java new file mode 100644 index 0000000..cbe57dd --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/data/DoubleListTimeBlockUnit.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.data; + +import java.util.LinkedList; +import java.util.List; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlockUnit; + +public class DoubleListTimeBlockUnit extends TimeBlockUnit { + + /* + * Used for residuals parser where a variable can be resolved multiple times (orthogonal correctors) + */ + + private List values; + + public DoubleListTimeBlockUnit(String varName) { + super(varName); + this.values = new LinkedList(); + } + + public List getValues() { + return values; + } + + @Override + public String toString() { + return "[" + getVarName() + ", " + values + "]"; + } +} diff --git a/src/eu/engys/gui/solver/postprocessing/data/DoubleTimeBlockUnit.java b/src/eu/engys/gui/solver/postprocessing/data/DoubleTimeBlockUnit.java new file mode 100644 index 0000000..3e3437b --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/data/DoubleTimeBlockUnit.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.data; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlockUnit; + + +public class DoubleTimeBlockUnit extends TimeBlockUnit { + + private Double value; + + public DoubleTimeBlockUnit(String varName, Double value) { + super(varName); + this.value = value; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + + @Override + public String toString() { + return "[" + getVarName() + ", " + getValue() + "]"; + } +} diff --git a/src/eu/engys/gui/solver/postprocessing/data/PointTimeBlockUnit.java b/src/eu/engys/gui/solver/postprocessing/data/PointTimeBlockUnit.java new file mode 100644 index 0000000..cdf20e9 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/data/PointTimeBlockUnit.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.data; + +import javax.vecmath.Point3d; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlockUnit; + +public class PointTimeBlockUnit extends TimeBlockUnit { + + private Point3d point; + + public PointTimeBlockUnit(String varName, double[] points) { + super(varName); + this.point = new Point3d(points); + } + + public PointTimeBlockUnit(String varName, Point3d point) { + super(varName); + this.point = point; + } + + public Point3d getPoint() { + return point; + } + + @Override + public String toString() { + return "[" + getVarName() + ", " + getPoint() + "]"; + } +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/AbstractChartPanel.java b/src/eu/engys/gui/solver/postprocessing/panels/AbstractChartPanel.java new file mode 100644 index 0000000..2b7dbd6 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/AbstractChartPanel.java @@ -0,0 +1,148 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels; + +import static org.jfree.chart.ChartPanel.DEFAULT_HEIGHT; +import static org.jfree.chart.ChartPanel.DEFAULT_MAXIMUM_DRAW_HEIGHT; +import static org.jfree.chart.ChartPanel.DEFAULT_MAXIMUM_DRAW_WIDTH; +import static org.jfree.chart.ChartPanel.DEFAULT_MINIMUM_DRAW_HEIGHT; +import static org.jfree.chart.ChartPanel.DEFAULT_MINIMUM_DRAW_WIDTH; +import static org.jfree.chart.ChartPanel.DEFAULT_WIDTH; + +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.text.DecimalFormat; + +import javax.swing.JPanel; + +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.block.BlockBorder; +import org.jfree.chart.labels.CrosshairLabelGenerator; +import org.jfree.chart.panel.CrosshairOverlay; +import org.jfree.chart.plot.Crosshair; +import org.jfree.chart.title.LegendTitle; +import org.jfree.ui.RectangleEdge; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; + +public abstract class AbstractChartPanel extends JPanel { + + protected static final String TIME_LABEL = "Time [s]"; + + protected String title; + protected String domainAxisLabel; + protected String rangeAxisLabel; + + protected ChartPanel chartPanel; + protected JFreeChart chart; + + protected CrosshairOverlay overlay; + + public AbstractChartPanel(String title, String domainAxisLabel, String rangeAxisLabel) { + super(new BorderLayout()); + this.title = title; + this.domainAxisLabel = domainAxisLabel; + this.rangeAxisLabel = rangeAxisLabel; + } + + public void layoutComponents() { + createChart(); + this.chart.setBackgroundPaint(new Color(0, 0, 0, 0)); + this.chartPanel = createChartPanel(); + layoutLegend(); + } + + protected abstract void createChart(); + + public abstract void stop(); + + public abstract void addToDataSet(TimeBlocks list); + + public abstract void clearData(); + + private ChartPanel createChartPanel() { + boolean useBuffer = true; + boolean showPropertiesMenu = true; + boolean showCopyMenu = true; + boolean showSaveMenu = false; + boolean showPrintMenu = true; + boolean showZoomMenu = true; + boolean showTooltipsMenu = true; + ChartPanel panel = new ChartPanel(chart, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_MINIMUM_DRAW_WIDTH, DEFAULT_MINIMUM_DRAW_HEIGHT, DEFAULT_MAXIMUM_DRAW_WIDTH, DEFAULT_MAXIMUM_DRAW_HEIGHT, useBuffer, showPropertiesMenu, showCopyMenu, showSaveMenu, showPrintMenu, showZoomMenu, showTooltipsMenu); + this.overlay = createOverlay(); + return panel; + } + + private CrosshairOverlay createOverlay() { + CrosshairOverlay crosshairOverlay = new CrosshairOverlay(); + Crosshair xCrosshair = new Crosshair(Double.NaN, Color.BLUE.brighter(), new BasicStroke(0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 1.0f }, 0.0f)); + xCrosshair.setLabelGenerator(new CrosshairLabelGenerator() { + @Override + public String generateLabel(Crosshair crosshair) { + DecimalFormat decimalFormat = new DecimalFormat("#.######"); + return decimalFormat.format(crosshair.getValue()); + } + }); + xCrosshair.setLabelBackgroundPaint(Color.WHITE); + xCrosshair.setLabelOutlineVisible(false); + xCrosshair.setLabelVisible(true); + + Crosshair yCrosshair = new Crosshair(Double.NaN, Color.BLUE.brighter(), new BasicStroke(0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 1.0f }, 0.0f)); + yCrosshair.setLabelGenerator(new CrosshairLabelGenerator() { + @Override + public String generateLabel(Crosshair crosshair) { + DecimalFormat decimalFormat = new DecimalFormat("#.######"); + return decimalFormat.format(crosshair.getValue()); + } + }); + yCrosshair.setLabelBackgroundPaint(Color.WHITE); + yCrosshair.setLabelOutlineVisible(false); + yCrosshair.setLabelVisible(true); + + crosshairOverlay.addDomainCrosshair(xCrosshair); + crosshairOverlay.addRangeCrosshair(yCrosshair); + return crosshairOverlay; + } + + private void layoutLegend() { + LegendTitle legend = chart.getLegend(); + if (legend != null) { + legend.setFrame(BlockBorder.NONE); + legend.setBackgroundPaint(null); + legend.setPosition(RectangleEdge.RIGHT); + legend.setVisible(false); + } + } + + public JFreeChart getChart() { + return chart; + } + + public void initSeries() { + } +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/AbstractParserView.java b/src/eu/engys/gui/solver/postprocessing/panels/AbstractParserView.java new file mode 100644 index 0000000..1f51633 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/AbstractParserView.java @@ -0,0 +1,266 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.io.File; +import java.io.IOException; +import java.util.List; + +import javax.swing.JComponent; +import javax.swing.JLayer; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; + +import org.apache.commons.io.FilenameUtils; +import org.jfree.chart.ChartUtilities; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.executor.FileManagerSupport; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObject; +import eu.engys.core.project.system.monitoringfunctionobjects.Parser; +import eu.engys.core.project.system.monitoringfunctionobjects.ParserView; +import eu.engys.gui.solver.postprocessing.panels.utils.WaitLayerUI; +import eu.engys.util.Util; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.FileChooserUtils; + +public abstract class AbstractParserView extends JPanel implements ParserView { + + private static final Logger logger = LoggerFactory.getLogger(AbstractParserView.class); + protected Model model; + protected MonitoringFunctionObject functionObject; + protected ProgressMonitor monitor; + protected JTabbedPane tabbedPane; + private boolean parsingEnabled; + + private WaitLayerUI loadingPane; + + public AbstractParserView(Model model, MonitoringFunctionObject functionObject, ProgressMonitor monitor) { + super(new BorderLayout()); + this.model = model; + this.functionObject = functionObject; + this.monitor = monitor; + this.tabbedPane = new JTabbedPane(); + this.parsingEnabled = false; + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(tabbedPane, BorderLayout.CENTER); + + loadingPane = new WaitLayerUI(new EnableParsing()); + JLayer layer = new JLayer(mainPanel, loadingPane); + + add(layer, BorderLayout.CENTER); + } + + @Override + public void reset() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + clearData(); + loadingPane.init(); + setParsingEnabled(false); + } + }); + } + + @Override + public void handleSolverStarted() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + clearData(); + loadingPane.stop(); + } + }); + } + + @Override + public void showLoading() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + loadingPane.start(); + } + }); + } + + @Override + public void stopLoading() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + loadingPane.stop(); + } + }); + } + + @Override + public void setCrosshairVisibile(boolean visible) { + for (Component c : tabbedPane.getComponents()) { + if (c instanceof MovingAverageChartPanel) { + ((MovingAverageChartPanel) c).setCrosshairVisible(visible); + } + } + } + + @Override + public void showLogFile() { + try { + List parsersList = gerReportParsersList(); + for (Parser parser : parsersList) { + File logFile = parser.getFile(); + if (logFile != null && logFile.exists()) { + if (Util.isWindows() && FilenameUtils.getExtension(logFile.getName()).isEmpty()) { + FileManagerSupport.open(logFile.getParentFile()); + } else { + FileManagerSupport.open(logFile); + } + } + } + } catch (Exception e1) { + JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(AbstractParserView.this), e1.getMessage(), "Export Error", JOptionPane.ERROR_MESSAGE); + logger.error("Cannot open log file", e1.getMessage()); + } + } + + @Override + public void exportToExcel() { + final File excelFile = FileChooserUtils.getExcelFile(); + if (excelFile != null) { + monitor.setIndeterminate(true); + monitor.start("Export to Excel", false, new Runnable() { + @Override + public void run() { + try { + getExporter().exportToExcel(excelFile, monitor); + } catch (Exception e) { + showErrorMessage(e); + } finally { + monitor.end(); + } + } + + }); + } + } + + @Override + public void exportToCSV() { + final File csvFile = FileChooserUtils.getCSVFile(); + if (csvFile != null) { + monitor.start("Export to CSV", false, new Runnable() { + @Override + public void run() { + try { + getExporter().exportToCSV(csvFile, monitor); + } catch (Exception e) { + showErrorMessage(e); + } finally { + monitor.end(); + } + } + }); + } + } + + @Override + public void exportToPNG() { + AbstractChartPanel chartPanel = (AbstractChartPanel) tabbedPane.getSelectedComponent(); + File pngFile = FileChooserUtils.getPNGFile(); + if (pngFile != null && chartPanel != null) { + // PRE-SAVE + chartPanel.getChart().setBackgroundPaint(Color.WHITE); + if (chartPanel.getChart().getLegend() != null) { + chartPanel.getChart().getLegend().setBackgroundPaint(Color.WHITE); + chartPanel.getChart().getLegend().setVisible(true); + } + // SAVE + try { + ChartUtilities.saveChartAsPNG(pngFile, chartPanel.getChart(), chartPanel.getSize().width, chartPanel.getSize().height); + } catch (IOException e1) { + e1.printStackTrace(); + } + + // POST-SAVE + chartPanel.getChart().setBackgroundPaint(new Color(0, 0, 0, 0)); + if (chartPanel.getChart().getLegend() != null) { + chartPanel.getChart().getLegend().setBackgroundPaint(new Color(0, 0, 0, 0)); + chartPanel.getChart().getLegend().setVisible(false); + } + FileManagerSupport.open(pngFile); + } else { + logger.error("Problem saving chart to PNG"); + } + } + + private void showErrorMessage(final Exception e) { + ExecUtil.invokeLater(new Runnable() { + + @Override + public void run() { + JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(AbstractParserView.this), e.getMessage(), "Export Error", JOptionPane.ERROR_MESSAGE); + logger.error("Cannot export", e.getMessage()); + } + }); + } + + @Override + public boolean isParsingEnabled() { + return parsingEnabled; + } + + @Override + public void setParsingEnabled(boolean parsingEnabled) { + this.parsingEnabled = parsingEnabled; + } + + @Override + public JComponent getPanel() { + return this; + } + + protected class EnableParsing implements Runnable { + @Override + public void run() { + setParsingEnabled(true); + ActionManager.getInstance().invoke("solver.refresh.once"); + if (!model.getSolverModel().getServerState().getSolverState().isDoingSomething()) { + setParsingEnabled(false); + } + } + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/HistoryChartPanel.java b/src/eu/engys/gui/solver/postprocessing/panels/HistoryChartPanel.java new file mode 100644 index 0000000..0031cf6 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/HistoryChartPanel.java @@ -0,0 +1,87 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels; + +import java.util.List; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.labels.StandardXYToolTipGenerator; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.renderer.xy.StandardXYItemRenderer; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; + +import eu.engys.util.ui.textfields.DoubleField; + +public abstract class HistoryChartPanel extends MovingAverageChartPanel { + + private static final long serialVersionUID = 1L; + + protected List seriesNames; + + public HistoryChartPanel(String title, List seriesNames, String domainAxisLabel, String rangeAxisLabel, boolean showMovingAverage) { + super(title, domainAxisLabel, rangeAxisLabel, showMovingAverage); + this.seriesNames = seriesNames; + this.dataset = new XYSeriesCollection(); + } + + @Override + public void initSeries() { + for (String serieName : seriesNames) { + XYSeries series = new XYSeries(serieName); + dataset.addSeries(series); + populateSeriesPanel(dataset.getSeriesIndex(series.getKey()), series.getKey().toString()); + } + } + + @Override + protected void createChart() { + this.chart = ChartFactory.createXYLineChart("", "", "", dataset, PlotOrientation.VERTICAL, true, true, false); + + NumberAxis domainAxis = new NumberAxis(domainAxisLabel); + domainAxis.setAutoRangeIncludesZero(false); + + NumberAxis rangeAxis = new NumberAxis(rangeAxisLabel); + rangeAxis.setNumberFormatOverride(DoubleField.getFormatForDISPLAY(10)); + + chart.getXYPlot().setDomainAxis(domainAxis); + chart.getXYPlot().setRangeAxis(rangeAxis); + chart.getXYPlot().setDataset(1, movingAverageDataSet); + + StandardXYItemRenderer movingAverageRenderer = new StandardXYItemRenderer(); + movingAverageRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); + chart.getXYPlot().setRenderer(1, movingAverageRenderer); + } + + @Override + protected void clearDataset() { + for (int i = 0; i < dataset.getSeriesCount(); i++) { + dataset.getSeries(i).clear(); + } + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/MovingAverageChartPanel.java b/src/eu/engys/gui/solver/postprocessing/panels/MovingAverageChartPanel.java new file mode 100644 index 0000000..e54469e --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/MovingAverageChartPanel.java @@ -0,0 +1,235 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels; + +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.BorderFactory; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; + +import org.jfree.chart.ChartMouseEvent; +import org.jfree.chart.ChartMouseListener; +import org.jfree.chart.plot.Crosshair; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.XYItemRenderer; +import org.jfree.data.general.DatasetUtilities; +import org.jfree.data.xy.AbstractIntervalXYDataset; +import org.jfree.data.xy.XYSeriesCollection; +import org.jfree.ui.RectangleEdge; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlock; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.gui.solver.postprocessing.panels.utils.MovingAveragePanel; +import eu.engys.gui.solver.postprocessing.panels.utils.SeriesPanel; +import eu.engys.util.ui.ExecUtil; + +public abstract class MovingAverageChartPanel extends AbstractChartPanel { + + private static final long serialVersionUID = 1L; + + protected SeriesPanel seriesPanel; + protected MovingAveragePanel movingAveragePanel; + + protected D dataset; + protected XYSeriesCollection movingAverageDataSet; + private boolean showMovingAverage; + + private CrosshairListener crosshairListener; + + public MovingAverageChartPanel(String title, String domainAxisLabel, String rangeAxisLabel, boolean showMovingAverage) { + super(title, domainAxisLabel, rangeAxisLabel); + setName(title + ".chart.panel"); + this.showMovingAverage = showMovingAverage; + this.movingAverageDataSet = new XYSeriesCollection(); + this.crosshairListener = new CrosshairListener(); + } + + @Override + public void layoutComponents() { + super.layoutComponents(); + chartPanel.addOverlay(overlay); + + this.seriesPanel = new SeriesPanel(showMovingAverage ? movingAveragePanel = new MovingAveragePanel(dataset, movingAverageDataSet) : null); + + JScrollPane seriesScrollPane = new JScrollPane(seriesPanel); + seriesScrollPane.setBorder(BorderFactory.createEmptyBorder()); + + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + splitPane.setOneTouchExpandable(false); + splitPane.setLeftComponent(chartPanel); + splitPane.setRightComponent(seriesScrollPane); + + double scrollPaneWidth = splitPane.getPreferredSize().getWidth(); + double seriesPanelWidth = seriesPanel.getPreferredSize().getWidth(); + if (seriesPanelWidth != 0 && scrollPaneWidth != 0) { + double value = 1 - (seriesPanelWidth / scrollPaneWidth) - 0.07; + splitPane.setResizeWeight(value); + } else { + splitPane.setResizeWeight(0.9); + } + add(splitPane, BorderLayout.CENTER); + } + + public void setCrosshairVisible(boolean visible) { + if (visible) { + chartPanel.addChartMouseListener(crosshairListener); + chartPanel.addMouseListener(crosshairListener); + } else { + chartPanel.removeChartMouseListener(crosshairListener); + chartPanel.removeMouseListener(crosshairListener); + removeCrosshair(); + } + } + + @Override + public void addToDataSet(final TimeBlocks list) { + synchronized (list) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + notifySeries(false); + for (final TimeBlock block : list) { + addTimeBlock(block); + } + if(showMovingAverage){ + movingAveragePanel.updateMovingAverageDataset(); + } + notifySeries(true); + refreshGUI(); + } + }); + } + } + + protected abstract void addTimeBlock(final TimeBlock block); + + protected void populateSeriesPanel(int seriesIndex, String seriesTitle) { + XYItemRenderer baseRenderer = chart.getXYPlot().getRenderer(); + seriesPanel.addSeries(baseRenderer, seriesIndex, seriesTitle); + + if (showMovingAverage) { + XYItemRenderer renderer = chart.getXYPlot().getRenderer(1); + renderer.setSeriesPaint(seriesIndex, ((Color) baseRenderer.getItemPaint(seriesIndex, 0)).darker().darker()); + renderer.setSeriesStroke(seriesIndex, new BasicStroke(1)); + seriesPanel.addMovingAverageSeries(renderer, seriesIndex, seriesTitle); + } + } + + @Override + public void clearData() { + notifySeries(false); + clearDataset(); + clearMovingAverageDataset(); + notifySeries(true); + removeCrosshair(); + chartPanel.restoreAutoDomainBounds(); + } + + protected abstract void clearDataset(); + + private void clearMovingAverageDataset() { + for (int i = 0; i < movingAverageDataSet.getSeriesCount(); i++) { + movingAverageDataSet.getSeries(i).clear(); + } + } + + protected void notifySeries(boolean notify) { + dataset.setNotify(notify); + movingAverageDataSet.setNotify(notify); + } + + protected void refreshGUI() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + seriesPanel.revalidate(); + chartPanel.revalidate(); + chartPanel.repaint(); + } + }); + } + + private void removeCrosshair() { + ((Crosshair) overlay.getDomainCrosshairs().get(0)).setValue(Double.NaN); + ((Crosshair) overlay.getRangeCrosshairs().get(0)).setValue(Double.NaN); + } + + @Override + public void stop() { + } + + private class CrosshairListener extends MouseAdapter implements ChartMouseListener { + + @Override + public void chartMouseClicked(ChartMouseEvent arg0) { + } + + @Override + public void chartMouseMoved(ChartMouseEvent event) { + if (chart.getPlot() instanceof XYPlot) { + XYPlot plot = (XYPlot) chart.getPlot(); + double x = plot.getDomainAxis().java2DToValue(event.getTrigger().getX(), chartPanel.getScreenDataArea(), RectangleEdge.BOTTOM); + // make the crosshairs disappear if the mouse is out of range + if (!plot.getDomainAxis().getRange().contains(x)) { + x = Double.NaN; + } + ((Crosshair) overlay.getDomainCrosshairs().get(0)).setValue(x); + + double y = DatasetUtilities.findYValue(dataset, getClosestSeriesIndex(x, event.getTrigger().getY()), x); + ((Crosshair) overlay.getRangeCrosshairs().get(0)).setValue(y); + } + + } + + private int getClosestSeriesIndex(double x, int compare) { + int series = 0; + double distance = Double.MAX_VALUE; + for (int i = 0; i < dataset.getSeriesCount(); i++) { + double y = DatasetUtilities.findYValue(dataset, i, x); + double toCompare = ((XYPlot) chart.getPlot()).getRangeAxis().java2DToValue(compare, chartPanel.getScreenDataArea(), ((XYPlot) chart.getPlot()).getRangeAxisEdge()); + + if (Math.abs(y - toCompare) < distance) { + distance = Math.abs(y - toCompare); + series = i; + } + } + + return series; + } + + @Override + public void mouseExited(MouseEvent e) { + removeCrosshair(); + } + + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/actions/ExportToCSVAction.java b/src/eu/engys/gui/solver/postprocessing/panels/actions/ExportToCSVAction.java new file mode 100644 index 0000000..9415791 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/actions/ExportToCSVAction.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; + +import eu.engys.gui.solver.postprocessing.panels.utils.SelectedViewProvider; +import eu.engys.util.ui.ResourcesUtil; + +public class ExportToCSVAction extends AbstractAction { + + private static final Icon CSV_ICON = ResourcesUtil.getIcon("file"); + private SelectedViewProvider selector; + + public ExportToCSVAction(SelectedViewProvider selector) { + super("", CSV_ICON); + this.selector = selector; + putValue(SHORT_DESCRIPTION, "Export chart data in CSV format"); + } + + @Override + public void actionPerformed(ActionEvent e) { + selector.getSelectedView().exportToCSV(); + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/actions/ExportToExcelAction.java b/src/eu/engys/gui/solver/postprocessing/panels/actions/ExportToExcelAction.java new file mode 100644 index 0000000..ab6ec01 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/actions/ExportToExcelAction.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; + +import eu.engys.gui.solver.postprocessing.panels.utils.SelectedViewProvider; +import eu.engys.util.ui.ResourcesUtil; + +public class ExportToExcelAction extends AbstractAction { + + private SelectedViewProvider selector; + private static final Icon EXCEL_ICON = ResourcesUtil.getIcon("file.excel"); + + public ExportToExcelAction(SelectedViewProvider selector) { + super("", EXCEL_ICON); + this.selector = selector; + putValue(SHORT_DESCRIPTION, "Export chart data in Excel format"); + } + + @Override + public void actionPerformed(ActionEvent e) { + selector.getSelectedView().exportToExcel(); + } +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/actions/ExportToPNGAction.java b/src/eu/engys/gui/solver/postprocessing/panels/actions/ExportToPNGAction.java new file mode 100644 index 0000000..d36d294 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/actions/ExportToPNGAction.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; + +import eu.engys.gui.solver.postprocessing.panels.utils.SelectedViewProvider; +import eu.engys.util.ui.ResourcesUtil; + +public class ExportToPNGAction extends AbstractAction { + + private static final Icon PNG_ICON = ResourcesUtil.getIcon("file.png"); + private SelectedViewProvider selector; + + public ExportToPNGAction(SelectedViewProvider selector) { + super("", PNG_ICON); + this.selector = selector; + putValue(SHORT_DESCRIPTION, "Export chart in PNG format"); + } + + @Override + public void actionPerformed(ActionEvent e) { + selector.getSelectedView().exportToPNG(); + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/actions/ShowCrosshairAction.java b/src/eu/engys/gui/solver/postprocessing/panels/actions/ShowCrosshairAction.java new file mode 100644 index 0000000..4581e64 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/actions/ShowCrosshairAction.java @@ -0,0 +1,56 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Icon; + +import eu.engys.core.project.Model; +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObject; +import eu.engys.util.ui.ResourcesUtil; + +public class ShowCrosshairAction extends AbstractAction { + + private static final Icon CROSSHAIR_ICON = ResourcesUtil.getIcon("crosshair.icon"); + private Model model; + + public ShowCrosshairAction(Model model) { + super("", CROSSHAIR_ICON); + this.model = model; + putValue(SHORT_DESCRIPTION, "Show a crosshair over the chart"); + } + + @Override + public void actionPerformed(ActionEvent e) { + boolean visible = ((AbstractButton) e.getSource()).isSelected(); + for (MonitoringFunctionObject fo : model.getMonitoringFunctionObjects()) { + fo.getView().setCrosshairVisibile(visible); + } + } +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/actions/ShowCrosshairForResidualsAction.java b/src/eu/engys/gui/solver/postprocessing/panels/actions/ShowCrosshairForResidualsAction.java new file mode 100644 index 0000000..bf89aec --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/actions/ShowCrosshairForResidualsAction.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Icon; + +import eu.engys.gui.solver.postprocessing.panels.residuals.ResidualsView; +import eu.engys.util.ui.ResourcesUtil; + +public class ShowCrosshairForResidualsAction extends AbstractAction { + + private static final Icon CROSSHAIR_ICON = ResourcesUtil.getIcon("crosshair.icon"); + private ResidualsView residualsView; + + public ShowCrosshairForResidualsAction(ResidualsView residualsView) { + super("", CROSSHAIR_ICON); + this.residualsView = residualsView; + putValue(SHORT_DESCRIPTION, "Show a crosshair over the chart"); + } + + @Override + public void actionPerformed(ActionEvent e) { + boolean visible = ((AbstractButton) e.getSource()).isSelected(); + residualsView.setCrosshairVisibile(visible); + } +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/actions/ShowLogFileAction.java b/src/eu/engys/gui/solver/postprocessing/panels/actions/ShowLogFileAction.java new file mode 100644 index 0000000..54d50be --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/actions/ShowLogFileAction.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; + +import eu.engys.gui.solver.postprocessing.panels.utils.SelectedViewProvider; +import eu.engys.util.ui.ResourcesUtil; + +public class ShowLogFileAction extends AbstractAction { + + private static final Icon LOG_FILE_ICON = ResourcesUtil.getIcon("browse.file"); + private SelectedViewProvider selector; + + public ShowLogFileAction(SelectedViewProvider selector) { + super("", LOG_FILE_ICON); + this.selector = selector; + putValue(SHORT_DESCRIPTION, "Open log file"); + } + + @Override + public void actionPerformed(ActionEvent e) { + selector.getSelectedView().showLogFile(); + } +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsChartPanel.java b/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsChartPanel.java new file mode 100644 index 0000000..d99d9fe --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsChartPanel.java @@ -0,0 +1,94 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.residuals; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.axis.LogarithmicAxis; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.data.xy.XYSeries; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlock; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlockUnit; +import eu.engys.gui.solver.postprocessing.data.DoubleListTimeBlockUnit; +import eu.engys.gui.solver.postprocessing.panels.HistoryChartPanel; + +public class ResidualsChartPanel extends HistoryChartPanel { + + public ResidualsChartPanel() { + super("Residuals", null, TIME_LABEL, "", false); + } + + @Override + protected void createChart() { + this.chart = ChartFactory.createXYLineChart("", "", "", dataset, PlotOrientation.VERTICAL, true, true, false); + NumberAxis domainAxis = new NumberAxis(domainAxisLabel); + domainAxis.setAutoRangeIncludesZero(false); + + LogarithmicAxis rangeAxis = new LogarithmicAxis(rangeAxisLabel); + rangeAxis.setExpTickLabelsFlag(true); + + XYPlot xyPlot = chart.getXYPlot(); + xyPlot.setDomainAxis(domainAxis); + xyPlot.setRangeAxis(rangeAxis); + } + + @Override + protected void addTimeBlock(TimeBlock block) { + for (TimeBlockUnit unit : block.getUnitsMap().values()) { + if (unit instanceof DoubleListTimeBlockUnit) { + addTimeUnit(block.getTime(), (DoubleListTimeBlockUnit) unit); + } + } + } + + private void addTimeUnit(double time, DoubleListTimeBlockUnit unit) { + String varName = unit.getVarName(); + if (dataset.getSeriesIndex(varName) == -1) { + XYSeries series = new XYSeries(varName); + dataset.addSeries(series); + populateSeriesPanel(dataset.getSeriesIndex(series.getKey()), series.getKey().toString()); + } + XYSeries xyserie = dataset.getSeries(varName); + DoubleListTimeBlockUnit doubleListUnit = (DoubleListTimeBlockUnit) unit; + for (Double value : doubleListUnit.getValues()) { + if (value > 0) { + xyserie.add(time, value); + } + } + } + + @Override + public void clearData() { + // Chart is recreated everytime so we remove all + dataset.removeAllSeries(); + chartPanel.restoreAutoDomainBounds(); + seriesPanel.clear(); + refreshGUI(); + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsExporter.java b/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsExporter.java new file mode 100644 index 0000000..80dd5a5 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsExporter.java @@ -0,0 +1,193 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.residuals; + +import static eu.engys.core.report.excel.ExcelUtils.addDoubleCell; +import static eu.engys.core.report.excel.ExcelUtils.addHeaderCell; +import static eu.engys.core.report.excel.ExcelUtils.autoSizeColumns; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; + +import au.com.bytecode.opencsv.CSVWriter; +import eu.engys.core.project.system.monitoringfunctionobjects.Parser; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlock; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlockUnit; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.core.report.Exporter; +import eu.engys.gui.solver.postprocessing.data.DoubleListTimeBlockUnit; +import eu.engys.util.progress.ProgressMonitor; + +public class ResidualsExporter extends Exporter { + + public ResidualsExporter(List parsers, ProgressMonitor monitor) { + super(parsers, monitor); + } + + @Override + protected void populateExcelFile(Workbook workbook) throws Exception { + monitor.setIndeterminate(false); + + Parser parser = parsers.get(0); + monitor.info(PARSING_LOG_FILE + parser.getFile(), 1); + parser.init(); + TimeBlocks blocks = parser.updateParsing(); + parser.end(); + + monitor.setTotal(blocks.size()); + monitor.info(POPULATING_SHEET + "Residuals" + DOTS, 1); + addExcelSheet(workbook, blocks); + } + + @Override + protected void populateCSVFile(CSVWriter writer) throws Exception { + monitor.setIndeterminate(false); + + Parser parser = parsers.get(0); + monitor.info(PARSING_LOG_FILE + parser.getFile(), 1); + parser.init(); + TimeBlocks blocks = parser.updateParsing(); + parser.end(); + + monitor.setTotal(blocks.size()); + monitor.info(POPULATING_SHEET + "Residuals" + DOTS, 1); + addCSVSheet(writer, blocks); + } + + /* + * CSV + */ + + private void addCSVSheet(CSVWriter writer, TimeBlocks blocks) { + if (!blocks.isEmpty()) { + addCSVHeaderRow(writer, blocks.get(0)); + addCSVTableRows(writer, blocks); + } + } + + private void addCSVHeaderRow(CSVWriter writer, TimeBlock firstTimeBlock) { + List headerRow = new LinkedList<>(); + headerRow.add("Time"); + + Map unitsMap = firstTimeBlock.getUnitsMap(); + for (String var : unitsMap.keySet()) { + DoubleListTimeBlockUnit unit = (DoubleListTimeBlockUnit) unitsMap.get(var); + if (unit.getValues().size() == 1) { + headerRow.add(var); + } else { + for (int i = 0; i < unit.getValues().size(); i++) { + headerRow.add(var + i); + } + } + } + + writer.writeNext(headerRow.toArray(new String[0])); + } + + private void addCSVTableRows(CSVWriter writer, TimeBlocks blocks) { + List tableRows = new LinkedList<>(); + + for (int i = 0; i < blocks.size(); i++) { + TimeBlock block = blocks.get(i); + + List row = new LinkedList<>(); + row.add(String.valueOf(block.getTime())); + + Map unitsMap = block.getUnitsMap(); + for (String var : unitsMap.keySet()) { + DoubleListTimeBlockUnit unit = (DoubleListTimeBlockUnit) unitsMap.get(var); + for (int j = 0; j < unit.getValues().size(); j++) { + row.add(String.valueOf(unit.getValues().get(j))); + } + } + tableRows.add(row.toArray(new String[0])); + + monitor.setCurrent(null, monitor.getCurrent() + 1); + } + writer.writeAll(tableRows); + } + + /* + * Excel + */ + + private void addExcelSheet(Workbook workbook, TimeBlocks blocks) { + Sheet sheet = workbook.createSheet("Residuals"); + if (!blocks.isEmpty()) { + addExcelHeaderRow(workbook, sheet, blocks.get(0)); + addExcelTableRows(sheet, blocks); + autoSizeColumns(sheet); + } + } + + private void addExcelHeaderRow(Workbook workbook, Sheet sheet, TimeBlock firstTimeBlock) { + Row headerRow = sheet.createRow(0); + addHeaderCell(workbook, headerRow, 0, "Time"); + + Map unitsMap = firstTimeBlock.getUnitsMap(); + int counter = 1; + for (String var : unitsMap.keySet()) { + DoubleListTimeBlockUnit unit = (DoubleListTimeBlockUnit) unitsMap.get(var); + if (unit.getValues().size() == 1) { + addHeaderCell(workbook, headerRow, counter, var); + counter++; + } else { + for (int i = 0; i < unit.getValues().size(); i++) { + addHeaderCell(workbook, headerRow, counter, var + i); + counter++; + } + } + } + } + + private void addExcelTableRows(Sheet sheet, TimeBlocks blocks) { + for (int i = 0; i < blocks.size(); i++) { + TimeBlock block = blocks.get(i); + + // i+1 because row 0 is for the header + Row row = sheet.createRow(i + 1); + row.createCell(0).setCellValue(block.getTime()); + + Map unitsMap = block.getUnitsMap(); + int counter = 0; + for (String var : unitsMap.keySet()) { + DoubleListTimeBlockUnit unit = (DoubleListTimeBlockUnit) unitsMap.get(var); + for (int j = 0; j < unit.getValues().size(); j++) { + addDoubleCell(sheet, i, counter, unit.getValues().get(j)); + counter++; + } + } + + monitor.setCurrent(null, monitor.getCurrent() + 1); + } + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsPanel.java b/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsPanel.java new file mode 100644 index 0000000..b7db9fd --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsPanel.java @@ -0,0 +1,99 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.residuals; + +import javax.inject.Inject; +import javax.swing.JComponent; +import javax.swing.JToggleButton; + +import eu.engys.core.controller.Controller; +import eu.engys.core.project.Model; +import eu.engys.core.project.system.monitoringfunctionobjects.ParserView; +import eu.engys.gui.DefaultGUIPanel; +import eu.engys.gui.solver.postprocessing.panels.actions.ExportToCSVAction; +import eu.engys.gui.solver.postprocessing.panels.actions.ExportToExcelAction; +import eu.engys.gui.solver.postprocessing.panels.actions.ExportToPNGAction; +import eu.engys.gui.solver.postprocessing.panels.actions.ShowCrosshairForResidualsAction; +import eu.engys.gui.solver.postprocessing.panels.actions.ShowLogFileAction; +import eu.engys.gui.solver.postprocessing.panels.utils.SelectedViewProvider; +import eu.engys.util.ui.UiUtil; + +public class ResidualsPanel extends DefaultGUIPanel implements SelectedViewProvider { + + private static final String TITLE = "Residuals"; + private ResidualsView residualsView; + private JToggleButton showCrosshairButton; + + @Inject + public ResidualsPanel(Model model, Controller controller) throws Exception { + super(TITLE, model); + this.residualsView = (ResidualsView) controller.getResidualView(); + } + + @Override + protected JComponent layoutComponents() { + populateToolbar(); + return residualsView.getPanel(); + } + + @Override + public void stop() { + super.stop(); + stopCrosshair(); + } + + private void stopCrosshair() { + if (showCrosshairButton.isSelected()) { + showCrosshairButton.doClick(); + } + } + + private void populateToolbar() { + titleToolbar.add(showCrosshairButton = UiUtil.createToolBarToggleButton(new ShowCrosshairForResidualsAction(residualsView), true)); + titleToolbar.addSeparator(); + titleToolbar.add(UiUtil.createToolBarButton(new ShowLogFileAction(this))); + titleToolbar.add(UiUtil.createToolBarButton(new ExportToExcelAction(this))); + titleToolbar.add(UiUtil.createToolBarButton(new ExportToCSVAction(this))); + titleToolbar.add(UiUtil.createToolBarButton(new ExportToPNGAction(this))); + + } + + @Override + public ParserView getSelectedView() { + return residualsView; + } + + @Override + public JComponent getPanel() { + return this; + } + + @Override + public void load() { + residualsView.reset(); + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsView.java b/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsView.java new file mode 100644 index 0000000..cf8deff --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/residuals/ResidualsView.java @@ -0,0 +1,101 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.residuals; + +import java.util.ArrayList; +import java.util.List; + +import eu.engys.core.project.Model; +import eu.engys.core.project.system.monitoringfunctionobjects.Parser; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.core.report.Exporter; +import eu.engys.gui.solver.postprocessing.panels.AbstractParserView; +import eu.engys.gui.solver.postprocessing.parsers.ResidualsParser; +import eu.engys.gui.solver.postprocessing.parsers.ResidualsUtils; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.UiUtil; + +public class ResidualsView extends AbstractParserView { + + private ResidualsChartPanel chartPanel; + + // public static void main(String[] args) { + // new HelyxLookAndFeel().init(); + // Model model = new Model(); + // model.init(); + // ResidualsView panel = new ResidualsView(model, null); + // JFrame f = UiUtil.defaultTestFrame("a", panel); + // f.setSize(600, 500); + // f.setVisible(true); + // } + + public ResidualsView(Model model, ProgressMonitor monitor) { + super(model, null, monitor); + this.chartPanel = new ResidualsChartPanel(); + chartPanel.layoutComponents(); + + tabbedPane.addTab("Residuals", chartPanel); + UiUtil.setOneTabHide(tabbedPane); + } + + @Override + public List gerReportParsersList() { + List reportParsersList = new ArrayList<>(); + reportParsersList.add(new ResidualsParser(ResidualsUtils.fileToParse(model))); + return reportParsersList; + } + + @Override + public Exporter getExporter() { + return new ResidualsExporter(gerReportParsersList(), monitor); + } + + @Override + public String getKey() { + return ResidualsParser.KEY; + } + + @Override + public void clearData() { + chartPanel.clearData(); + } + + @Override + public void handleFunctionObjectChanged() { + } + + @Override + public void stop() { + } + + @Override + public void updateParsing(List newTimeBlocks) { + if (!newTimeBlocks.isEmpty()) { + chartPanel.addToDataSet(newTimeBlocks.get(0)); + } + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/utils/MovingAverageCalculator.java b/src/eu/engys/gui/solver/postprocessing/panels/utils/MovingAverageCalculator.java new file mode 100644 index 0000000..b8d963d --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/utils/MovingAverageCalculator.java @@ -0,0 +1,161 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.utils; + +import org.jfree.data.xy.AbstractIntervalXYDataset; +import org.jfree.data.xy.XYDataItem; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import org.jfree.data.xy.YIntervalDataItem; +import org.jfree.data.xy.YIntervalSeries; +import org.jfree.data.xy.YIntervalSeriesCollection; + +public class MovingAverageCalculator { + + public static void calculate(AbstractIntervalXYDataset sourceDataset, AbstractIntervalXYDataset movingAverageDataSet, MovingAverageType type, int period) { + if (type.isTrailing()) { + if(sourceDataset instanceof XYSeriesCollection){ + calculateTrailing((XYSeriesCollection)sourceDataset, (XYSeriesCollection)movingAverageDataSet, period); + } else if(sourceDataset instanceof YIntervalSeriesCollection){ + calculateTrailing((YIntervalSeriesCollection)sourceDataset, (XYSeriesCollection)movingAverageDataSet, period); + } + } else { + if(sourceDataset instanceof XYSeriesCollection){ + calculateCentral((XYSeriesCollection)sourceDataset, (XYSeriesCollection)movingAverageDataSet, period); + } else if(sourceDataset instanceof YIntervalSeriesCollection){ + calculateCentral((YIntervalSeriesCollection)sourceDataset, (XYSeriesCollection)movingAverageDataSet, period); + } + } + } + + /* + * XY SERIES + */ + + // Sum of the left N-values, divided by N + private static void calculateTrailing(XYSeriesCollection sourceDataset, XYSeriesCollection movingAverageDataSet, int period) { + movingAverageDataSet.removeAllSeries(); + + for (int i = 0; i < sourceDataset.getSeriesCount(); i++) { + XYSeries origSeries = sourceDataset.getSeries(i); + XYSeries maSeries = new XYSeries(origSeries.getKey() + "-MAVG"); + + for (int j = 0; j < origSeries.getItemCount(); j++) { + XYDataItem origItem = origSeries.getDataItem(j); + if (j - (period - 1) < 0) { + // do nothing + } else { + double yValue = 0; + for (int k = (j - (period - 1)); k <= j; k++) { + yValue += origSeries.getDataItem(k).getYValue(); + } + maSeries.add(origItem.getXValue(), (yValue / period)); + } + } + movingAverageDataSet.addSeries(maSeries); + } + } + + // Sum of the N/2 left-values and of the N/2 right-values, divided by N + private static void calculateCentral(XYSeriesCollection sourceDataset, XYSeriesCollection movingAverageDataSet, int period) { + movingAverageDataSet.removeAllSeries(); + for (int i = 0; i < sourceDataset.getSeriesCount(); i++) { + XYSeries origSeries = sourceDataset.getSeries(i); + XYSeries maSeries = new XYSeries(origSeries.getKey() + "-MAVG"); + + int limit = (int) Math.floor(period / 2); + + for (int j = 0; j < origSeries.getItemCount(); j++) { + XYDataItem origItem = origSeries.getDataItem(j); + if (j - limit < 0) { + // do nothing + } else if (j + limit >= origSeries.getItemCount()) { + // do nothing + } else { + double yValue = 0; + for (int k = (j - limit); k <= (j + limit); k++) { + yValue += origSeries.getDataItem(k).getYValue(); + } + maSeries.add(origItem.getXValue(), (yValue / period)); + } + } + movingAverageDataSet.addSeries(maSeries); + } + } + + /* + * YSERIES + */ + + private static void calculateTrailing(YIntervalSeriesCollection sourceDataset, XYSeriesCollection movingAverageDataSet, int period) { + movingAverageDataSet.removeAllSeries(); + + for (int i = 0; i < sourceDataset.getSeriesCount(); i++) { + YIntervalSeries origSeries = sourceDataset.getSeries(i); + XYSeries maSeries = new XYSeries(origSeries.getKey() + "-MAVG"); + + for (int j = 0; j < origSeries.getItemCount(); j++) { + YIntervalDataItem origItem = (YIntervalDataItem) origSeries.getDataItem(j); + if (j - (period - 1) < 0) { + // do nothing + } else { + double yValue = 0; + for (int k = (j - (period - 1)); k <= j; k++) { + yValue += ((YIntervalDataItem) origSeries.getDataItem(k)).getYValue(); + } + maSeries.add(origItem.getX().doubleValue(), (yValue / period)); + } + } + movingAverageDataSet.addSeries(maSeries); + } + } + + private static void calculateCentral(YIntervalSeriesCollection sourceDataset, XYSeriesCollection movingAverageDataSet, int period) { + movingAverageDataSet.removeAllSeries(); + for (int i = 0; i < sourceDataset.getSeriesCount(); i++) { + YIntervalSeries origSeries = sourceDataset.getSeries(i); + XYSeries maSeries = new XYSeries(origSeries.getKey() + "-MAVG"); + + int limit = (int) Math.floor(period / 2); + + for (int j = 0; j < origSeries.getItemCount(); j++) { + YIntervalDataItem origItem = (YIntervalDataItem) origSeries.getDataItem(j); + if (j - limit < 0) { + // do nothing + } else if (j + limit >= origSeries.getItemCount()) { + // do nothing + } else { + double yValue = 0; + for (int k = (j - limit); k <= (j + limit); k++) { + yValue += ((YIntervalDataItem) origSeries.getDataItem(k)).getYValue(); + } + maSeries.add(origItem.getX().doubleValue(), (yValue / period)); + } + } + movingAverageDataSet.addSeries(maSeries); + } + } +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/utils/MovingAveragePanel.java b/src/eu/engys/gui/solver/postprocessing/panels/utils/MovingAveragePanel.java new file mode 100644 index 0000000..2934ed8 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/utils/MovingAveragePanel.java @@ -0,0 +1,105 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.utils; + +import java.awt.BorderLayout; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.JComboBox; +import javax.swing.JPanel; + +import org.jfree.data.xy.AbstractIntervalXYDataset; + +import eu.engys.util.ui.ComponentsFactory; +import eu.engys.util.ui.builder.PanelBuilder; +import eu.engys.util.ui.textfields.IntegerField; + +public class MovingAveragePanel extends JPanel { + + private JComboBox type; + private IntegerField periodField; + + private AbstractIntervalXYDataset sourceDataSet; + private AbstractIntervalXYDataset movingAverageDataset; + + private MovingAverageType movingAverageType = MovingAverageType.TRAILING; + private int movingAveragePeriod = 1; + + public MovingAveragePanel(AbstractIntervalXYDataset sourceDataSet, AbstractIntervalXYDataset movingAverageDataSet) { + super(new BorderLayout()); + this.sourceDataSet = sourceDataSet; + this.movingAverageDataset = movingAverageDataSet; + layoutComponents(); + } + + private void layoutComponents() { + PanelBuilder builder = new PanelBuilder(); + + type = ComponentsFactory.selectField(new String[] { MovingAverageType.TRAILING.getLabel(), MovingAverageType.CENTERED.getLabel() }); + type.setPrototypeDisplayValue(MovingAverageType.CENTERED.getLabel()); + type.addPropertyChangeListener(new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + updateMovingAverageType((String) type.getSelectedItem()); + } + } + }); + type.setSelectedItem(movingAverageType.getLabel()); + builder.addComponent("Type", type); + + periodField = ComponentsFactory.intField(1, Integer.MAX_VALUE); + periodField.addPropertyChangeListener(new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + updateMovingAveragePeriod(periodField.getIntValue()); + } + } + }); + builder.addComponent("Period", periodField); + + add(builder.removeMargins().getPanel(), BorderLayout.CENTER); + } + + private void updateMovingAveragePeriod(int period) { + this.movingAveragePeriod = period; + updateMovingAverageDataset(); + } + + private void updateMovingAverageType(String label) { + this.movingAverageType = MovingAverageType.getTypeByLabel(label); + updateMovingAverageDataset(); + } + + public void updateMovingAverageDataset() { + MovingAverageCalculator.calculate(sourceDataSet, movingAverageDataset, movingAverageType, movingAveragePeriod); + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/utils/MovingAverageType.java b/src/eu/engys/gui/solver/postprocessing/panels/utils/MovingAverageType.java new file mode 100644 index 0000000..52eef9b --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/utils/MovingAverageType.java @@ -0,0 +1,57 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.utils; + +public enum MovingAverageType { + + TRAILING("Trailing"), CENTERED("Centered"); + + private String label; + + private MovingAverageType(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + public boolean isTrailing() { + return equals(TRAILING); + } + + public static MovingAverageType getTypeByLabel(String label) { + MovingAverageType[] all = values(); + for (MovingAverageType type : all) { + if (type.getLabel().equals(label)) { + return type; + } + } + return null; + + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/utils/SelectedViewProvider.java b/src/eu/engys/gui/solver/postprocessing/panels/utils/SelectedViewProvider.java new file mode 100644 index 0000000..434bb7d --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/utils/SelectedViewProvider.java @@ -0,0 +1,32 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.utils; + +import eu.engys.core.project.system.monitoringfunctionobjects.ParserView; + +public interface SelectedViewProvider { + ParserView getSelectedView(); +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/utils/SeriesPanel.java b/src/eu/engys/gui/solver/postprocessing/panels/utils/SeriesPanel.java new file mode 100644 index 0000000..b8b05a8 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/utils/SeriesPanel.java @@ -0,0 +1,136 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.utils; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JPanel; + +import org.jfree.chart.renderer.xy.XYItemRenderer; + +import eu.engys.util.ui.ComponentsFactory; + +public class SeriesPanel extends JPanel { + + private Map seriesVisibility = new HashMap<>(); + private Map movingAverageSeriesVisibility = new HashMap<>(); + private JPanel seriesPanel; + private JPanel seriesAveragePanel; + + public SeriesPanel(JPanel movingAveragePanel) { + super(); + seriesPanel = new JPanel(new GridBagLayout()); + seriesAveragePanel = new JPanel(new GridBagLayout()); + + if (movingAveragePanel != null) { + setLayout(new GridLayout(2, 1)); + + JPanel movingAveragepanel = new JPanel(new BorderLayout()); + movingAveragepanel.setBorder(BorderFactory.createTitledBorder("Moving Average")); + movingAveragepanel.add(movingAveragePanel, BorderLayout.NORTH); + movingAveragepanel.add(seriesAveragePanel, BorderLayout.CENTER); + + seriesPanel.setBorder(BorderFactory.createTitledBorder("Series")); + add(seriesPanel); + add(movingAveragepanel); + } else { + setLayout(new BorderLayout()); + add(seriesPanel, BorderLayout.CENTER); + } + } + + public void clear() { + // do not clear visibility maps + seriesPanel.removeAll(); + seriesAveragePanel.removeAll(); + } + + public void addSeries(final XYItemRenderer renderer, final int seriesIndex, final String label) { + boolean visible = true; + if (seriesVisibility.containsKey(label)) { + visible = seriesVisibility.get(label); + } else { + seriesVisibility.put(label, visible); + } + final JCheckBox checkBox = ComponentsFactory.checkField(label, visible, getColorOfSeries(renderer, seriesIndex)); + checkBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (checkBox.isSelected()) { + seriesVisibility.put(label, true); + renderer.setSeriesVisible(seriesIndex, true, true); + } else { + seriesVisibility.put(label, false); + renderer.setSeriesVisible(seriesIndex, false, true); + } + } + }); + seriesPanel.add(checkBox, new GridBagConstraints(0, seriesIndex, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + } + + public void addMovingAverageSeries(final XYItemRenderer renderer, final int seriesIndex, final String label) { + boolean visible = false; + if (movingAverageSeriesVisibility.containsKey(label)) { + visible = movingAverageSeriesVisibility.get(label); + } else { + movingAverageSeriesVisibility.put(label, visible); + } + final JCheckBox checkBox = ComponentsFactory.checkField(label, visible, getColorOfSeries(renderer, seriesIndex)); + checkBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (checkBox.isSelected()) { + seriesVisibility.put(label, true); + renderer.setSeriesVisible(seriesIndex, true, true); + } else { + seriesVisibility.put(label, false); + renderer.setSeriesVisible(seriesIndex, false, true); + } + } + }); + + seriesAveragePanel.add(checkBox, new GridBagConstraints(0, seriesIndex, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + renderer.setSeriesVisible(seriesIndex, visible, true); + } + + // Used to colour points in the 3D + public static Color getColorOfSeries(XYItemRenderer renderer, int seriesIndex) { + Color colorWithTransparency = (Color) renderer.getItemPaint(seriesIndex, 0); + return new Color(colorWithTransparency.getRed(), colorWithTransparency.getGreen(), colorWithTransparency.getBlue()); + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/panels/utils/WaitLayerUI.java b/src/eu/engys/gui/solver/postprocessing/panels/utils/WaitLayerUI.java new file mode 100644 index 0000000..a8f1875 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/panels/utils/WaitLayerUI.java @@ -0,0 +1,288 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.panels.utils; + +import static java.awt.AlphaComposite.SRC_OVER; +import static java.awt.BasicStroke.CAP_ROUND; +import static java.awt.BasicStroke.JOIN_ROUND; +import static java.awt.RenderingHints.KEY_ANTIALIASING; +import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON; + +import java.awt.AWTEvent; +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.geom.Rectangle2D; +import java.beans.PropertyChangeEvent; + +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JLayer; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.plaf.LayerUI; + +import eu.engys.util.ui.ResourcesUtil; + +public class WaitLayerUI extends LayerUI implements ActionListener { + + private Timer timer; + private int angle; + private UiState state; + private Runnable runnable; + private boolean mouseOver; + + private static final int FPS = 24; + private static final int TICK = 1000 / FPS; + private static final String PROPERTY_NAME = "tick"; + + private static final Icon REFRESH_ICON_GRAY = ResourcesUtil.getIcon("chart.refresh.gray.icon"); + private static final Icon REFRESH_ICON_WHITE = ResourcesUtil.getIcon("chart.refresh.white.icon"); + + public WaitLayerUI(Runnable runnable) { + this.runnable = runnable; + init(); + } + + @Override + public void installUI(JComponent c) { + super.installUI(c); + JLayer jlayer = (JLayer) c; + jlayer.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); + } + + @Override + public void uninstallUI(JComponent c) { + JLayer jlayer = (JLayer) c; + jlayer.setLayerEventMask(0); + super.uninstallUI(c); + } + + public void init() { + changeState(UiState.SHOW_REFRESH); + } + + public void start() { + if (state.isShowingRefreshIcon()) { + timer = new Timer(TICK, this); + timer.start(); + changeState(UiState.SHOW_WHEEL); + } + } + + public void stop() { + if (state.isShowingRefreshIcon() || state.isShowingWheel()) { + changeState(UiState.SHOW_NOTHING); + if (timer != null) { + timer.stop(); + } + } + } + + @Override + public void paint(Graphics g, JComponent c) { + super.paint(g, c); + switch (state) { + case SHOW_REFRESH: + paintRefreshIcon(g, c); + break; + case SHOW_WHEEL: + paintLoadingWheel(g, c); + break; + case SHOW_NOTHING: + break; + default: + break; + } + } + + private void paintRefreshIcon(Graphics g, JComponent c) { + Graphics2D g2 = (Graphics2D) g.create(); + paintBackgroundPanel(g2, c); + paintBackgroundButton(g2, c); + paintRefreshIcon(g2, c); + g2.dispose(); + } + + private void paintLoadingWheel(Graphics g, JComponent c) { + Graphics2D g2 = (Graphics2D) g.create(); + paintBackgroundPanel(g2, c); + paintWheel(g2, c); + g2.dispose(); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (state.isShowingWheel()) { + repaintLayer(); + angle += 3; + if (angle >= 360) { + angle = 0; + } + } + } + + @Override + protected void processMouseEvent(MouseEvent event, JLayer layer) { + if (event.getID() == MouseEvent.MOUSE_RELEASED && isOnRefreshButton(layer, event)) { + if (state.isShowingRefreshIcon()) { + runnable.run(); + } + } + } + + @Override + protected void processMouseMotionEvent(MouseEvent event, JLayer layer) { + if (event.getID() == MouseEvent.MOUSE_MOVED) { + if (isOnRefreshButton(layer, event)) { + mouseOver = true; + } else { + mouseOver = false; + } + repaintLayer(); + } + } + + public boolean isOnRefreshButton(JLayer layer, MouseEvent event) { + ImageIcon imageIcon = (ImageIcon) REFRESH_ICON_GRAY; + int x = (layer.getWidth() - imageIcon.getIconWidth()) / 2; + int y = (layer.getHeight() - imageIcon.getIconHeight()) / 2; + int w = imageIcon.getIconWidth(); + int h = imageIcon.getIconHeight(); + Rectangle2D refreshIconBounds = new Rectangle2D.Double(x, y, w, h); + Point mousePoint = SwingUtilities.convertPoint((Component) event.getSource(), event.getPoint(), layer); + return refreshIconBounds.contains(mousePoint); + } + + private void changeState(UiState state) { + this.state = state; + repaintLayer(); + } + + private void repaintLayer() { + firePropertyChange(PROPERTY_NAME, 0, 1); + } + + @Override + public void applyPropertyChange(PropertyChangeEvent event, JLayer layer) { + if (PROPERTY_NAME.equals(event.getPropertyName())) { + layer.repaint(); + } + } + + /* + * Paint + */ + private void paintRefreshIcon(Graphics2D g2, JComponent c) { + ImageIcon imageGray = (ImageIcon) REFRESH_ICON_GRAY; + ImageIcon imageWhite = (ImageIcon) REFRESH_ICON_WHITE; + int x = ((c.getWidth() - imageGray.getIconWidth()) / 2); + int y = ((c.getHeight() - imageGray.getIconHeight()) / 2); + + if (mouseOver) { + g2.drawImage(imageWhite.getImage(), x, y, null); + } else { + g2.drawImage(imageGray.getImage(), x, y, null); + } + } + + private void paintWheel(Graphics2D g2, JComponent c) { + int cx = c.getWidth() / 2; + int cy = c.getHeight() / 2; + int stroke = 3; + int linesSize = 9; + + g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); + g2.setStroke(new BasicStroke(stroke, CAP_ROUND, JOIN_ROUND)); + g2.setPaint(Color.GRAY.darker()); + g2.rotate(Math.PI * angle / 180, cx, cy); + for (int i = 0; i < 12; i++) { + float scale = (11.0f - (float) i) / 11.0f; + g2.drawLine(cx + linesSize, cy, cx + linesSize * 2, cy); + g2.rotate(-Math.PI / 6, cx, cy); + g2.setComposite(AlphaComposite.getInstance(SRC_OVER, scale)); + } + } + + private void paintBackgroundButton(Graphics2D g2, JComponent c) { + ImageIcon image = (ImageIcon) REFRESH_ICON_GRAY; + int padding = 8; + int x = ((c.getWidth() - image.getIconWidth()) / 2); + int y = ((c.getHeight() - image.getIconHeight()) / 2); + int w = image.getIconWidth(); + int h = image.getIconHeight(); + int roundAngle = image.getIconWidth() / 2; + int grayIntensity = 100; + + g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); + g2.setColor(new Color(grayIntensity, grayIntensity, grayIntensity)); + g2.fillRoundRect(x - padding, y - padding, w + (padding * 2), h + (padding * 2), roundAngle, roundAngle); + } + + private void paintBackgroundPanel(Graphics2D g2, JComponent c) { + int w = c.getWidth(); + int h = c.getHeight(); + + // float alpha = 1.0f; + float alpha = 0.6f; + Color color = new JPanel().getBackground(); + + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + Composite backupComposite = g2.getComposite(); + g2.setColor(color); + g2.setComposite(AlphaComposite.getInstance(SRC_OVER, alpha)); + g2.fillRect(0, 0, w, h); + g2.setComposite(backupComposite); + } + + private enum UiState { + SHOW_REFRESH, SHOW_WHEEL, SHOW_NOTHING; + + public boolean isShowingRefreshIcon() { + return this == SHOW_REFRESH; + } + + public boolean isShowingWheel() { + return this == SHOW_WHEEL; + } + + public boolean isShowingNothing() { + return this == SHOW_NOTHING; + } + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/parsers/AbstractParser.java b/src/eu/engys/gui/solver/postprocessing/parsers/AbstractParser.java new file mode 100644 index 0000000..90da429 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/parsers/AbstractParser.java @@ -0,0 +1,169 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.parsers; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObject; +import eu.engys.core.project.system.monitoringfunctionobjects.Parser; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.util.Util; + +public abstract class AbstractParser implements Parser { + + private static final int MAX_LINES_PARSED_AT_A_TIME = 100_000; + + private static final Logger logger = LoggerFactory.getLogger(AbstractParser.class); + + private boolean isParserInitialised; + private BufferedReader in; + + protected MonitoringFunctionObject functionObject; + + protected File file; + + protected String blockKey; + + private boolean needUpdate; + + public AbstractParser(MonitoringFunctionObject functionObject, File file, String blockKey) { + this.functionObject = functionObject; + this.file = file; + this.blockKey = blockKey; + } + + public AbstractParser(MonitoringFunctionObject functionObject, File file) { + this(functionObject, file, file.getName()); + } + + @Override + public void clear() { + } + + @Override + public void init() { + logger.debug("INIT: {} [{}]", getClass().getSimpleName(), getFile()); + try { + File file = getFile(); + if (file.exists()) { + in = new BufferedReader(new FileReader(file), 2048); + logger.info("{} Parsing file {}", getClass().getCanonicalName(), file); + } + } catch (Exception e) { + logger.warn("INIT PROBLEM: {}", e.getMessage()); + } finally { + isParserInitialised = true; + } + } + + @Override + public TimeBlocks updateParsing() throws Exception { + logger.debug("UPDATE: {} [{}] ", getClass().getSimpleName(), getFile()); + if (in == null && isParserInitialised) { + init(); + } + + if (in != null) { + return parse(); + } + + return new TimeBlocks(blockKey); + } + + @Override + public void end() { + if (in != null) { + logger.debug("END: {} [{}]", getClass().getSimpleName(), getFile()); + try { + in.close(); + } catch (Exception e) { + logger.warn("END PROBLEM: {}", e.getMessage()); + } finally { + in = null; + isParserInitialised = false; + } + } + } + + private TimeBlocks parse() throws IOException { + needUpdate = false; + List newFileLines = updateNewFileLines(); + if (newFileLines.size() > 0) { + TimeBlocks timeBlocks = updateNewTimeBlocks(newFileLines); + removeInconsistentBlocks(timeBlocks); + checkTimeBlockConsistency(timeBlocks); + newFileLines = null; + System.gc(); + + if (needUpdate) { + timeBlocks.addAll(parse()); + } + + return timeBlocks; + } + + return new TimeBlocks(blockKey); + } + + public List updateNewFileLines() throws IOException { + List newFileLines = new ArrayList<>(); + String s = null; + int i = 0; + while ((s = in.readLine()) != null) { + String line = Util.getTrimmedSingleSpaceLine(s); + if (!line.isEmpty()) { + newFileLines.add(line); + i++; + } + if (i == MAX_LINES_PARSED_AT_A_TIME) { + needUpdate = true; + break; + } + } + return newFileLines; + } + + protected void removeInconsistentBlocks(TimeBlocks newTimeBlocks) { + } + + protected abstract TimeBlocks updateNewTimeBlocks(List newFileLines); + + public abstract boolean checkTimeBlockConsistency(TimeBlocks newTimeBlocks); + + @Override + public File getFile() { + return file; + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/parsers/ParserUtils.java b/src/eu/engys/gui/solver/postprocessing/parsers/ParserUtils.java new file mode 100644 index 0000000..185e7f1 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/parsers/ParserUtils.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.parsers; + +import org.slf4j.Logger; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlock; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; + +public class ParserUtils { + + public static boolean checkTimeBlockConsistency(TimeBlocks newTimeBlocks, int variablesSize, Logger logger) { + if(newTimeBlocks.isEmpty() || variablesSize < 0){ + return true; + } + for (TimeBlock timeBlock : newTimeBlocks) { + if(timeBlock.getSize() < variablesSize){ + logger.error("The number of units is smaller than the number of variables : {} < {}", timeBlock.getSize(), variablesSize); + return false; + } + if(timeBlock.getSize() > variablesSize){ + logger.error("The number of units is bigger than the number of variables : {} > {}", timeBlock.getSize(), variablesSize); + return false; + } + } + return true; + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/parsers/ResidualsParser.java b/src/eu/engys/gui/solver/postprocessing/parsers/ResidualsParser.java new file mode 100644 index 0000000..3bd9109 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/parsers/ResidualsParser.java @@ -0,0 +1,234 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.parsers; + +import java.io.File; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlock; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlockUnit; +import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks; +import eu.engys.gui.solver.postprocessing.data.DoubleListTimeBlockUnit; + +public class ResidualsParser extends AbstractParser { + + private static final Logger logger = LoggerFactory.getLogger(ResidualsParser.class); + public static final String KEY = "residuals"; + + private static final String CHECK_STRING1 = ", Initial residual = "; + private static final String CHECK_STRING2 = ", Final residual"; + private static final String CHECK_STRING3 = "Solving for "; + private static final String ILAMBDA = "ILambda"; + public static final String TIME_PREFIX = "Time = "; + + // COUPLED + private static final String TIME_PREFIX_COUPLED = "PHYSICAL TIME = "; + private static final String U_MOM = "U-Mom"; + private static final String V_MOM = "V-Mom"; + private static final String W_MOM = "W-Mom"; + private static final String P_MASS = "p-Mass"; + private static final String K_EQN = "K-Eqn"; + private static final String OMEGA_EQN = "Omega-Eqn"; + private static final String EPSILON_EQN = "Epsilon-Eqn"; + + private TimeBlock incompleteBlock;// from previous parsing + + private int timeBlockSize = -1; + + public ResidualsParser(File file) { + super(null, file); + this.incompleteBlock = null; + this.timeBlockSize = -1; + } + + @Override + public String getKey() { + return KEY; + } + + @Override + public void clear() { + super.clear(); + this.timeBlockSize = -1; + this.incompleteBlock = null; + } + + @Override + public TimeBlocks updateNewTimeBlocks(List newFileLines) { + // newTimeBlocks.clear(); + TimeBlocks newTimeBlocks = new TimeBlocks(blockKey); + + if (incompleteBlock != null) { + newTimeBlocks.add(incompleteBlock); + incompleteBlock = null; + } + for (String row : newFileLines) { + if (isValidTimeRow(row)) { + TimeBlock timeBlock = new TimeBlock(Double.parseDouble(extractTimeValue(row))); + newTimeBlocks.add(timeBlock); + } else if (newTimeBlocks.size() > 0 && isValidDataRow(row)) { + String extractVarName = extractVarName(row); + TimeBlock lastTimeBlock = newTimeBlocks.getLast(); + Map unitsMap = lastTimeBlock.getUnitsMap(); + if (!unitsMap.containsKey(extractVarName)) { + unitsMap.put(extractVarName, new DoubleListTimeBlockUnit(extractVarName)); + } + DoubleListTimeBlockUnit unit = (DoubleListTimeBlockUnit) unitsMap.get(extractVarName); + unit.getValues().add(extractInitialResidual(row)); + } + } + + return newTimeBlocks; + } + + public boolean checkTimeBlockConsistency(TimeBlocks newTimeBlocks) { + return ParserUtils.checkTimeBlockConsistency(newTimeBlocks, timeBlockSize, logger); + } + + @Override + public void removeInconsistentBlocks(TimeBlocks newTimeBlocks) { + boolean timeBlockSizeNotSet = timeBlockSize == -1; + if (newTimeBlocks.size() == 0) { + return; + } else { + if (newTimeBlocks.size() == 1 && timeBlockSizeNotSet) { + // E' il primo blocco in assoluto e non so se e' completo + this.incompleteBlock = newTimeBlocks.removeLast(); + return; + } else { + // Ho piu' di un blocco (quindi almeno il primo e' completo) + // Oppure ho un blocco solo ma non e' il primo (lo capisco dal + // fatto che timeBlockSize e' settata) + + if (timeBlockSizeNotSet) { + timeBlockSize = newTimeBlocks.get(0).getUnitsMap().size(); + } + + if (lastBlockIsIncomplete(newTimeBlocks)) { + this.incompleteBlock = newTimeBlocks.removeLast(); + logger.debug("Block {} is smaller than it should: {} < {} and will be reprocessed", incompleteBlock.getTime(), incompleteBlock.getUnitsMap().size(), timeBlockSize); + } else if (lastBlockIsOK(newTimeBlocks)) { + /* is OK */ + } else { + logger.debug("Block {} is bigger than it should: {} > {}", newTimeBlocks.getLast().getTime(), newTimeBlocks.getLast().getUnitsMap().size(), timeBlockSize); + } + } + } + } + + private boolean lastBlockIsIncomplete(TimeBlocks newTimeBlocks) { + TimeBlock lastBlock = newTimeBlocks.getLast(); + return lastBlock.getUnitsMap().size() < timeBlockSize; + } + + private boolean lastBlockIsOK(TimeBlocks newTimeBlocks) { + TimeBlock lastBlock = newTimeBlocks.getLast(); + return lastBlock.getUnitsMap().size() == timeBlockSize; + } + + @Override + public boolean isValidTimeRow(String row) { + boolean isResidualsTimeRow = row.startsWith(TIME_PREFIX); + boolean isCoupledResidualsTimeRow = row.startsWith(TIME_PREFIX_COUPLED); + return isResidualsTimeRow || isCoupledResidualsTimeRow; + } + + @Override + public boolean isValidDataRow(String row) { + return isValidResidualsDataRow(row) || isValidCoupledResidualsDataRow(row); + } + + private boolean isValidResidualsDataRow(String row) { + return row.contains(CHECK_STRING1) && row.contains(CHECK_STRING2) && row.contains(CHECK_STRING3) && !row.contains(ILAMBDA); + } + + private boolean isValidCoupledResidualsDataRow(String row) { + return row.contains(U_MOM) || row.contains(V_MOM) || row.contains(W_MOM) || row.contains(P_MASS) || row.contains(K_EQN) || row.contains(OMEGA_EQN) || row.contains(EPSILON_EQN); + } + + public String extractTimeValue(String row) { + if (row.startsWith(TIME_PREFIX)) { + return row.substring(row.indexOf(TIME_PREFIX) + TIME_PREFIX.length()); + } else if (row.startsWith(TIME_PREFIX_COUPLED)) { + return row.substring(row.indexOf(TIME_PREFIX_COUPLED) + TIME_PREFIX_COUPLED.length()); + } + return ""; + } + + public String extractVarName(String row) { + if (isValidResidualsDataRow(row)) { + return row.substring(row.indexOf(CHECK_STRING3) + CHECK_STRING3.length(), row.indexOf(CHECK_STRING1)); + } else if (isValidCoupledResidualsDataRow(row)) { + if (row.contains(U_MOM)) { + return "Ux"; + } else if (row.contains(V_MOM)) { + return "Uy"; + } else if (row.contains(W_MOM)) { + return "Uz"; + } else if (row.contains(P_MASS)) { + return "p"; + } else if (row.contains(K_EQN)) { + return "k"; + } else if (row.contains(OMEGA_EQN)) { + return "omega"; + } else if (row.contains(EPSILON_EQN)) { + return "epsilon"; + } else { + return ""; + } + } else { + return ""; + } + } + + public Double extractInitialResidual(String row) { + if (isValidResidualsDataRow(row)) { + return Double.parseDouble(row.substring(row.indexOf(CHECK_STRING1) + CHECK_STRING1.length(), row.indexOf(CHECK_STRING2))); + } else if (isValidCoupledResidualsDataRow(row)) { + // the value is beetween the 4th and 5th "|" + int initialDelimiter = StringUtils.ordinalIndexOf(row, "|", 4); + int finalDelimiter = StringUtils.ordinalIndexOf(row, "|", 5); + String stringValue = row.substring(initialDelimiter + 1, finalDelimiter).trim(); + return Double.parseDouble(stringValue); + } + return 0.0; + } + + // For test purpose only + public void setIncompleteBlock(TimeBlock incompleteBlock) { + this.incompleteBlock = incompleteBlock; + } + + public void setTimeBlockSize(int timeBlockSize) { + this.timeBlockSize = timeBlockSize; + } + +} diff --git a/src/eu/engys/gui/solver/postprocessing/parsers/ResidualsUtils.java b/src/eu/engys/gui/solver/postprocessing/parsers/ResidualsUtils.java new file mode 100644 index 0000000..5a05f60 --- /dev/null +++ b/src/eu/engys/gui/solver/postprocessing/parsers/ResidualsUtils.java @@ -0,0 +1,61 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.solver.postprocessing.parsers; + +import java.io.File; +import java.nio.file.Paths; + +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.util.IOUtils; + +public class ResidualsUtils { + + public static void clearLogFile(Model model) { + File logFile = fileToParse(model); + if (logFile != null && logFile.exists()) { + IOUtils.clearFile(logFile); + } + } + + public static File fileToParse(Model model) { + String logFile = model.getSolverModel().getLogFile(); + if (logFile.isEmpty()) { + logFile = guessLogFile(model); + } + return Paths.get(model.getProject().getBaseDir().getAbsolutePath(), openFOAMProject.LOG, logFile).toFile(); + + } + + private static String guessLogFile(Model model) { + String application = model.getState().getSolver().getName(); + if (application != null && !application.isEmpty()) { + return application + ".log"; + } + return "none.log"; + } + +} diff --git a/src/eu/engys/gui/tree/AbstractSelectionHandler.java b/src/eu/engys/gui/tree/AbstractSelectionHandler.java new file mode 100644 index 0000000..fcb7859 --- /dev/null +++ b/src/eu/engys/gui/tree/AbstractSelectionHandler.java @@ -0,0 +1,47 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.tree; + + +public abstract class AbstractSelectionHandler implements SelectionHandler { + + private boolean enabled = true; + @Override + public void enable() { + this.enabled = true; + } + + @Override + public void disable() { + this.enabled = false; + } + + @Override + public boolean isEnabled() { + return enabled; + } + +} diff --git a/src/eu/engys/gui/tree/DefaultTreeNodeManager.java b/src/eu/engys/gui/tree/DefaultTreeNodeManager.java new file mode 100644 index 0000000..bb59bb3 --- /dev/null +++ b/src/eu/engys/gui/tree/DefaultTreeNodeManager.java @@ -0,0 +1,118 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.tree; + +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.MutableTreeNode; + +import eu.engys.core.project.Model; +import eu.engys.gui.GUIPanel; + +public class DefaultTreeNodeManager implements TreeNodeManager { + + protected DefaultMutableTreeNode root; + protected Model model; + private Tree tree; + protected Map nodeMap; + + public DefaultTreeNodeManager(Model model, GUIPanel guiPanel) { + this.model = model; + this.nodeMap = new HashMap(); + this.root = new DefaultMutableTreeNode(guiPanel); + } + + @Override + public void update(Observable o, Object arg) { + } + + @Override + public void clear() { + } + + @Override + public DefaultMutableTreeNode getRoot() { + return root; + } + + @Override + public void setTree(Tree tree) { + this.tree = tree; + } + + @Override + public Tree getTree() { + return tree; + } + + @Override + public DefaultTreeCellRenderer getRenderer() { + return null; + } + + @Override + public SelectionHandler getSelectionHandler() { + return null; + } + + @Override + public PopUpBuilder getPopUpBuilder() { + return null; + } + + @Override + public Class getRendererClass() { + return null; + } + + protected void treeChanged(DefaultMutableTreeNode node) { + if (tree != null) { + int[] childIndices = new int[node.getChildCount()]; + for (int i = 0; i < childIndices.length; i++) { + childIndices[i] = node.getIndex(node.getChildAt(i)); + } + getTree().getModel().reload(node); + } + } + + public void refreshNode(K key) { + getTree().getModel().nodeChanged(nodeMap.get(key)); + } + + protected void clearNode(DefaultMutableTreeNode node) { + if (tree != null) { + for (int i = node.getChildCount() - 1; i >= 0; i--) { + getTree().getModel().removeNodeFromParent((MutableTreeNode) node.getChildAt(i)); + } + getTree().getModel().reload(node); + } + } +} diff --git a/src/eu/engys/gui/tree/GUIPanelHandler.java b/src/eu/engys/gui/tree/GUIPanelHandler.java new file mode 100644 index 0000000..ad964d4 --- /dev/null +++ b/src/eu/engys/gui/tree/GUIPanelHandler.java @@ -0,0 +1,41 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.tree; + +import java.util.Set; + +import eu.engys.gui.GUIPanel; + +public interface GUIPanelHandler { + + Set getPanels(); + + void selectPanel(String key); + void selectAndClearPanel(String key); + + +} diff --git a/src/eu/engys/gui/tree/SelectionHandler.java b/src/eu/engys/gui/tree/SelectionHandler.java new file mode 100644 index 0000000..c3e0ab4 --- /dev/null +++ b/src/eu/engys/gui/tree/SelectionHandler.java @@ -0,0 +1,48 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.tree; + +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public interface SelectionHandler { + + void enable(); + void disable(); + boolean isEnabled(); + + void handleSelection(boolean fire3DEvent, Object... selection); + void handleVisibility(VisibleItem item); + + void process3DSelectionEvent(Picker picker, Actor actor, boolean keep); + void process3DVisibilityEvent(boolean selected); + + void clear(); + + +} diff --git a/src/eu/engys/gui/tree/Tree.java b/src/eu/engys/gui/tree/Tree.java new file mode 100644 index 0000000..63cc198 --- /dev/null +++ b/src/eu/engys/gui/tree/Tree.java @@ -0,0 +1,581 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.tree; + +import java.awt.Component; +import java.awt.Font; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; + +import eu.engys.core.modules.ModulePanel; +import eu.engys.gui.GUIPanel; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.EventManager.Event; +import eu.engys.gui.events.EventManager.GenericEventListener; +import eu.engys.gui.events.view3D.ActorPopUpEvent; +import eu.engys.gui.events.view3D.ActorSelectionEvent; +import eu.engys.gui.events.view3D.ActorVisibilityEvent; +import eu.engys.gui.events.view3D.VisibleItemEvent; +import eu.engys.gui.tree.TreeNodeManager.PopUpBuilder; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.TreeUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.checkboxtree.AddCheckBoxToTree; +import eu.engys.util.ui.checkboxtree.AddCheckBoxToTree.CheckBoxSelectionListener; +import eu.engys.util.ui.checkboxtree.AddCheckBoxToTree.CheckTreeManager; +import eu.engys.util.ui.checkboxtree.RootVisibleItem; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class Tree extends JScrollPane { + + private final GUIPanelHandler panelsHandler; + + private DefaultTreeModel treeModel; + private Map nodesMap = new HashMap(); + private Map, DefaultTreeCellRenderer> renderersMap = new HashMap<>(); + private Map selectionHandlersMap = new HashMap<>(); + private Map, PopUpBuilder> popupBuildersMap = new HashMap<>(); + private JTree tree; + private DefaultMutableTreeNode root; + private CheckTreeManager checkManager; + + private boolean fire3DEvent = true; + + private PopUpMenuListener popUp; + + public Tree(GUIPanelHandler panelsHandler) { + super(); + this.panelsHandler = panelsHandler; + layoutComponents(); + } + + private void layoutComponents() { + root = new DefaultMutableTreeNode(); + treeModel = new DefaultTreeModel(root); + tree = new JTree(treeModel); + tree.setToggleClickCount(0); + tree.setSelectionModel(new TreeSelectionModel()); + tree.setRootVisible(false); + tree.setCellRenderer(new TreeRenderer()); + tree.setRowHeight(20); + tree.setLargeModel(true); + + setViewportView(tree); + + Set panels = panelsHandler.getPanels(); + for (GUIPanel guiPanel : panels) { + addPanel(guiPanel); + } + + treeModel.nodeStructureChanged(root); + + checkManager = AddCheckBoxToTree.toTree(tree).withListener(new CheckBoxTreeToPanels()); + tree.getSelectionModel().addTreeSelectionListener(new TreeToPanels()); + + popUp = new PopUpMenuListener(); + tree.addMouseListener(popUp); + } + + public CheckTreeManager getCheckManager() { + return checkManager; + } + + public void addListener() { + EventManager.registerEventListener(new ActorPopUpListener(), ActorPopUpEvent.class); + EventManager.registerEventListener(new ActorSelectionListener(), ActorSelectionEvent.class); + EventManager.registerEventListener(new ActorVisibilityListener(), ActorVisibilityEvent.class); + } + + public void removeListener() { + EventManager.unregisterEventSubscriptions(ActorPopUpEvent.class); + EventManager.unregisterEventSubscriptions(ActorSelectionEvent.class); + EventManager.unregisterEventSubscriptions(ActorVisibilityEvent.class); + } + + public void addPanel(GUIPanel guiPanel) { + TreeNodeManager treeNodeManager = guiPanel.getTreeNodeManager(); + treeNodeManager.setTree(this); + DefaultMutableTreeNode node = treeNodeManager.getRoot(); + + installRenderer(treeNodeManager); + installListener(treeNodeManager); + installPopUpActions(treeNodeManager); + + nodesMap.put(guiPanel, node); + + int childIndex = guiPanel.getIndex(); + if (childIndex >= 0 && childIndex <= root.getChildCount()) { + root.insert(node, childIndex); + } else { + root.add(node); + } + + getModel().reload(); + expandNode(); + } + + public void removePanel(GUIPanel guiPanel) { + if (nodesMap.containsKey(guiPanel)) { + DefaultMutableTreeNode node = nodesMap.remove(guiPanel); + + TreeNodeManager treeNodeManager = guiPanel.getTreeNodeManager(); + removeRenderer(treeNodeManager); + removeListener(treeNodeManager); + removePopUpActions(treeNodeManager); + + root.remove(node); + getModel().reload(); + expandNode(); + } + } + + private void installRenderer(TreeNodeManager treeNodeManager) { + DefaultTreeCellRenderer renderer = treeNodeManager.getRenderer(); + Class rendererClass = treeNodeManager.getRendererClass(); + if (renderer != null) { + renderersMap.put(rendererClass, renderer); + } + } + + private void removeRenderer(TreeNodeManager treeNodeManager) { + Class rendererClass = treeNodeManager.getRendererClass(); + if (renderersMap.containsKey(rendererClass)) { + renderersMap.remove(rendererClass); + } + } + + private void installListener(TreeNodeManager treeNodeManager) { + SelectionHandler handler = treeNodeManager.getSelectionHandler(); + DefaultMutableTreeNode root = treeNodeManager.getRoot(); + if (handler != null) { + selectionHandlersMap.put(root, handler); + } + } + + private void removeListener(TreeNodeManager treeNodeManager) { + DefaultMutableTreeNode root = treeNodeManager.getRoot(); + if (selectionHandlersMap.containsKey(root)) { + selectionHandlersMap.remove(root); + } + } + + private void installPopUpActions(TreeNodeManager treeNodeManager) { + PopUpBuilder builder = treeNodeManager.getPopUpBuilder(); + Class rendererClass = treeNodeManager.getRendererClass(); + if (builder != null) { + popupBuildersMap.put(rendererClass, builder); + } + } + + private void removePopUpActions(TreeNodeManager treeNodeManager) { + Class rendererClass = treeNodeManager.getRendererClass(); + if (popupBuildersMap.containsKey(rendererClass)) { + popupBuildersMap.remove(rendererClass); + } + } + + public void selectPanel(GUIPanel panel) { + if (nodesMap.containsKey(panel)) { + TreeNode node = nodesMap.get(panel); + tree.setSelectionPath(new TreePath(getModel().getPathToRoot(node))); + } + } + + private final class ActorSelectionListener implements GenericEventListener { + @Override + public void eventTriggered(Object obj, Event event) { + ActorSelectionEvent selectionEvent = ActorSelectionEvent.class.cast(event); + final Actor selection = selectionEvent.getActor(); + final boolean keep = selectionEvent.isKeep(); + final Picker picker = selectionEvent.getPicker(); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + processSelectionEvent(picker, selection, keep); + } + }); + } + + private void processSelectionEvent(Picker picker, Actor actor, boolean keep) { + if (actor == null) { + TreePath[] selectionPath = tree.getSelectionPaths(); + if (selectionPath != null) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath[0].getLastPathComponent(); + DefaultMutableTreeNode parent = TreeUtil.getFirstLevelParent(node); + tree.setSelectionPath(new TreePath(getModel().getPathToRoot(parent))); + } + } else { + for (SelectionHandler handler : selectionHandlersMap.values()) { + if (handler.isEnabled()) { + handler.process3DSelectionEvent(picker, actor, keep); + } + } + } + } + + } + + private final class ActorPopUpListener implements GenericEventListener { + @Override + public void eventTriggered(Object obj, Event event) { + ActorPopUpEvent popUpEvent = ActorPopUpEvent.class.cast(event); + Actor selection = popUpEvent.getActor(); + Picker picker = popUpEvent.getPicker(); + if (selection != null) { + popUp.mouseReleased(popUpEvent.getMouseEvent()); + } + } + } + + private final class ActorVisibilityListener implements GenericEventListener { + @Override + public void eventTriggered(Object obj, Event event) { + ActorVisibilityEvent selectionEvent = ActorVisibilityEvent.class.cast(event); + final boolean select = selectionEvent.isSelect(); + + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + processTreeCheckBoxSelectionEvent(select); + } + }); + } + + private void processTreeCheckBoxSelectionEvent(boolean selected) { + for (SelectionHandler handler : selectionHandlersMap.values()) { + if (handler.isEnabled()) { + handler.process3DVisibilityEvent(selected); + } + } + tree.repaint(); + } + + } + + private final class TreeToPanels implements TreeSelectionListener { + @Override + public void valueChanged(TreeSelectionEvent e) { + TreePath[] selectionPath = tree.getSelectionPaths(); + if (selectionPath != null) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath[0].getLastPathComponent(); + List selection = TreeUtil.toUserObjects(selectionPath); + + if (node.getLevel() != 1) { + DefaultMutableTreeNode firstLevelParent = TreeUtil.getFirstLevelParent(node); + selectPanelByNode(firstLevelParent); + + SelectionHandler selectionHandler = selectionHandlersMap.get(firstLevelParent); + if (selectionHandler.isEnabled()) { + selectionHandler.handleSelection(fire3DEvent, selection.toArray()); + } + } else { + selectAndClerPanelByNode(node); + } + } else { + for (SelectionHandler handler : selectionHandlersMap.values()) { + if (handler.isEnabled()) { + handler.handleSelection(fire3DEvent, new Object[0]); + } + } + } + } + + private void selectAndClerPanelByNode(DefaultMutableTreeNode node) { + if (node.getLevel() == 1) { + selectAndClearPanelByNode(node); + } else { + selectAndClearPanelByFirstLevelParent(node); + } + } + + private void selectAndClearPanelByNode(DefaultMutableTreeNode node) { + panelsHandler.selectAndClearPanel(getNodeLabel(node)); + } + + private void selectAndClearPanelByFirstLevelParent(DefaultMutableTreeNode node) { + DefaultMutableTreeNode firstLevelParent = TreeUtil.getFirstLevelParent(node); + selectAndClearPanelByNode(firstLevelParent); + } + + private void selectPanelByNode(DefaultMutableTreeNode node) { + panelsHandler.selectPanel(getNodeLabel(node)); + } + + private String getNodeLabel(DefaultMutableTreeNode node) { + Object userObject = node.getUserObject(); + if (userObject instanceof String) { + return (String) userObject; + } else if (userObject instanceof ModulePanel) { + return ((ModulePanel) userObject).getKey(); + } else if (userObject instanceof RootVisibleItem) { + return ((RootVisibleItem) userObject).getName(); + } else { + return ""; + } + } + + } + + private final class CheckBoxTreeToPanels implements CheckBoxSelectionListener { + + @Override + public void selectionAdded(DefaultMutableTreeNode node) { + // System.out.println("Tree.CheckBoxTreeToPanels.selectionAdded()"); + Object userObject = node.getUserObject(); + if (userObject instanceof RootVisibleItem) { + if (node.getChildCount() > 0) { + for (int i = 0; i < node.getChildCount(); i++) { + DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i); + selectionAdded(child); + } + } + } else if (userObject instanceof VisibleItem) { + selectNode(node, true); + } + } + + private void selectNode(DefaultMutableTreeNode node, boolean selected) { + Object userObject = node.getUserObject(); + VisibleItem item = (VisibleItem) userObject; + item.setVisible(selected); + + if (node.getLevel() != 1) { + DefaultMutableTreeNode firstLevelParent = TreeUtil.getFirstLevelParent(node); + SelectionHandler handler = selectionHandlersMap.get(firstLevelParent); + if (handler.isEnabled()) { + handler.handleVisibility(item); + EventManager.triggerEvent(this, new VisibleItemEvent(this, (VisibleItem) userObject)); + } + } + } + + @Override + public void selectionRemoved(DefaultMutableTreeNode node) { + // System.out.println("Tree.CheckBoxTreeToPanels.selectionRemoved() "+node); + Object userObject = node.getUserObject(); + if (userObject instanceof RootVisibleItem) { + if (node.getChildCount() > 0) { + for (int i = 0; i < node.getChildCount(); i++) { + DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i); + selectionRemoved(child); + } + } + } else if (userObject instanceof VisibleItem) { + selectNode(node, false); + } + } + } + + public class TreeRenderer extends DefaultTreeCellRenderer { + + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + + Object userObject = node.getUserObject(); + if (userObject != null) { + Class klass = containsClass(userObject.getClass()); + if (klass != Object.class) { + return renderersMap.get(klass).getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + } + } + super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + if (userObject instanceof ModulePanel) { + setText(((ModulePanel) userObject).getTitle()); + } + if (node.getLevel() == 1) { + setFont(tree.getFont().deriveFont(Font.BOLD)); + } else { + setFont(tree.getFont().deriveFont(Font.PLAIN)); + } + setIcon(null); + return this; + } + } + + private Class containsClass(Class klass) { + if (klass == null) { + return Object.class; + } + if (renderersMap.containsKey(klass)) { + return klass; + } + + if (klass.getSuperclass() != null && klass.getSuperclass() != Object.class) { + return containsClass(klass.getSuperclass()); + } + + if (klass.getInterfaces().length != 0) { + for (Class c : klass.getInterfaces()) { + Class k = containsClass(c); + if (k != Object.class) { + return k; + } + } + } + return Object.class; + } + + public void clearAllSelections() { + tree.clearSelection(); + checkManager.clearSelection(); + } + + public void clearSelection() { + tree.clearSelection(); + } + + public void clearCheckSelection() { + checkManager.clearSelection(); + } + + public boolean isAlreadySelected(DefaultMutableTreeNode selectedNode) { + TreePath treePath = new TreePath(getPathToRoot(selectedNode)); + return tree.getSelectionModel().isPathSelected(treePath); + } + + public void addSelectedNode(DefaultMutableTreeNode selectedNode) { + this.fire3DEvent = false; + TreePath treePath = new TreePath(getPathToRoot(selectedNode)); + tree.getSelectionModel().addSelectionPath(treePath); + tree.repaint(); + this.fire3DEvent = true; + } + + public void removeSelectedNode(DefaultMutableTreeNode selectedNode) { + this.fire3DEvent = false; + TreePath treePath = new TreePath(getPathToRoot(selectedNode)); + tree.getSelectionModel().removeSelectionPath(treePath); + tree.repaint(); + this.fire3DEvent = true; + } + + public void setSelectedNode(DefaultMutableTreeNode selectedNode) { + this.fire3DEvent = false; + TreePath treePath = new TreePath(getPathToRoot(selectedNode)); + tree.getSelectionModel().setSelectionPath(treePath); + tree.scrollPathToVisible(treePath); + tree.repaint(); + this.fire3DEvent = true; + } + + public Object[] getPathToRoot(DefaultMutableTreeNode selectedNode) { + return ((DefaultTreeModel) tree.getModel()).getPathToRoot(selectedNode); + } + + public TreePath[] getSelectedDescendantOf(DefaultMutableTreeNode parentNode) { + TreePath parentPath = new TreePath(getPathToRoot(parentNode)); + List selection = new ArrayList<>(); + TreePath[] selectionPaths = getSelectionPaths(); + if (selectionPaths != null) { + for (TreePath path : selectionPaths) { + if (path != parentPath && parentPath.isDescendant(path)) { + selection.add(path); + } + } + } + return selection.toArray(new TreePath[0]); + } + + public TreePath[] getSelectionPaths() { + return tree.getSelectionPaths(); + } + + public void expandNode() { + UiUtil.expandAll(tree, true); + } + + public void expandNode(DefaultMutableTreeNode node) { + TreePath treePath = new TreePath(node.getPath()); + UiUtil.expandAll(tree, treePath, true); + } + + public void setSelectionPaths(TreePath[] selPaths) { + tree.setSelectionPaths(selPaths); + } + + public DefaultTreeModel getModel() { + return (DefaultTreeModel) tree.getModel(); + } + + private final class PopUpMenuListener extends MouseAdapter { + private JPopupMenu popUp; + + public PopUpMenuListener() { + popUp = new JPopupMenu(); + } + + @Override + public void mouseReleased(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + + // Select row if not selected + // tree.setSelectionRow(tree.getClosestRowForLocation(e.getX(), e.getY())); + + TreePath[] selectionPath = tree.getSelectionPaths(); + if (selectionPath != null) { + List selection = TreeUtil.toUserObjects(selectionPath); + Class klass = containsClass(selection.get(0).getClass()); + if (klass != Object.class) { + if (popupBuildersMap.containsKey(klass)) { + popUp.removeAll(); + + PopUpBuilder builder = popupBuildersMap.get(klass); + builder.populate(popUp); + popUp.show(e.getComponent(), e.getX(), e.getY()); + } + } + } + } + } + } + + public void selectPanelIfNeeded() { + if (tree.getSelectionCount() == 0) { + tree.setSelectionRow(0); + } + } +} diff --git a/src/eu/engys/gui/tree/TreeNodeManager.java b/src/eu/engys/gui/tree/TreeNodeManager.java new file mode 100644 index 0000000..c48f0c5 --- /dev/null +++ b/src/eu/engys/gui/tree/TreeNodeManager.java @@ -0,0 +1,57 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.tree; + +import java.util.Observer; + +import javax.swing.JPopupMenu; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; + + +public interface TreeNodeManager extends Observer { + + public void clear(); + + public DefaultMutableTreeNode getRoot(); + + public void setTree(Tree tree); + + public Tree getTree(); + + public DefaultTreeCellRenderer getRenderer(); + + public Class getRendererClass(); + + public SelectionHandler getSelectionHandler(); + + public PopUpBuilder getPopUpBuilder(); + + public interface PopUpBuilder { + void populate(JPopupMenu popUp); + } +} diff --git a/src/eu/engys/gui/tree/TreeSelectionModel.java b/src/eu/engys/gui/tree/TreeSelectionModel.java new file mode 100644 index 0000000..2a2fca5 --- /dev/null +++ b/src/eu/engys/gui/tree/TreeSelectionModel.java @@ -0,0 +1,78 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.tree; + +import java.util.List; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreePath; + +import eu.engys.util.ui.TreeUtil; + +public class TreeSelectionModel extends DefaultTreeSelectionModel { + + public TreeSelectionModel() { + super(); + } + + @Override + public void setSelectionPaths(TreePath[] selectionPath) { + if ((selectionPath != null) && (selectionPath.length > 0)) { + TreePath firstPathParent = selectionPath[0].getParentPath(); + + if (firstPathParent == null) { + TreePath[] paths = new TreePath[] {selectionPath[0]}; + super.setSelectionPaths(paths); + return; + } + + if (TreeUtil.areSiblings(selectionPath, firstPathParent)) { + TreePath[] consistentPath = TreeUtil.getAConsistentSelection(selectionPath); + if (consistentPath.length > 0) { + super.setSelectionPaths(consistentPath); + } +// } + } + } + } + + @Override + public void addSelectionPaths(TreePath[] selectionPath) { + if (getSelectionPath() != null) { + TreePath firstPathParent = getSelectionPath().getParentPath(); + if (TreeUtil.areSiblings(selectionPath, firstPathParent)) { + Class leadSelectionClass = ((DefaultMutableTreeNode) getSelectionPath().getLastPathComponent()).getUserObject().getClass(); + List selection = TreeUtil.toUserObjects(selectionPath); + + if (TreeUtil.isConsistent(selection.toArray(), leadSelectionClass)) { + super.addSelectionPaths(selectionPath); + } + } + } + } +} diff --git a/src/eu/engys/gui/view/AbstractView3DElement.java b/src/eu/engys/gui/view/AbstractView3DElement.java new file mode 100644 index 0000000..c1ecff9 --- /dev/null +++ b/src/eu/engys/gui/view/AbstractView3DElement.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view; + +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.gui.GUIPanel; +import eu.engys.gui.view3D.CanvasPanel; + +public abstract class AbstractView3DElement implements View3DElement { + + private static final Logger logger = LoggerFactory.getLogger(View3DElement.class); + + private Set panels; + + public AbstractView3DElement(Set panels) { + this.panels = panels; + } + + @Override + public void install(CanvasPanel view3D) { + for (GUIPanel panel : panels) { + panel.install(view3D); + } + } + + @Override + public void start(CanvasPanel view3D) { + logger.info("[START 3D] {}", getClass().getSimpleName()); + view3D.applyContext(getClass()); + } + + @Override + public void stop(CanvasPanel view3D) { + logger.info("[STOP 3D] {}", getClass().getSimpleName()); + } + + @Override + public void save(CanvasPanel view3D) { + view3D.dumpContext(getClass()); + } + +} diff --git a/src/eu/engys/gui/view/AbstractViewElement.java b/src/eu/engys/gui/view/AbstractViewElement.java new file mode 100644 index 0000000..a73874a --- /dev/null +++ b/src/eu/engys/gui/view/AbstractViewElement.java @@ -0,0 +1,225 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import java.util.HashSet; +import java.util.Set; + +import javax.swing.ImageIcon; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.materials.Materials; +import eu.engys.core.project.runtimefields.RuntimeFields; +import eu.engys.core.project.state.Solver; +import eu.engys.core.project.state.State; +import eu.engys.core.project.system.fieldmanipulationfunctionobjects.FieldManipulationFunctionObjects; +import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObjects; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.gui.Actions; +import eu.engys.gui.GUIError; +import eu.engys.gui.GUIPanel; +import eu.engys.gui.ModelObserver; +import eu.engys.gui.tree.Tree; +import eu.engys.launcher.StartUpMonitor; +import eu.engys.util.plaf.ILookAndFeel; + +public abstract class AbstractViewElement implements ViewElement { + + private static final Logger logger = LoggerFactory.getLogger(ViewElement.class); + + protected final String title; + protected final View3DElement view3DElement; + protected final Set panels; + protected final Set modulePanels; + protected final Set modules; + protected final ILookAndFeel lookAndFeel; + protected final Actions actions; + + public AbstractViewElement(String title, Set panels, Set modules, View3DElement view3DElement, Actions actions, ILookAndFeel lookAndFeel) { + this.title = title; + this.panels = panels; + this.modules = modules; + this.actions = actions; + this.lookAndFeel = lookAndFeel; + this.view3DElement = view3DElement; + this.modulePanels = getModulePanels(); + logger.info("-> {}", getTitle()); + } + + protected Set getModulePanels() { + Set allPanels = new HashSet(); + return allPanels; + } + + @Override + public void layoutComponents() { + for (GUIPanel guiPanel : panels) { + StartUpMonitor.info("Layout " + guiPanel.getTitle()); + logger.info("Layout " + guiPanel.getTitle()); + guiPanel.layoutPanel(); + } + for (GUIPanel guiPanel : modulePanels) { + StartUpMonitor.info("Layout " + guiPanel.getTitle()); + logger.info("Layout " + guiPanel.getTitle()); + guiPanel.layoutPanel(); + } + } + + @Override + public int getPreferredWidth() { + return 0; + } + + @Override + public Actions getActions() { + return actions; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public ImageIcon getIcon() { + return null; + } + + @Override + public Set getPanels() { + // do not add module panels. The module is responsible to add/remove the panel because it contains the logic (module on/off) + return panels; + + } + + @Override + public Set getModules() { + return modules; + } + + @Override + public Tree getTree() { + return getPanel().getTree(); + } + + @Override + public View3DElement getView3D() { + return view3DElement; + } + + @Override + public void start() { + logger.info("[START] {}", getTitle()); + getPanel().start(); + } + + @Override + public void stop() { + logger.info("[STOP] {}", getTitle()); + getPanel().stop(); + } + + @Override + public void clear() { + getPanel().clear(); + logger.info("[CLEAR] {}", getTitle()); + } + + @Override + public void load(Model model) { + logger.info("[LOAD] {}", getTitle()); + for (GUIPanel guiPanel : panels) { + try { + guiPanel.load(); + logger.info("[LOAD] -> {} LOADED", guiPanel.getKey()); + } catch (GUIError error) { + logger.error("[LOAD ERROR] {}", error); + } + } + for (GUIPanel guiPanel : modulePanels) { + try { + guiPanel.load(); + logger.info("[LOAD] -> {} LOADED", guiPanel.getKey()); + } catch (GUIError error) { + logger.error("[LOAD ERROR] {}", error); + } + } + } + + @Override + public void save(Model model) { + logger.info("[SAVE] {}", getTitle()); + for (GUIPanel guiPanel : panels) { + try { + guiPanel.save(); + } catch (GUIError error) { + logger.error("[SAVE ERROR] {}", error); + } + } + for (GUIPanel guiPanel : modulePanels) { + try { + guiPanel.save(); + } catch (GUIError error) { + logger.error("[SAVE ERROR] {}", error); + } + } + } + + @Override + public void changeObserved(Object arg) { + for (ModelObserver observer : getPanel().getObservers()) { + logger.trace("[CHANGE OBSERVED] [{}] -> Panel: {}", arg.getClass().getSimpleName(), observer.getTitle()); + + if (arg instanceof State) { + observer.stateChanged(); + } else if (arg instanceof Solver) { + observer.solverChanged(); + } else if (arg instanceof Materials) { + observer.materialsChanged(); + } else if (arg instanceof Fields) { + observer.fieldsChanged(); + } else if (arg instanceof RuntimeFields) { + observer.runtimeFieldsChanged(); + } else if (arg instanceof openFOAMProject) { + observer.projectChanged(); + } else if (arg instanceof FieldManipulationFunctionObjects) { + observer.fieldManipulationFunctionObjectsChanged(); + } else if (arg instanceof MonitoringFunctionObjects) { + observer.monitoringFunctionObjectsChanged(); + } + } + } + + @Override + public boolean isEnabled(Model model) { + return true; + } +} diff --git a/src/eu/engys/gui/view/ApplicationToolBar.java b/src/eu/engys/gui/view/ApplicationToolBar.java new file mode 100644 index 0000000..17e6467 --- /dev/null +++ b/src/eu/engys/gui/view/ApplicationToolBar.java @@ -0,0 +1,102 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import static eu.engys.util.ui.UiUtil.createToolBarButton; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.JToolBar; +import javax.swing.SwingUtilities; + +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.launcher.StartUpMonitor; +import eu.engys.util.ui.ViewAction; + +public class ApplicationToolBar extends JToolBar { + + private Model model; + + public ApplicationToolBar(Model model) { + super(JToolBar.HORIZONTAL); + this.model = model; + StartUpMonitor.info("Loading Toolbar"); + setFloatable(false); + setRollover(true); + setOpaque(false); + setBorder(BorderFactory.createEmptyBorder()); + + layoutComponents(); + } + + private void layoutComponents() { + add(createToolBarButton(ActionManager.getInstance().get("application.create"))); + add(createToolBarButton(ActionManager.getInstance().get("application.open"))); + add(createToolBarButton(ActionManager.getInstance().get("application.recent"))); + add(createToolBarButton(ActionManager.getInstance().get("application.save"))); + add(createToolBarButton(ActionManager.getInstance().get("application.saveAs"))); + addSeparator(); + add(createToolBarButton(ActionManager.getInstance().get("application.open.terminal"))); + add(createToolBarButton(ActionManager.getInstance().get("application.browse.case"))); + + if (ActionManager.getInstance().contains("application.support.window")) { + addSeparator(); + add(createToolBarButton(ActionManager.getInstance().get("application.support.window"))); + } + + ViewAction connectionAction = ActionManager.getInstance().get("application.connection.window"); + if (ActionManager.getInstance().contains("application.connection.window")) { + addSeparator(); + add(createToolBarButton(connectionAction)); + connectionAction.setEnabled(false); + } + + add(Box.createHorizontalGlue()); + add(createToolBarButton(ActionManager.getInstance().get("application.exit"))); + + ActionManager.getInstance().get("application.save").setEnabled(false); + ActionManager.getInstance().get("application.saveAs").setEnabled(false); + ActionManager.getInstance().get("application.open.terminal").setEnabled(false); + ActionManager.getInstance().get("application.browse.case").setEnabled(false); + } + + public void refresh() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + ActionManager.getInstance().get("application.save").setEnabled(model.getProject() != null); + ActionManager.getInstance().get("application.saveAs").setEnabled(model.getProject() != null); + ActionManager.getInstance().get("application.open.terminal").setEnabled(model.getProject() != null); + ActionManager.getInstance().get("application.browse.case").setEnabled(model.getProject() != null); + if (ActionManager.getInstance().contains("application.connection.window")) { + ActionManager.getInstance().get("application.connection.window").setEnabled(model.getProject() != null); + } + } + }); + } + +} diff --git a/src/eu/engys/gui/view/DefaultControllerListener.java b/src/eu/engys/gui/view/DefaultControllerListener.java new file mode 100644 index 0000000..01c003a --- /dev/null +++ b/src/eu/engys/gui/view/DefaultControllerListener.java @@ -0,0 +1,174 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.ControllerListener; +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.executor.TerminalManager; +import eu.engys.core.project.Model; + +public class DefaultControllerListener implements ControllerListener { + + private static final Logger logger = LoggerFactory.getLogger(DefaultControllerListener.class); + private View view; + private ElementSelector selector; + + public DefaultControllerListener(Model model, View view) { + this.view = view; + this.selector = new ElementSelector(model, view); + } + + @Override + public void saveLocation() { + selector.saveLocation(); + } + + @Override + public void goToLocation() { + selector.goToLocation(); + } + + @Override + public void selectDestinationAndGo() { + selector.selectDestinationAndGo(); + } + + /* + * Case + */ + @Override + public void beforeNewCase() { + logger.debug("BEFORE NEW CASE"); + TerminalManager.getInstance().clear(); + view.clear(); + if (view.getController().getClient() != null) { + view.getController().getClient().reset(); + } + } + + @Override + public void afterNewCase() { + logger.debug("AFTER NEW CASE"); + view.loadView(); + selector.goToFirstElement(); + } + + @Override + public void beforeLoadCase() { + logger.debug("BEFORE LOAD CASE"); + view.clear(); + TerminalManager.getInstance().clear(); + } + + @Override + public void afterLoadCase() { + logger.debug("AFTER LOAD CASE"); + view.loadView(); + } + + @Override + public void beforeReopenCase() { + logger.debug("BEFORE REOPEN CASE"); + view.clear(); + } + + @Override + public void afterReopenCase() { + logger.debug("AFTER REOPEN CASE"); + afterLoadCase(); + } + + @Override + public void beforeSaveCase() { + logger.debug("BEFORE SAVE CASE"); + view.saveView(); + } + + @Override + public void afterSaveCase() { + logger.debug("AFTER SAVE CASE"); + view.loadToolbars(); + } + + /* + * Base mesh from file + */ + @Override + public void afterBlockMesh() { + view.getCanvasPanel().resetZoom(); + } + + /* + * Check + */ + + @Override + public void beforeCheckMesh() { + } + + @Override + public void afterCheckMesh() { + view.getCanvasPanel().getMeshController().readTimeSteps(); + view.getCanvasPanel().loadWidgets(); + selector.goToBoundaryMesh(); + } + + /* + * Virtualise + */ + + @Override + public void beforeVirtualise() { + logger.debug("BEFORE VIRTUALISE"); + view.saveView(); + selector.saveLocation(); + } + + @Override + public void afterVirtualise(GeometryToMesh g2m) { + view.getCanvasPanel().geometryToMesh(g2m); + selector.goToLocation(); + } + + /* + * Solver + */ + + @Override + public void beforeRunCase() { + selector.goToResiduals(); + } + + @Override + public void afterRunCase() { + view.getCanvasPanel().getMeshController().readTimeSteps(); + view.getCanvasPanel().loadWidgets(); + } + +} diff --git a/src/eu/engys/gui/view/ElementSelector.java b/src/eu/engys/gui/view/ElementSelector.java new file mode 100644 index 0000000..37505b1 --- /dev/null +++ b/src/eu/engys/gui/view/ElementSelector.java @@ -0,0 +1,154 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.Model; +import eu.engys.core.project.SolverState; +import eu.engys.util.ui.ExecUtil; + +public class ElementSelector { + + private static final Logger logger = LoggerFactory.getLogger(ElementSelector.class); + + public static final String MESH = "Mesh"; + private static final String MESH_ELEMENT = "eu.engys.gui.mesh.MeshElement"; + + private static final String CASE_SETUP_ELEMENT = "eu.engys.gui.casesetup.CaseSetupElement"; + public static final String FIELDS_INITIALISATION = "Fields Initialisation"; + + private static final String SOLVER_ELEMENT = "eu.engys.gui.solver.SolverElement"; + public static final String RESIDUALS = "Residuals"; + + private Model model; + private View view; + + private Class currentTab; + private String currentNode; + + public ElementSelector(Model model, View view) { + this.model = model; + this.view = view; + } + + public void selectDestinationAndGo() { + if(model.hasProject()){ + if (model.getSolverModel() != null && model.getSolverModel().getServerState() != null && model.getSolverModel().getServerState().getSolverState().isDoingSomething()) { + SolverState solverState = model.getSolverModel().getServerState().getSolverState(); + if(solverState.isMeshing()){ + goToTabAndPanel(getMeshElementClass(), null); + } else if (solverState.isInitialising()){ + goToFieldsInitialisation(); + } else if (solverState.isRunning()){ + goToResiduals(); + } else { + goToFirstElement(); + } + } else { + goToFirstElement(); + } + } + } + + public void saveLocation() { + if(view.getMainPanel().getCurrentElement() != null){ + this.currentTab = view.getMainPanel().getCurrentElement().getClass(); + this.currentNode = view.getMainPanel().getElement(currentTab).getPanel().getSelectedNode(); + } else { + this.currentTab = null; + this.currentNode = null; + } + logger.debug("Location saved: {} - {}", currentTab, currentNode); + } + + public void goToLocation() { + goToTabAndPanel(currentTab, currentNode); + } + + public void goToFirstElement() { + goToTabAndPanel((Class)null, null); + } + + public void goToBoundaryMesh() { + goToTabAndPanel(getMeshElementClass(), MESH); + view.getMainPanel().getElement(getMeshElementClass()).getPanel().getNode(MESH).start(); + } + + private void goToFieldsInitialisation() { + goToTabAndPanel(getCaseSetupElementClass(), FIELDS_INITIALISATION); + } + + public void goToResiduals() { + goToTabAndPanel(getSolverElementClass(), RESIDUALS); + } + + private void goToTabAndPanel(final Class klass, final String panel) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + view.getMainPanel().stop(null); + view.getMainPanel().start(klass); + view.getCanvasPanel().start(klass); + + if(panel != null){ + view.getMainPanel().getElement(klass).getPanel().selectNode(panel); + } + + logger.debug("Location selected: {} - {}", klass, panel); + } + }); + } + + @SuppressWarnings("unchecked") + private Class getCaseSetupElementClass() { + try { + return (Class) Class.forName(CASE_SETUP_ELEMENT); + } catch (ClassNotFoundException e) { + } + return null; + } + + @SuppressWarnings("unchecked") + private Class getSolverElementClass() { + try { + return (Class) Class.forName(SOLVER_ELEMENT); + } catch (ClassNotFoundException e) { + } + return null; + } + + @SuppressWarnings("unchecked") + private Class getMeshElementClass() { + try { + return (Class) Class.forName(MESH_ELEMENT); + } catch (ClassNotFoundException e) { + } + return null; + } + +} diff --git a/src/eu/engys/gui/view/MainPanel.java b/src/eu/engys/gui/view/MainPanel.java new file mode 100644 index 0000000..4c0abfa --- /dev/null +++ b/src/eu/engys/gui/view/MainPanel.java @@ -0,0 +1,271 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import java.awt.BorderLayout; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.swing.JPanel; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.executor.TerminalManager; +import eu.engys.core.project.Model; +import eu.engys.gui.GUIPanel; +import eu.engys.launcher.StartUpMonitor; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; + +public class MainPanel extends JPanel { + + private class TabChangeListener implements ChangeListener { + private ViewElement elementByIndex(int index) { + String title = tabbedPane.getTitleAt(index); + ViewElement element = elementsByTitle.get(title); + return element; + } + + public void stateChanged(ChangeEvent changeEvent) { + int index = tabbedPane.getSelectedIndex(); + ViewElement newElement = elementByIndex(index); + MainPanel.this.firePropertyChange("element", currentElement== null ? null : currentElement.getClass(), newElement.getClass()); + } + } + + private static final Logger logger = LoggerFactory.getLogger(MainPanel.class); + + private final Model model; + private final ProgressMonitor monitor; + private final Set viewElements; + + private Map, ViewElement> elementsByClass = new HashMap, ViewElement>(); + private Map elementsByTitle = new HashMap(); + + private JTabbedPane tabbedPane; + private ViewElement currentElement; + + private TabChangeListener tabChangeListener; + + public MainPanel(Model model, Set viewElements, ProgressMonitor monitor) { + this.model = model; + this.viewElements = viewElements; + this.monitor = monitor; + } + + public void layoutComponents() { + setLayout(new BorderLayout()); + + tabbedPane = new JTabbedPane(); + tabbedPane.putClientProperty("Synthetica.tabbedPane.tabIndex", 0); + tabbedPane.setName("view.tab"); + + for (ViewElement element : viewElements) { + layoutElements(element); + } + + JSplitPane terminalSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + terminalSplitPane.setTopComponent(tabbedPane); + terminalSplitPane.setBottomComponent(TerminalManager.getInstance().getComponent()); + terminalSplitPane.setResizeWeight(1); + terminalSplitPane.setOneTouchExpandable(false); + + add(terminalSplitPane); + + tabChangeListener = new TabChangeListener(); + tabbedPane.addChangeListener(tabChangeListener); + + disableAll(); + } + + private void layoutElements(ViewElement element) { + StartUpMonitor.info("Layout " + element.getTitle()); + logger.info("Layout {}", element.getTitle()); + + element.layoutComponents(); + elementsByClass.put(element.getClass(), element); + elementsByTitle.put(element.getTitle(), element); + + JPanel panel = element.getPanel(); + tabbedPane.addTab(element.getTitle(), panel); + } + + public ViewElement getElement(Class klass) { + return elementsByClass.get(klass); + } + + public ViewElement getElement(String title) { + return elementsByTitle.get(title); + } + + public void clear() { + currentElement = null; + for (ViewElement element : viewElements) { + clear(element.getClass()); + } + } + + private void clear(Class klass) { + if (elementsByClass.containsKey(klass)) { + final ViewElement viewElement = elementsByClass.get(klass); + ExecUtil.invokeAndWait(new Runnable() { + + @Override + public void run() { + viewElement.clear(); + // viewElement.getView3D().clear(); + for (final GUIPanel panel : viewElement.getPanels()) { + panel.clear(); + } + } + }); + + } + } + + public void load() { + for (ViewElement element : viewElements) { + _load(element); + } + } + + private void _load(final ViewElement viewElement) { + logger.debug("LOAD: {}", viewElement.getTitle()); + if (viewElement.isEnabled(model)) { + monitor.setIndeterminate(true); + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + viewElement.load(model); + _enable(viewElement, true); + } + }); + monitor.setIndeterminate(false); + } else { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + _enable(viewElement, false); + } + }); + } + } + + public void save() { + for (final ViewElement viewElement : viewElements) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + if (viewElement.isEnabled(model)) { + viewElement.save(model); + } + } + }); + } + } + + public ViewElement getCurrentElement() { + return currentElement; + } + + private void _enable(final ViewElement element, final boolean enable) { + int index = tabbedPane.indexOfTab(element.getTitle()); + if (index >= 0) { + tabbedPane.setEnabledAt(index, enable); + } + if (enable) + UiUtil.enable(element.getPanel()); + else + UiUtil.disable(element.getPanel()); + } + + public void disableAll() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + for (ViewElement element : viewElements) { + _enable(element, false); + } + } + }); + } + + public void stop(Class klass) { + if (klass == null) { + if (currentElement != null) { + _stop(currentElement); + } else { + _stop(viewElements.iterator().next()); + } + } else if (elementsByClass.containsKey(klass)) { + _stop(elementsByClass.get(klass)); + } + } + + private void _stop(final ViewElement viewElement) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + viewElement.stop(); + viewElement.save(model); + } + }); + } + + public void start(Class klass) { + if (klass == null) { + _start(viewElements.iterator().next()); + } else if (elementsByClass.containsKey(klass)) { + _start(elementsByClass.get(klass)); + } + } + + private void _start(final ViewElement viewElement) { + this.currentElement = viewElement; + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + + viewElement.start(); + viewElement.getActions().update(); + + int index = tabbedPane.indexOfTab(viewElement.getTitle()); + if (index >= 0 && index != tabbedPane.getSelectedIndex()) { + tabbedPane.removeChangeListener(tabChangeListener); + tabbedPane.setSelectedIndex(index); + tabbedPane.addChangeListener(tabChangeListener); + } + } + }); + } +} diff --git a/src/eu/engys/gui/view/StatusBar.java b/src/eu/engys/gui/view/StatusBar.java new file mode 100644 index 0000000..321ed81 --- /dev/null +++ b/src/eu/engys/gui/view/StatusBar.java @@ -0,0 +1,184 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ +package eu.engys.gui.view; + +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JToolBar; +import javax.swing.JToolBar.Separator; +import javax.swing.SwingConstants; + +import org.apache.commons.lang.StringUtils; + +import eu.engys.core.executor.TerminalManager; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.application.OpenMonitorEvent; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.MemoryWidget; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.ResourcesUtil; + +public class StatusBar extends JPanel { + + private static final Icon consoleIcon = ResourcesUtil.getIcon("console.tab.icon"); + private static final Icon monitorIcon = ResourcesUtil.getIcon("console.tab.icon"); + + private static final String DEFAULT_TEXT = StringUtils.repeat(" ", 10); + + private JButton terminalButton; + private JLabel nameLabel; + private JLabel versionLabel; + private JLabel caseLabel; + private JLabel typeLabel; + private JLabel licenseLabel; + private JButton monitorButton; + private MemoryWidget memoryWidget; + + public StatusBar() { + super(); + layoutComponents(); + } + + private void layoutComponents() { + setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); + + terminalButton = createTerminalButton(); + nameLabel = createLabel(ApplicationInfo.getName()); + versionLabel = createLabel(ApplicationInfo.getVersion() + " " + "[" + ApplicationInfo.getBuildDate() + "]"); + caseLabel = createLabel(DEFAULT_TEXT); + typeLabel = createLabel(DEFAULT_TEXT); + licenseLabel = createLabel(DEFAULT_TEXT); + + monitorButton = createMonitorButton(); + memoryWidget = createMemoryWidget(); + + add(terminalButton); + addSeparator(); + add(nameLabel); + addSeparator(); + add(versionLabel); + addSeparator(); + add(caseLabel); + addSeparator(); + add(typeLabel); + addSeparator(); + add(licenseLabel); + add(Box.createHorizontalGlue()); + add(monitorButton); + addSeparator(); + add(memoryWidget); + } + + private void addSeparator() { + Separator separator = new JToolBar.Separator(); + separator.setOrientation(SwingConstants.VERTICAL); + add(separator); + } + + private MemoryWidget createMemoryWidget() { + MemoryWidget mem = new MemoryWidget(); + setupDimensions(mem, MemoryWidget.PROTOTYPE_STRING); + return mem; + } + + private JButton createMonitorButton() { + JButton button = new JButton(monitorIcon); + button.setFocusable(false); + button.setBorder(BorderFactory.createEmptyBorder()); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + EventManager.triggerEvent(this, new OpenMonitorEvent()); + } + }); + return button; + } + + private JLabel createLabel(String text) { + JLabel label = new JLabel(text); + label.setBorder(BorderFactory.createEmptyBorder()); + + setupDimensions(label, label.getText()); + + return label; + } + + private void setupDimensions(JComponent c, String text) { + Dimension d = new Dimension(c.getFontMetrics(c.getFont()).stringWidth(text), 20); + c.setPreferredSize(d); + c.setMaximumSize(d); + } + + private JButton createTerminalButton() { + JButton button = new JButton(consoleIcon); + button.setFocusable(false); + button.setBorder(BorderFactory.createEmptyBorder()); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + TerminalManager.getInstance().toggleVisibility(); + } + }); + return button; + } + + public void load(final Model model) { + ExecUtil.invokeLater(new Runnable() { + public void run() { + openFOAMProject project = model.getProject(); + if (project != null) { + caseLabel.setText(project.getBaseDir().getAbsolutePath()); + typeLabel.setText(project.isParallel() ? "Parallel" : "Serial"); + } else { + caseLabel.setText(""); + typeLabel.setText(""); + } + + setupDimensions(caseLabel, caseLabel.getText()); + setupDimensions(typeLabel, typeLabel.getText()); + + revalidate(); + repaint(); + } + }); + + } + + public void updateLicenseField() { + } + +} diff --git a/src/eu/engys/gui/view/SurfacesCombo.java b/src/eu/engys/gui/view/SurfacesCombo.java new file mode 100644 index 0000000..287ab7a --- /dev/null +++ b/src/eu/engys/gui/view/SurfacesCombo.java @@ -0,0 +1,102 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import java.awt.Component; + +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.ListCellRenderer; + +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.Surface; + +public class SurfacesCombo extends JComboBox { + + public SurfacesCombo() { + super(); + setRenderer(new SurfacesComboRenderer(getRenderer())); + } + + public void loadAll(Model model) { + for (Surface surface : model.getGeometry().getSurfaces()) { + if (surface.getType().isStl()) { + if (surface.isSingleton()) { + addItem(surface); + } else { + addItem(surface); + for (Surface region : surface.getRegions()) { + addItem(region); + } + } + } else { + addItem(surface); + } + } + } + + public void loadSTLs(Model model) { + for (Surface surface : model.getGeometry().getSurfaces()) { + if (surface.getType().isStl()) { + addItem(surface); + } + } + } + + public void loadParents(Model model) { + for (Surface surface : model.getGeometry().getSurfaces()) { + if (surface.getType().isStl() || surface.getType().isBaseShape()) { + addItem(surface); + } + } + } + + public Surface getSelectedSurface() { + return (Surface) getSelectedItem(); + } + + class SurfacesComboRenderer implements ListCellRenderer { + + private ListCellRenderer renderer; + + public SurfacesComboRenderer(ListCellRenderer renderer) { + this.renderer = renderer; + } + + @Override + public Component getListCellRendererComponent(JList list, Surface value, int index, boolean isSelected, boolean cellHasFocus) { + Component c = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (c instanceof JLabel) { + ((JLabel) c).setText(value.getName()); + } + return c; + } + + + } + +} diff --git a/src/eu/engys/gui/view/View.java b/src/eu/engys/gui/view/View.java new file mode 100644 index 0000000..5024561 --- /dev/null +++ b/src/eu/engys/gui/view/View.java @@ -0,0 +1,430 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import java.awt.BorderLayout; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.util.List; +import java.util.Observable; +import java.util.Observer; +import java.util.Set; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JSplitPane; +import javax.swing.SwingUtilities; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.inject.Inject; + +import eu.engys.application.AbstractApplication; +import eu.engys.core.Arguments; +import eu.engys.core.controller.Controller; +import eu.engys.core.executor.FileManagerSupport; +import eu.engys.core.executor.TerminalSupport; +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.modules.ModulesUtil; +import eu.engys.core.presentation.Action; +import eu.engys.core.presentation.ActionContainer; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.gui.CreateCaseDialog; +import eu.engys.gui.MenuBar; +import eu.engys.gui.RecentItems; +import eu.engys.gui.StartPanel; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.AddSurfaceEvent; +import eu.engys.gui.view3D.CanvasPanel; +import eu.engys.launcher.StartUpMonitor; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.plaf.ILookAndFeel; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; + +public class View extends JPanel implements Observer, ActionContainer { + + private static final Logger logger = LoggerFactory.getLogger(View.class); + + private final Model model; + private final Controller controller; + + private MainPanel mainPanel; + private final CanvasPanel canvasPanel; + + private final ILookAndFeel lookAndFeel; + private final Set viewElements; + private final Set modules; + private final ProgressMonitor monitor; + + private JSplitPane splitPane; + private MenuBar menuBar; + private StatusBar statusBar; + private ApplicationToolBar applicationToolBar; + + private JDialog startupDialog; + + @Override + public boolean isDemo() { + return controller.isDemo(); + } + + @Inject + public View(Model model, Controller controller, CanvasPanel canvasPanel, ILookAndFeel lookAndFeel, Set vElements, Set modules, ProgressMonitor monitor) { + super(); + this.model = model; + this.controller = controller; + this.viewElements = vElements; + this.canvasPanel = canvasPanel; + this.lookAndFeel = lookAndFeel; + this.modules = modules; + this.monitor = monitor; + + for (ViewElement element : viewElements) { + controller.getReader().registerReader(element.getReader()); + controller.getWriter().registerWriter(element.getWriter()); + } + + controller.addListener(new DefaultControllerListener(model, this)); + model.addObserver(this); + + StartUpMonitor.info("Loading View"); + logger.info("Loading View"); + + ActionManager.getInstance().parseActions(this); + } + + public void setProgressMonitorParent(JFrame frame) { + this.monitor.setParent(frame); + } + + public void layoutComponents() { + menuBar = new MenuBar(this); + statusBar = new StatusBar(); + applicationToolBar = new ApplicationToolBar(model); + + mainPanel = new MainPanel(model, viewElements, monitor); + + mainPanel.layoutComponents(); + canvasPanel.layoutComponents(); + + setLayout(new BorderLayout()); + setName("view"); + + splitPane = new JSplitPane(); + splitPane.setName("split.pane.3d"); + splitPane.setLeftComponent(mainPanel); + splitPane.setRightComponent(canvasPanel.getPanel()); + splitPane.setDividerLocation(lookAndFeel.getMainWidth()); + splitPane.setOneTouchExpandable(false); + + add(applicationToolBar, BorderLayout.NORTH); + add(splitPane, BorderLayout.CENTER); + + // updateSplitPosition(elementByIndex(0)); + + mainPanel.addPropertyChangeListener("element", new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + Class oldKlass = (Class) evt.getOldValue(); + Class newKlass = (Class) evt.getNewValue(); + + // System.out.println("oldKlass = " + oldKlass); + // System.out.println("newKlass = " + newKlass); + + if (oldKlass != null && oldKlass != newKlass) { + _stop(oldKlass); + } + _start(newKlass); + } + }); + } + + public StatusBar getStatusBar() { + return statusBar; + } + + public MenuBar getMenuBar() { + return menuBar; + } + + public ApplicationToolBar getToolBar() { + return applicationToolBar; + } + + public MainPanel getMainPanel() { + return mainPanel; + } + + public CanvasPanel getCanvasPanel() { + return canvasPanel; + } + + public void clear() { + canvasPanel.clear(); + mainPanel.clear(); + } + + public void saveView() { + monitor.info("Saving GUI"); + + mainPanel.save(); + canvasPanel.save(); + + ModulesUtil.save(modules); + } + + public void loadView() { + loadToolbars(); + + if (model.hasProject()) { + monitor.info(""); + monitor.info("Loading 3D"); + canvasPanel.load(); + + monitor.info(""); + monitor.info("Loading GUI"); + mainPanel.load(); + } else { + canvasPanel.clear(); + mainPanel.disableAll(); + } + } + + public void loadToolbars() { + if (model.hasProject()) { + RecentItems.getInstance().push(model.getProject().getBaseDir()); + } + menuBar.updateDictionariesList(model); + statusBar.load(model); + applicationToolBar.refresh(); + } + + private void _stop(Class klass) { + logger.debug("STOP: {}", klass.getSimpleName()); + mainPanel.stop(klass); + canvasPanel.stop(klass); + } + + private void _start(Class klass) { + logger.debug("START: {}", klass.getSimpleName()); + mainPanel.start(klass); + canvasPanel.start(klass); + } + + @Override + public void update(Observable o, Object arg) { + if (o instanceof Model) { + if (arg != null) { + for (ViewElement element : viewElements) { + logger.debug("[CHANGE OBSERVERD] {}", element.getClass().getName()); + element.changeObserved(arg); + } + } + } + } + + @Action(key = "application.create") + public void createCase() { + if (controller.allowActionsOnRunning(false)) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + final CreateCaseDialog createCaseDialog = new CreateCaseDialog(); + createCaseDialog.showDialog(); + if (createCaseDialog.isOK()) { + hideStartupDialog(); + controller.createCase(createCaseDialog.getParameters()); + } + importFiles(); + } + }); + } + } + + @Action(key = "application.open") + public void openCase() { + if (controller.allowActionsOnRunning(false)) { + if (Arguments.baseDir != null) { + controller.openCase(Arguments.baseDir); + Arguments.baseDir = null; + } else { + controller.openCase(null); + } + importFiles(); + } + } + + public void importFiles() { + if (Arguments.stlFiles != null) { + monitor.setIndeterminate(false); + monitor.start("Loading STL Files", false, new Runnable() { + @Override + public void run() { + for (File file : Arguments.stlFiles) { + Stl stl = model.getGeometry().getFactory().readSTL(file, monitor); + model.getGeometry().addSurface(stl); + model.geometryChanged(stl); + + EventManager.triggerEvent(this, new AddSurfaceEvent(stl)); + } + Arguments.stlFiles = null; + monitor.end(); + } + }); + } + } + + @Action(key = "application.recent") + public void open() { + try { + Point location = MouseInfo.getPointerInfo().getLocation(); + SwingUtilities.convertPointFromScreen(location, UiUtil.getActiveWindow()); + createRecentProjectsPopUp().show(this, location.x, (location.y / 2)); + } catch (Exception e) { + // convertPointFromScreen can throw a Nullpointer exception + // no need to do anything + } + + } + + private JPopupMenu createRecentProjectsPopUp() { + final JPopupMenu popup = new JPopupMenu(); + List items = RecentItems.getInstance().getItems(); + if (items.isEmpty()) { + JMenuItem menuItem = new JMenuItem(RecentItems.NO_ITEMS); + menuItem.setEnabled(false); + popup.add(menuItem); + } else { + Icon CASE_ICON = ResourcesUtil.getIcon(ApplicationInfo.getVendor().toLowerCase() + ".case"); + for (final String item : items) { + popup.add(new AbstractAction(item, CASE_ICON) { + @Override + public void actionPerformed(ActionEvent e) { + if (controller.allowActionsOnRunning(false)) { + controller.openCase(new File(item)); + } + } + }); + } + popup.addSeparator(); + popup.add(new AbstractAction("Clear") { + @Override + public void actionPerformed(ActionEvent e) { + RecentItems.getInstance().clear(); + } + }); + } + return popup; + } + + @Action(key = "application.save", checkLicense = true) + public void save() { + File baseDir = model.getProject().getBaseDir(); + if (baseDir.exists()) { + int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "Overwrite existing case?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (retVal == JOptionPane.YES_OPTION) { + controller.saveCase(baseDir); + } + } + } + + @Action(key = "application.saveAs", checkLicense = true) + public void saveAs() { + controller.saveCase(null); + } + + @Action(key = "application.exit") + public void exit() { + if (controller.allowActionsOnRunning(true)) { + _exit(); + } + } + + @Action(key = "application.browse.case") + public void browseCase() { + if (model.getProject() != null && model.getProject().getBaseDir() != null) { + FileManagerSupport.open(model.getProject().getBaseDir()); + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "No project directory", "File System error", JOptionPane.ERROR_MESSAGE); + } + } + + @Action(key = "application.open.terminal", checkEnv = true, checkLicense = true) + public void openTerminal() { + if (model.getProject() != null && model.getProject().getBaseDir() != null) { + TerminalSupport.openTerminal(model); + } + } + + private void _exit() { + System.exit(0); + } + + public void showStartupDialog(AbstractApplication abstractApplication) { + startupDialog = new JDialog(abstractApplication.getFrame(), JDialog.DEFAULT_MODALITY_TYPE); + startupDialog.getContentPane().setLayout(new BorderLayout()); + startupDialog.setName("engys.cfd.dialog"); + startupDialog.getContentPane().add(new StartPanel(abstractApplication, this), BorderLayout.CENTER); + startupDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + startupDialog.setResizable(false); + startupDialog.setTitle(controller.isDemo() ? "(Demo mode)" : ""); + abstractApplication.checkVersion(); + // dialog.getRootPane().setWindowDecorationStyle(JRootPane.NONE); + // dialog.getRootPane().setBorder(BorderFactory.createLineBorder(Color.BLACK)); + UiUtil.centerAndShow(startupDialog); + } + + @Action(key = "application.startup.hide") + public void hideStartupDialog() { + if (startupDialog != null) { + startupDialog.dispose(); + } + } + + public void dump() { + model.getPatches().print(); + } + + public Controller getController() { + return controller; + } + +} diff --git a/src/eu/engys/gui/view/View3DElement.java b/src/eu/engys/gui/view/View3DElement.java new file mode 100644 index 0000000..81f4916 --- /dev/null +++ b/src/eu/engys/gui/view/View3DElement.java @@ -0,0 +1,41 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view; + +import eu.engys.gui.view3D.CanvasPanel; + + +public interface View3DElement { + + public void start(CanvasPanel view3d); + public void stop(CanvasPanel view3d); + public void load(CanvasPanel view3d); + public void save(CanvasPanel view3d); + + public void install(CanvasPanel view3d); + +} diff --git a/src/eu/engys/gui/view/ViewElement.java b/src/eu/engys/gui/view/ViewElement.java new file mode 100644 index 0000000..1a56d6d --- /dev/null +++ b/src/eu/engys/gui/view/ViewElement.java @@ -0,0 +1,80 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import java.util.Set; + +import javax.swing.ImageIcon; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.Model; +import eu.engys.core.project.ProjectReader; +import eu.engys.core.project.ProjectWriter; +import eu.engys.gui.Actions; +import eu.engys.gui.GUIPanel; +import eu.engys.gui.tree.Tree; + +public interface ViewElement { + + public String getTitle(); + + public ImageIcon getIcon(); + + public ViewElementPanel getPanel(); + + public Tree getTree(); + + public void start(); + + public void stop(); + + public void clear(); + + public void load(Model model); + + public void save(Model model); + + public void layoutComponents(); + + public Set getPanels(); + + public Set getModules(); + + public boolean isEnabled(Model model); + + public View3DElement getView3D(); + + public Actions getActions(); + + public ProjectReader getReader(); + + public ProjectWriter getWriter(); + + public int getPreferredWidth(); + + public void changeObserved(Object arg); + +} diff --git a/src/eu/engys/gui/view/ViewElementNavigator.java b/src/eu/engys/gui/view/ViewElementNavigator.java new file mode 100644 index 0000000..222a81e --- /dev/null +++ b/src/eu/engys/gui/view/ViewElementNavigator.java @@ -0,0 +1,106 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view; + +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.ButtonGroup; +import javax.swing.ButtonModel; +import javax.swing.JPanel; +import javax.swing.JToggleButton; + +import eu.engys.gui.GUIPanel; +import eu.engys.util.ui.stepcomponent.FlatButtonUI; + +public class ViewElementNavigator extends JPanel { + + private ViewElementPanel viewElementPanel; + private ButtonGroup bg; + private Map buttonsMap = new HashMap(); + + public ViewElementNavigator(ViewElementPanel viewElementPanel) { + super(); + setName("view.element.navigator"); + this.viewElementPanel = viewElementPanel; + layoutComponents(); + } + + private void layoutComponents() { + setLayout(new GridLayout(0, 1, 4, 4)); + bg = new ButtonGroup() { + public void setSelected(ButtonModel m, boolean b) { + if (b) { + super.setSelected(m, b); + } else { + clearSelection(); + } + } + }; + Set panels = viewElementPanel.getPanels(); + GUIPanel[] panelsArray = panels.toArray(new GUIPanel[panels.size()]); + for (int i=0; i panels; + protected Map panelsMap = new HashMap(); + protected Map modulePanelsMap = new HashMap(); + + private JSplitPane splitPane; + private Tree tree; + private ViewElement element; + + public ViewElementPanel(ViewElement element) { + super(); + this.element = element; + this.panels = element.getPanels(); + setName(element.getTitle()); + layoutPanel(); + } + + protected void layoutPanel() { + mainLayout = new CardLayout(); + guiPanelContainer = new JPanel(mainLayout); + + tree = new Tree(this); + + for (GUIPanel guiPanel : panels) { + String title = guiPanel.getKey(); + JComponent panel = guiPanel.getPanel(); + + guiPanelContainer.add(panel, title); + panelsMap.put(title, guiPanel); + } + + splitPane = new JSplitPane(); + splitPane.setOneTouchExpandable(false); + splitPane.setLeftComponent(tree); + splitPane.setRightComponent(guiPanelContainer); + splitPane.setDividerLocation(200); + + setLayout(new BorderLayout()); + setBorder(UiUtil.getStandardBorder()); + + if (element.getActions() != null) { + add(element.getActions().toolbar(), BorderLayout.NORTH); + } + + add(splitPane, BorderLayout.CENTER); + } + + private GUIPanel selectedPanel; + + @Override + public void selectAndClearPanel(String key) { + selectPanel(key); + selectedPanel.clear(); + } + + @Override + public void selectPanel(final String key) { + if (selectedPanel != null) { + if (selectedPanel.getKey().equals(key)) + return; + if (selectedPanel.canStop()) { + selectedPanel.stop(); + } else { + return; + } + } + + if (panelsMap.containsKey(key)) { + this.selectedPanel = panelsMap.get(key); + } else if (modulePanelsMap.containsKey(key)) { + this.selectedPanel = (GUIPanel) modulePanelsMap.get(key); + } + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + selectedPanel.start(); + mainLayout.show(guiPanelContainer, key); + } + }); + } + + public void selectNode(String key) { + selectPanel(key); + tree.selectPanel(selectedPanel); + } + + public GUIPanel getNode(String key) { + return panelsMap.get(key); + } + + @Override + public Set getPanels() { + return panels; + } + + public List getObservers() { + List list = new ArrayList(); + for (GUIPanel guiPanel : panelsMap.values()) { + if (guiPanel instanceof ModelObserver) { + list.add((ModelObserver) guiPanel); + } + } + for (ModulePanel modulePanel : modulePanelsMap.values()) { + if (modulePanel instanceof ModelObserver) { + list.add((ModelObserver) modulePanel); + } + } + return list; + } + + public void start() { + if (tree != null) { + tree.selectPanelIfNeeded(); + if (selectedPanel != null) { + selectedPanel.start(); + } + tree.addListener(); + } + } + + public void stop() { + if (tree != null) { + tree.removeListener(); + } + if (selectedPanel != null) { + selectedPanel.stop(); + } + } + + public String getSelectedNode() { + return selectedPanel.getKey(); + } + + public void clear() { + getTree().clearAllSelections(); + } + + public Tree getTree() { + return tree; + } + + @Override + public void addPanel(ModulePanel modulePanel) { + String key = modulePanel.getKey(); + + if (!modulePanelsMap.containsKey(key)) { + JComponent panel = modulePanel.getPanel(); + guiPanelContainer.add(panel, key); + modulePanelsMap.put(key, modulePanel); + } + + if (modulePanel instanceof GUIPanel) { + tree.addPanel((GUIPanel) modulePanel); + } + + } + + @Override + public void removePanel(ModulePanel modulePanel) { + if (modulePanel instanceof GUIPanel) { + tree.removePanel((GUIPanel) modulePanel); + } + } + + /* + * For test purposes only + */ + public Map getModulePanelsMap() { + return modulePanelsMap; + } +} diff --git a/src/eu/engys/gui/view/ViewElementPanelTopNavigator.java b/src/eu/engys/gui/view/ViewElementPanelTopNavigator.java new file mode 100644 index 0000000..ae81547 --- /dev/null +++ b/src/eu/engys/gui/view/ViewElementPanelTopNavigator.java @@ -0,0 +1,132 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.util.Set; + +import javax.swing.JComponent; +import javax.swing.JPanel; + +import eu.engys.gui.GUIPanel; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; + +public class ViewElementPanelTopNavigator extends ViewElementPanel { + + private CardLayout mainLayout; + private JPanel mainPanel; + private ViewElementTopNavigator navigator; + + private GUIPanel selectedPanel; + + public ViewElementPanelTopNavigator(ViewElement element) { + super(element); + } + + protected void layoutPanel() { + mainLayout = new CardLayout(); + mainPanel = new JPanel(mainLayout); + + navigator = new ViewElementTopNavigator(this); + + for (GUIPanel guiPanel : panels) { + String title = guiPanel.getKey(); + JComponent panel = guiPanel.getPanel(); + + mainPanel.add(panel, title); + panelsMap.put(title, guiPanel); + } + + setLayout(new BorderLayout()); + setBorder(UiUtil.getStandardBorder()); + add(navigator, BorderLayout.NORTH); + add(mainPanel, BorderLayout.CENTER); + + if (panels.iterator().hasNext()) { + String key = panels.iterator().next().getKey(); + navigator.selectPanel(key); + selectPanel(key); + } + } + + GUIPanel getSelectedPanel() { + return selectedPanel; + } + + public boolean canStop(final String key) { + return selectedPanel != null && selectedPanel.canStop(); + } + + @Override + public void selectPanel(final String key) { + if (key == null) + return; + if (selectedPanel != null) { + if (selectedPanel.getKey().equals(key)) + return; + if (selectedPanel.canStop()) { + selectedPanel.stop(); + } else { + return; + } + } + final GUIPanel panel = panelsMap.get(key); + this.selectedPanel = panel; + panel.start(); + + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + mainLayout.show(mainPanel, key); + navigator.selectPanel(key); + } + }); + } + + public void panelChanged(GUIPanel panel) { + selectPanel(panel.getKey()); + } + + public Set getPanels() { + return panels; + } + + @Override + public void clear() { + navigator.clear(); + selectedPanel = null; + } + + @Override + public void start() { + super.start(); + if (selectedPanel == null) { + navigator.setSelectedIndex(0); + } + } +} diff --git a/src/eu/engys/gui/view/ViewElementTopNavigator.java b/src/eu/engys/gui/view/ViewElementTopNavigator.java new file mode 100644 index 0000000..4e4db9b --- /dev/null +++ b/src/eu/engys/gui/view/ViewElementTopNavigator.java @@ -0,0 +1,83 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view; + +import java.util.Set; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import eu.engys.gui.GUIPanel; +import eu.engys.util.ui.stepcomponent.StepComponent; + +public class ViewElementTopNavigator extends StepComponent { + + private ViewElementPanelTopNavigator viewElementPanel; + + public ViewElementTopNavigator(ViewElementPanelTopNavigator viewElementPanel) { + super(15, 2, 60); + this.viewElementPanel = viewElementPanel; + load(); + } + + private void load() { + Set panels = viewElementPanel.getPanels(); + GUIPanel[] panelsArray = panels.toArray(new GUIPanel[panels.size()]); + for (int i = 0; i < panelsArray.length; i++) { + GUIPanel guiPanel = panelsArray[i]; + String title = guiPanel.getKey(); + if (i == 0) { + addFirst(title, null); + } else if (i == panelsArray.length - 1) { + addLast(title, null); + } else { + addStep(title, null); + } + } + getSelectionModel().addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + GUIPanel selectedPanel = viewElementPanel.getSelectedPanel(); + if (selectedPanel != null && !selectedPanel.getKey().equals(getSelectedStep())) { + viewElementPanel.selectPanel(getSelectedStep()); + if (!viewElementPanel.getSelectedPanel().getKey().equals(getSelectedStep())) { + selectPanel(selectedPanel.getKey()); + } + } else { + viewElementPanel.selectPanel(getSelectedStep()); + } + } + }); + } + + public void selectPanel(String key) { + setSelectedStep(key); + } + + public void clear() { + getSelectionModel().clearSelection(); + } +} diff --git a/src/eu/engys/gui/view/fallback/FallbackViewElement.java b/src/eu/engys/gui/view/fallback/FallbackViewElement.java new file mode 100644 index 0000000..47015c2 --- /dev/null +++ b/src/eu/engys/gui/view/fallback/FallbackViewElement.java @@ -0,0 +1,134 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view.fallback; + +import java.util.Collections; +import java.util.Set; + +import javax.swing.ImageIcon; + +import eu.engys.core.modules.ApplicationModule; +import eu.engys.core.project.Model; +import eu.engys.core.project.ProjectReader; +import eu.engys.core.project.ProjectWriter; +import eu.engys.gui.Actions; +import eu.engys.gui.GUIPanel; +import eu.engys.gui.tree.Tree; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view.ViewElement; +import eu.engys.gui.view.ViewElementPanel; + +public class FallbackViewElement implements ViewElement { + + @Override + public String getTitle() { + return null; + } + + @Override + public ImageIcon getIcon() { + return null; + } + + @Override + public ViewElementPanel getPanel() { + return null; + } + + @Override + public Tree getTree() { + return null; + } + + @Override + public void start() { + } + + @Override + public void stop() { + } + + @Override + public void clear() { + } + + @Override + public void load(Model model) { + } + + @Override + public void save(Model model) { + } + + @Override + public void layoutComponents() { + } + + @Override + public Set getPanels() { + return Collections.emptySet(); + } + + @Override + public Set getModules() { + return Collections.emptySet(); + } + + @Override + public boolean isEnabled(Model model) { + return false; + } + + @Override + public View3DElement getView3D() { + return null; + } + + @Override + public Actions getActions() { + return null; + } + + @Override + public ProjectReader getReader() { + return null; + } + + @Override + public ProjectWriter getWriter() { + return null; + } + + @Override + public int getPreferredWidth() { + return 0; + } + + @Override + public void changeObserved(Object arg) { + } + +} diff --git a/src/eu/engys/gui/view3D/Actor.java b/src/eu/engys/gui/view3D/Actor.java new file mode 100644 index 0000000..797a14d --- /dev/null +++ b/src/eu/engys/gui/view3D/Actor.java @@ -0,0 +1,86 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + +import vtk.vtkActor; +import vtk.vtkLookupTable; +import vtk.vtkMapper; +import vtk.vtkPolyData; +import vtk.vtkTransform; +import vtk.vtkUnstructuredGrid; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public interface Actor { + + String getName(); + VisibleItem getVisibleItem(); + + boolean getVisibility(); + void setVisibility(boolean onoff); + + vtkMapper getMapper(); + +// vtkProperty getProperty(); +// void setProperty(vtkProperty vtkProperty); + + vtkActor getActor(); + vtkActor getSelectionActor(); + + void rename(String name); + + void deleteActor(); + + void transformActor(boolean save, AffineTransform t); + + void interactiveOn(); + void interactiveOff(); + + double[] getBounds(); + + void setSolidColor(double[] color, double opacity); + void setScalarColors(vtkLookupTable lut, FieldItem field); + + vtkTransform getUserTransform(); + + void setInput(vtkPolyData input); + void setInput(vtkUnstructuredGrid input); + + void setRepresentation(Representation representation); + + void restoreFromSelection(); + void selectActor(); + void deselectActor(); + + void deselectedStateOn(); + void deselectedStateOff(); + + int getMemorySize(); + + + +} diff --git a/src/eu/engys/gui/view3D/Axis.java b/src/eu/engys/gui/view3D/Axis.java new file mode 100644 index 0000000..c8c5c2a --- /dev/null +++ b/src/eu/engys/gui/view3D/Axis.java @@ -0,0 +1,43 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + +public enum Axis { + X_AXE, Y_AXE, Z_AXE; + + public boolean isX() { + return this == X_AXE; + } + + public boolean isY() { + return this == Y_AXE; + } + + public boolean isZ() { + return this == Z_AXE; + } +} diff --git a/src/eu/engys/gui/view3D/BoxEventButton.java b/src/eu/engys/gui/view3D/BoxEventButton.java new file mode 100644 index 0000000..73d0529 --- /dev/null +++ b/src/eu/engys/gui/view3D/BoxEventButton.java @@ -0,0 +1,66 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + +import java.awt.Dimension; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JToggleButton; +import javax.swing.SwingConstants; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.BoxEvent; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.textfields.DoubleField; + +public class BoxEventButton extends JToggleButton { + + private static final Icon ICON_ON = ResourcesUtil.getResourceIcon("eu/engys/resources/images/lightbulb16.png"); + private static final Icon ICON_OFF = ResourcesUtil.getResourceIcon("eu/engys/resources/images/lightbulb_off16.png"); + + public BoxEventButton(final DoubleField[] boxMin, final DoubleField[] boxMax) { + super(); + setAction(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + if (isSelected()) { + EventManager.triggerEvent(this, new BoxEvent(boxMin, boxMax, EventActionType.SHOW)); + } else { + EventManager.triggerEvent(this, new BoxEvent(boxMin, boxMax, EventActionType.HIDE)); + } + } + }); + setPreferredSize(new Dimension(36, 48)); + setIcon(ICON_OFF); + setSelectedIcon(ICON_ON); + setPressedIcon(ICON_ON); +// setVerticalAlignment(SwingConstants.TOP); + setVerticalTextPosition(SwingConstants.CENTER); + } +} diff --git a/src/eu/engys/gui/view3D/CameraManager.java b/src/eu/engys/gui/view3D/CameraManager.java new file mode 100644 index 0000000..0862568 --- /dev/null +++ b/src/eu/engys/gui/view3D/CameraManager.java @@ -0,0 +1,35 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + + +public interface CameraManager { + public enum Position { + X_POS, X_NEG, Y_POS, Y_NEG, Z_POS, Z_NEG + } + + void setCameraPosition(Position pos); +} diff --git a/src/eu/engys/gui/view3D/CanvasPanel.java b/src/eu/engys/gui/view3D/CanvasPanel.java new file mode 100644 index 0000000..fc67a43 --- /dev/null +++ b/src/eu/engys/gui/view3D/CanvasPanel.java @@ -0,0 +1,92 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + +import java.awt.Color; + +import javax.swing.JPanel; +import javax.vecmath.Point3d; + +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.gui.events.view3D.VolumeReportVisibilityEvent.Kind; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view.ViewElement; +import eu.engys.gui.view3D.widget.Widget; +import eu.engys.util.ui.textfields.DoubleField; + +public interface CanvasPanel { + +// public void start(); +// public void stop(); +// public void load(); + public void start(Class klass); + public void stop(Class klass); + public void load(); + public void save(); + public void clear(); + + public void geometryToMesh(GeometryToMesh g2m); + + public JPanel getPanel(); + + public void showBox(DoubleField[] min, DoubleField[] max, EventActionType actions); + public void showPoint(DoubleField[] point, String key, EventActionType action, Color color); + public void showPlane(DoubleField[] origin, DoubleField[] normal, EventActionType actions); + public void showPlaneDisplay(DoubleField[] origin, DoubleField[] normal, EventActionType actions); + public void showAxis(DoubleField[] origin, DoubleField[] normal, EventActionType actions); + public void activateSelection(Selection selection, EventActionType action); + public void showQualityFields(QualityInfo qualityInfo, EventActionType action); + public void showLayersCoverage(LayerInfo layerInfo, JPanel colorBar, EventActionType action); + + public void layoutComponents(); + + public void updateMinAndMaxForFields(String varName, Point3d min, Point3d max); + public void showMinMaxFieldPoints(String key, Kind kind, boolean visible); + + public Geometry3DController getGeometryController(); + public Mesh3DController getMeshController(); + + public T getController(Class klass); + + public BoundingBox computeBoundingBox(boolean visibleOnly); + + public void showWidgetPanel(Widget widget); + public void hideWidgetPanel(Widget widget); + + public boolean showWidget(Widget widget); + public void hideWidget(Widget widget); + public void resetZoom(); + public void loadWidgets(); + + void registerController(Controller3D context); + + public void applyContext(Class klass); + public void dumpContext(Class klass); + +} diff --git a/src/eu/engys/gui/view3D/CellPicker.java b/src/eu/engys/gui/view3D/CellPicker.java new file mode 100644 index 0000000..6792a0e --- /dev/null +++ b/src/eu/engys/gui/view3D/CellPicker.java @@ -0,0 +1,33 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + + +public interface CellPicker { + + void pick(PickInfo pi); + +} diff --git a/src/eu/engys/gui/view3D/Context.java b/src/eu/engys/gui/view3D/Context.java new file mode 100644 index 0000000..9f59cef --- /dev/null +++ b/src/eu/engys/gui/view3D/Context.java @@ -0,0 +1,45 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + + +public class Context { + + protected Representation representation; + + public Context(Representation representation) { + this.representation = representation; + } + + public Representation getRepresentation() { + return representation; + } + + public boolean isEmpty() { + return false; + } +} diff --git a/src/eu/engys/gui/view3D/Controller3D.java b/src/eu/engys/gui/view3D/Controller3D.java new file mode 100644 index 0000000..cae00ef --- /dev/null +++ b/src/eu/engys/gui/view3D/Controller3D.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + +import java.util.Collection; + +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.gui.view.View3DElement; + +public interface Controller3D { + + void clearContext(); + void newContext(Class klass); + void newEmptyContext(Class klass); + void dumpContext(Class klass); + void applyContext(Class klass); + + Context getCurrentContext(); + + void loadActors(); + void clear(); + + Collection getActorsList(); + + void geometryToMesh(GeometryToMesh g2m); + + void zoomReset(); + void render(); + + void setRenderPanel(RenderPanel renderPanel); +} diff --git a/src/eu/engys/gui/view3D/Geometry3DController.java b/src/eu/engys/gui/view3D/Geometry3DController.java new file mode 100644 index 0000000..33b3a11 --- /dev/null +++ b/src/eu/engys/gui/view3D/Geometry3DController.java @@ -0,0 +1,69 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + +import java.awt.Color; +import java.util.Collection; +import java.util.Map; + +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.mesh.FieldItem; + +public interface Geometry3DController extends Controller3D { + + public void updateSurfacesSelection(Surface... selection); + + void updateSurfaceVisibility(Surface... selection); + + void updateSurfaceColor(Color color, Surface... selection); + + void addSurfaces(Surface... surface); + + void transformSurfaces(AffineTransform t, boolean save, Surface... surfaces); + + void changeSurface(Surface... surface); + + void removeSurfaces(Surface... surfaces); + + public BoundingBox computeBoundingBox(Surface... surfaces); + + void clear(); + + Collection getActorsList(); + + public Map getActorsMap(); + + public void showInternalMesh(); + + public void hideInternalMesh(); + + public void showField(FieldItem fieldItem); + + +} diff --git a/src/eu/engys/gui/view3D/Geometry3DEventListener.java b/src/eu/engys/gui/view3D/Geometry3DEventListener.java new file mode 100644 index 0000000..652566a --- /dev/null +++ b/src/eu/engys/gui/view3D/Geometry3DEventListener.java @@ -0,0 +1,136 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + +import java.awt.Color; + +import javax.swing.SwingUtilities; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.gui.events.EventManager.Event; +import eu.engys.gui.events.view3D.AddSurfaceEvent; +import eu.engys.gui.events.view3D.ChangeSurfaceEvent; +import eu.engys.gui.events.view3D.ColorSurfaceEvent; +import eu.engys.gui.events.view3D.RemoveSurfaceEvent; +import eu.engys.gui.events.view3D.RenameSurfaceEvent; +import eu.engys.gui.events.view3D.SelectSurfaceEvent; +import eu.engys.gui.events.view3D.TransformSurfaceEvent; +import eu.engys.gui.events.view3D.VisibleItemEvent; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class Geometry3DEventListener implements View3DEventListener { + + private Geometry3DController controller; + + public Geometry3DEventListener(Geometry3DController geometryActors) { + this.controller = geometryActors; + } + + @Override + public void eventTriggered(final Object obj, final Event event) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (event instanceof RemoveSurfaceEvent) { + handleRemoveSurface((RemoveSurfaceEvent) event); + } else if (event instanceof RenameSurfaceEvent) { + handleRenameSurface((RenameSurfaceEvent) event); + } else if (event instanceof ChangeSurfaceEvent) { + handleChangeSurface((ChangeSurfaceEvent) event); + } else if (event instanceof AddSurfaceEvent) { + handleAddSurface((AddSurfaceEvent) event); + } else if (event instanceof TransformSurfaceEvent) { + handleTransformSurface((TransformSurfaceEvent) event); + } else if (event instanceof SelectSurfaceEvent) { + handleSelectSurface((SelectSurfaceEvent) event); + } else if (event instanceof VisibleItemEvent) { + handleVisibleItem((VisibleItemEvent) event); + } else if (event instanceof ColorSurfaceEvent) { + handleColorSurface((ColorSurfaceEvent) event); + } + } + + }); + } + + private void handleColorSurface(ColorSurfaceEvent event) { + Surface selection = event.getSelection(); + Color c = event.getColor(); + controller.updateSurfaceColor(c, selection); + } + + private void handleVisibleItem(VisibleItemEvent event) { + VisibleItem selection = event.getSelection(); + if (selection instanceof Surface) { + controller.updateSurfaceVisibility((Surface) selection); + } + } + + private void handleSelectSurface(SelectSurfaceEvent event) { + Surface selection[] = event.getSelection(); + controller.updateSurfacesSelection(selection); + } + + private void handleAddSurface(AddSurfaceEvent e) { + Surface[] surfaces = e.getSurfaces(); + controller.addSurfaces(surfaces); + if (e.isResetZoom()) { + controller.zoomReset(); + } else { + controller.render(); + } + } + + private void handleTransformSurface(TransformSurfaceEvent e) { + Surface[] surfaces = e.getSurfaces(); + AffineTransform t = e.getTransformation(); + boolean save = e.shouldSave(); + controller.transformSurfaces(t, save, surfaces); + controller.render(); + } + + private void handleChangeSurface(ChangeSurfaceEvent e) { + Surface surface = e.getSurface(); + boolean resetZoom = e.isResetZoom(); + controller.changeSurface(surface); + controller.render(); + if (resetZoom) { + controller.zoomReset(); + } + } + + private void handleRemoveSurface(RemoveSurfaceEvent e) { + Surface[] surfaces = e.getSurfaces(); + controller.removeSurfaces(surfaces); + } + + private void handleRenameSurface(RenameSurfaceEvent e) { + /* DO NOTHING */ + } + +} diff --git a/src/eu/engys/gui/view3D/Interactor.java b/src/eu/engys/gui/view3D/Interactor.java new file mode 100644 index 0000000..234a00a --- /dev/null +++ b/src/eu/engys/gui/view3D/Interactor.java @@ -0,0 +1,48 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + +import vtk.vtkInteractorObserver; + +public interface Interactor { + + void setStyleToDefault(); + void setStyleToArea(); + void setStyleToZoom(); + + void start(); + + void dispose(); + + void updateSize(int w, int h); + + void wheelForwardEvent(); + void wheelBackwardEvent(); + + void addObserver(vtkInteractorObserver widget); + + +} diff --git a/src/eu/engys/gui/view3D/LayerInfo.java b/src/eu/engys/gui/view3D/LayerInfo.java new file mode 100644 index 0000000..a4faea5 --- /dev/null +++ b/src/eu/engys/gui/view3D/LayerInfo.java @@ -0,0 +1,46 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + +public enum LayerInfo { + NUM_LAYERS("numLayers", true), FCH("fch", false), LEVEL("level", true); + + private String key; + private boolean discrete; + + private LayerInfo(String key, boolean discrete) { + this.key = key; + this.discrete = discrete; + } + + public String getKey() { + return key; + } + + public boolean isDiscrete() { + return discrete; + } +} diff --git a/src/eu/engys/gui/view3D/Mesh3DController.java b/src/eu/engys/gui/view3D/Mesh3DController.java new file mode 100644 index 0000000..887e80a --- /dev/null +++ b/src/eu/engys/gui/view3D/Mesh3DController.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + +import java.util.Collection; + +import vtk.vtkPlane; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.core.project.mesh.ScalarBarType; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.patches.Patch; + +public interface Mesh3DController extends Controller3D { + + void updatePatchesSelection(Patch[] selection); + void updatePatchesVisibility(Patch... selection); + + void updateCellZonesSelection(CellZone[] selection); + void updateCellZonesVisibility(CellZone... selection); + + void clear(); + + BoundingBox computeBoundingBox(); + + void showTimeStep(double value); + void showField(FieldItem fieldItem); + + void clip(vtkPlane plane); + void slice(vtkPlane plane); + void crinkle(vtkPlane plane); + void disconnectFiltersFromInternalMesh(); + + void insideOut(boolean selected); + + void showExternalMesh(); + + void showInternalMesh(); + void hideInternalMesh(); + boolean isInternalMeshLoaded(); + + void readTimeSteps(); + FieldItem getCurrentFieldItem(); + double getCurrentTimeStep(); + + Collection getActorsList(); + + + void setAutomaticRangeCalculation(boolean autoRange); + void setManualRangeCalculation(double[] rangeField); + + void setScalarsActorsResolution(int resolution); + + void resetScalarsActorsRangeAndResolutionAndHue(); + void setScalarsBarType(ScalarBarType hueRangeType); + +} diff --git a/src/eu/engys/gui/view3D/Mesh3DEventListener.java b/src/eu/engys/gui/view3D/Mesh3DEventListener.java new file mode 100644 index 0000000..cc7c094 --- /dev/null +++ b/src/eu/engys/gui/view3D/Mesh3DEventListener.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + +import javax.swing.SwingUtilities; + +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.gui.events.EventManager.Event; +import eu.engys.gui.events.view3D.SelectCellZonesEvent; +import eu.engys.gui.events.view3D.SelectPatchesEvent; +import eu.engys.gui.events.view3D.VisibleItemEvent; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class Mesh3DEventListener implements View3DEventListener { + + private Mesh3DController mesh3DController; + + public Mesh3DEventListener(Mesh3DController mesh3DController) { + this.mesh3DController = mesh3DController; + } + + @Override + public void eventTriggered(Object obj, final Event event) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (event instanceof SelectPatchesEvent) { + handleSelectPatches((SelectPatchesEvent) event); + } else if (event instanceof SelectCellZonesEvent) { + handleSelectZones((SelectCellZonesEvent) event); + } else if (event instanceof VisibleItemEvent) { + handleVisibility((VisibleItemEvent) event); + } + } + }); + } + + private void handleSelectPatches(SelectPatchesEvent event) { + Patch selection[] = ((SelectPatchesEvent) event).getSelection(); + mesh3DController.updatePatchesSelection(selection); + } + + private void handleSelectZones(SelectCellZonesEvent event) { + CellZone selection[] = ((SelectCellZonesEvent) event).getSelection(); + mesh3DController.updateCellZonesSelection(selection); + } + + private void handleVisibility(VisibleItemEvent event) { + VisibleItem selection = event.getSelection(); + if (selection instanceof Patch) { + mesh3DController.updatePatchesVisibility((Patch) selection); + } else if (selection instanceof CellZone) { + mesh3DController.updateCellZonesVisibility((CellZone) selection); + } + } +} diff --git a/src/eu/engys/gui/view3D/PickInfo.java b/src/eu/engys/gui/view3D/PickInfo.java new file mode 100644 index 0000000..ec0e7fb --- /dev/null +++ b/src/eu/engys/gui/view3D/PickInfo.java @@ -0,0 +1,43 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + +import vtk.vtkDataSet; +import vtk.vtkPlanes; + +public class PickInfo { + + public Actor actor; + public vtkDataSet dataSet; + public int cellId; + public int[] cellIJK; + public double[] normal; + public double[] position; + public boolean shift; + public boolean control; + public vtkPlanes frustum; + +} diff --git a/src/eu/engys/gui/view3D/PickManager.java b/src/eu/engys/gui/view3D/PickManager.java new file mode 100644 index 0000000..0ec9352 --- /dev/null +++ b/src/eu/engys/gui/view3D/PickManager.java @@ -0,0 +1,43 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + + +public interface PickManager { + + void registerPickerForActors(Picker picker); + + void registerPickerForCells(CellPicker picker); + void unregisterPickerForCells(CellPicker picker); + + void pickForCells(); + + void pickForActors(); + + double[] pickPoint(); + + +} diff --git a/src/eu/engys/gui/view3D/Picker.java b/src/eu/engys/gui/view3D/Picker.java new file mode 100644 index 0000000..9546249 --- /dev/null +++ b/src/eu/engys/gui/view3D/Picker.java @@ -0,0 +1,35 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + + +public interface Picker { + public boolean containsActor(Actor actor); +// public String getActorName(Actor pickedActor); + public boolean canPickCells(Actor pickedActor); + public boolean canPickMesh(); +} diff --git a/src/eu/engys/gui/view3D/QualityInfo.java b/src/eu/engys/gui/view3D/QualityInfo.java new file mode 100644 index 0000000..3d4920f --- /dev/null +++ b/src/eu/engys/gui/view3D/QualityInfo.java @@ -0,0 +1,102 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + +import static eu.engys.gui.view3D.QualityInfo.Test.LESS_THAN; +import static eu.engys.gui.view3D.QualityInfo.Test.MORE_THAN; + +import java.awt.Color; + +import eu.engys.util.bean.AbstractBean; + + +public class QualityInfo extends AbstractBean { + +// metrics[0] = "nonOrthogonality"; +// metrics[1] = "pyramids"; +// metrics[2] = "skewness" ; +// metrics[3] = "weights"; +// metrics[4] = "volumeRatio"; +// metrics[5] = "determinant"; + public enum Test { + MORE_THAN, LESS_THAN; + } + + public enum QualityMeasure { + NON_ORTHOGONALITY("nonOrthogonality", MORE_THAN), + PYRAMIDS("pyramids", MORE_THAN), + SKEWNESS("skewness", LESS_THAN), + WEIGHTS("weights", MORE_THAN), + VOLUME_RATIO("volumeRatio", MORE_THAN), + DETERMINANT("determinant", MORE_THAN); + + private String fieldName; + private Test test; + + private QualityMeasure(String fieldName, Test test) { + this.fieldName = fieldName; + this.test = test; + } + + public String getFieldName() { + return fieldName; + } + + public Test getTest() { + return test; + } + } + + private QualityInfo.QualityMeasure measure; + private double threshold; + private Color color; + + public QualityInfo.QualityMeasure getMeasure() { + return measure; + } + public void setMeasure(QualityInfo.QualityMeasure measure) { + this.measure = measure; + } + public double getThreshold() { + return threshold; + } + public void setThreshold(double threshold) { + firePropertyChange("threshold", this.threshold, this.threshold = threshold); + } + + public Color getColor() { + return color; + } + public void setColor(Color color) { + this.color = color; + } + + @Override + public String toString() { + return "fieldName: " + getMeasure().getFieldName() + ", test: " + getMeasure().getTest() + ", threshold: " + getThreshold(); + } + +} diff --git a/src/eu/engys/gui/view3D/RenderPanel.java b/src/eu/engys/gui/view3D/RenderPanel.java new file mode 100644 index 0000000..b486ebd --- /dev/null +++ b/src/eu/engys/gui/view3D/RenderPanel.java @@ -0,0 +1,94 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + +import java.awt.Color; +import java.awt.event.KeyListener; + +import vtk.vtkAssembly; +import vtk.vtkImageData; +import eu.engys.gui.view3D.CameraManager.Position; + +public interface RenderPanel { + + void lock(); + + void Render(); + + void unlock(); + + void clear(); + + void setCameraPosition(Position xPos); + void resetCamera(); + + void wheelForward(); + void wheelBackward(); + + void zoomReset(); + void resetZoomLater(); + void resetZoomAndWait(); + + void clearSelection(); + + void setRepresentation(Representation r); + Representation getRepresentation(); + + void changeRepresentation(Representation r); + + void renderLater(); + void renderAndWait(); + + void addActor(vtkAssembly cor); + void addActor(Actor actor); + + void removeActor(Actor actor); + + void selectActors(boolean keepSelected, Actor... pickedActor); + + void setLowRendering(); + void setHighRendering(); + + void setActorColor(Color c, Actor... actor); + + void addKeyListener(KeyListener listener); + + void removeKeyListener(KeyListener listener); + + void dispose(); + + void ParallelProjectionOn(); + void ParallelProjectionOff(); + + PickManager getPickManager(); + + Interactor getInteractor(); + + vtkImageData toImageData(); + + void lowRenderingOff(); + void lowRenderingOn(); +} diff --git a/src/eu/engys/gui/view3D/Representation.java b/src/eu/engys/gui/view3D/Representation.java new file mode 100644 index 0000000..28ade97 --- /dev/null +++ b/src/eu/engys/gui/view3D/Representation.java @@ -0,0 +1,31 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + +public enum Representation { + SURFACE, SURFACE_WITH_EDGES, WIREFRAME, OUTLINE, PROFILE +} diff --git a/src/eu/engys/gui/view3D/Selection.java b/src/eu/engys/gui/view3D/Selection.java new file mode 100644 index 0000000..caeb094 --- /dev/null +++ b/src/eu/engys/gui/view3D/Selection.java @@ -0,0 +1,120 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D; + +import vtk.vtkIdTypeArray; +import vtk.vtkPolyData; +import eu.engys.util.bean.AbstractBean; + +public class Selection extends AbstractBean { + + public enum SelectionType { + CELL, AREA, FEATURE + } + + public enum SelectionTarget { + POINT, LINE, CELL + } + + public enum SelectionMode { + SELECT, DESELECT + } + + private Selection.SelectionType type = SelectionType.FEATURE; + private Selection.SelectionMode mode = SelectionMode.SELECT; + private Selection.SelectionTarget target = SelectionTarget.CELL; + + private double featureAngle = 30.0; + private boolean keepSelection = true; + + private vtkPolyData selectionData; + private vtkPolyData inverseSelectionData; + private vtkIdTypeArray idList; + private vtkPolyData dataSet; + + public void setType(Selection.SelectionType type) { + firePropertyChange("type", this.type, this.type = type); + } + public Selection.SelectionType getType() { + return type; + } + + public void setMode(Selection.SelectionMode mode) { + this.mode = mode; + } + public Selection.SelectionMode getMode() { + return mode; + } + + public void setTarget(Selection.SelectionTarget target) { + this.target = target; + } + public Selection.SelectionTarget getTarget() { + return target; + } + + public void setFeatureAngle(double featureAngle) { + this.featureAngle = featureAngle; + } + public double getFeatureAngle() { + return featureAngle; + } + + public void setKeepSelection(boolean keepSelection) { + this.keepSelection = keepSelection; + } + public boolean isKeepSelection() { + return keepSelection; + } + + public void setSelectionData(vtkPolyData selectionData) { + this.selectionData = selectionData; + } + public vtkPolyData getSelectionData() { + return selectionData; + } + + public void setInverseSelectionData(vtkPolyData inverseSelectionData) { + this.inverseSelectionData = inverseSelectionData; + } + public vtkPolyData getInverseSelectionData() { + return inverseSelectionData; + } + + public void setIdList(vtkIdTypeArray list) { + this.idList = list; + } + public vtkIdTypeArray getIdList() { + return idList; + } + + public void setDataSet(vtkPolyData dataSet) { + firePropertyChange("dataSet", this.dataSet, this.dataSet = dataSet); + } + public vtkPolyData getDataSet() { + return dataSet; + } +} diff --git a/src/eu/engys/gui/view3D/View3DEventListener.java b/src/eu/engys/gui/view3D/View3DEventListener.java new file mode 100644 index 0000000..5d85152 --- /dev/null +++ b/src/eu/engys/gui/view3D/View3DEventListener.java @@ -0,0 +1,33 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D; + +import eu.engys.gui.events.EventManager.GenericEventListener; + +public interface View3DEventListener extends GenericEventListener { + +} diff --git a/src/eu/engys/gui/view3D/fallback/Fallback3DElement.java b/src/eu/engys/gui/view3D/fallback/Fallback3DElement.java new file mode 100644 index 0000000..3fc3dd9 --- /dev/null +++ b/src/eu/engys/gui/view3D/fallback/Fallback3DElement.java @@ -0,0 +1,59 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D.fallback; + +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view3D.CanvasPanel; + +public class Fallback3DElement implements View3DElement { + + @Override + public void install(CanvasPanel view3d) { + } + + @Override + public void start(CanvasPanel view3D) { + } + + @Override + public void stop(CanvasPanel view3D) { + } + + @Override + public void load(CanvasPanel view3D) { + } + + @Override + public void save(CanvasPanel view3D) { + } + +// @Override +// public View3D getView3D() { +// return FALLBACK3D_PANEL; +// } + +} diff --git a/src/eu/engys/gui/view3D/fallback/FallbackGeometry3DController.java b/src/eu/engys/gui/view3D/fallback/FallbackGeometry3DController.java new file mode 100644 index 0000000..91f20fc --- /dev/null +++ b/src/eu/engys/gui/view3D/fallback/FallbackGeometry3DController.java @@ -0,0 +1,149 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D.fallback; + +import java.awt.Color; +import java.util.Collection; +import java.util.Map; + +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Context; +import eu.engys.gui.view3D.Geometry3DController; +import eu.engys.gui.view3D.RenderPanel; + +public class FallbackGeometry3DController implements Geometry3DController { + + @Override + public Context getCurrentContext() { + return null; + } + + @Override + public void setRenderPanel(RenderPanel renderPanel) { + } + + @Override + public void clearContext() { + } + + @Override + public void geometryToMesh(GeometryToMesh g2m) { + } + + @Override + public void updateSurfacesSelection(Surface... selection) { + } + + @Override + public void updateSurfaceVisibility(Surface... selection) { + } + + @Override + public void updateSurfaceColor(Color color, Surface... selection) { + } + + @Override + public void addSurfaces(Surface... surface) { + } + + @Override + public void transformSurfaces(AffineTransform t, boolean save, Surface... surfaces) { + } + + @Override + public void removeSurfaces(Surface... surfaces) { + } + + @Override + public BoundingBox computeBoundingBox(Surface... surfaces) { + return new BoundingBox(0, 0, 0, 0, 0, 0); + } + + @Override + public void clear() { + } + + @Override + public void dumpContext(Class klass) { + } + + @Override + public void applyContext(Class klass) { + } + + @Override + public Collection getActorsList() { + return null; + } + + @Override + public Map getActorsMap() { + return null; + } + + @Override + public void loadActors() { + } + + @Override + public void newContext(Class klass) { + } + + @Override + public void newEmptyContext(Class klass) { + } + + @Override + public void showInternalMesh() { + } + + @Override + public void hideInternalMesh() { + } + + @Override + public void changeSurface(Surface... surface) { + } + + @Override + public void render() { + } + + @Override + public void zoomReset() { + } + + @Override + public void showField(FieldItem fieldItem) { + } +} diff --git a/src/eu/engys/gui/view3D/fallback/FallbackMesh3DController.java b/src/eu/engys/gui/view3D/fallback/FallbackMesh3DController.java new file mode 100644 index 0000000..2175962 --- /dev/null +++ b/src/eu/engys/gui/view3D/fallback/FallbackMesh3DController.java @@ -0,0 +1,198 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.gui.view3D.fallback; + +import java.util.Collection; + +import vtk.vtkPlane; +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.core.project.mesh.ScalarBarType; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Context; +import eu.engys.gui.view3D.Mesh3DController; +import eu.engys.gui.view3D.RenderPanel; + +public class FallbackMesh3DController implements Mesh3DController { + + @Override + public void setRenderPanel(RenderPanel renderPanel) { + } + + @Override + public void updatePatchesSelection(Patch[] selection) { + } + + @Override + public void updateCellZonesVisibility(CellZone... selection) { + } + + @Override + public void updatePatchesVisibility(Patch... selection) { + } + + @Override + public void updateCellZonesSelection(CellZone[] selection) { + } + + @Override + public void loadActors() { + } + + @Override + public Context getCurrentContext() { + return null; + } + + @Override + public void clearContext() { + } + + @Override + public void clear() { + } + + @Override + public BoundingBox computeBoundingBox() { + return null; + } + + @Override + public void setManualRangeCalculation(double[] rangeField) { + } + + @Override + public void setScalarsActorsResolution(int resolution) { + } + + @Override + public void setScalarsBarType(ScalarBarType hueRangeType) { + } + + @Override + public void resetScalarsActorsRangeAndResolutionAndHue() { + } + + @Override + public void setAutomaticRangeCalculation(boolean autoRange) { + } + + @Override + public void dumpContext(Class klass) { + } + + @Override + public void applyContext(Class klass) { + } + + @Override + public void newContext(Class klass) { + } + + @Override + public void newEmptyContext(Class klass) { + } + + @Override + public void geometryToMesh(GeometryToMesh g2m) { + } + + @Override + public void showTimeStep(double value) { + } + + @Override + public FieldItem getCurrentFieldItem() { + return null; + } + + @Override + public double getCurrentTimeStep() { + return 0; + } + + @Override + public void showField(FieldItem fieldItem) { + } + + @Override + public void clip(vtkPlane plane) { + } + + @Override + public void slice(vtkPlane plane) { + } + + @Override + public void crinkle(vtkPlane plane) { + } + + @Override + public void insideOut(boolean selected) { + } + + @Override + public void showInternalMesh() { + } + + @Override + public void hideInternalMesh() { + } + + @Override + public void readTimeSteps() { + } + + @Override + public void showExternalMesh() { + } + + @Override + public Collection getActorsList() { + return null; + } + + @Override + public boolean isInternalMeshLoaded() { + return false; + } + + @Override + public void render() { + } + + @Override + public void zoomReset() { + } + + @Override + public void disconnectFiltersFromInternalMesh() { + } +} diff --git a/src/eu/engys/gui/view3D/fallback/FallbackView3D.java b/src/eu/engys/gui/view3D/fallback/FallbackView3D.java new file mode 100644 index 0000000..fe88214 --- /dev/null +++ b/src/eu/engys/gui/view3D/fallback/FallbackView3D.java @@ -0,0 +1,251 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D.fallback; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.vecmath.Point3d; + +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.gui.events.view3D.VolumeReportVisibilityEvent.Kind; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view.ViewElement; +import eu.engys.gui.view3D.CanvasPanel; +import eu.engys.gui.view3D.Controller3D; +import eu.engys.gui.view3D.Geometry3DController; +import eu.engys.gui.view3D.LayerInfo; +import eu.engys.gui.view3D.Mesh3DController; +import eu.engys.gui.view3D.QualityInfo; +import eu.engys.gui.view3D.Selection; +import eu.engys.gui.view3D.widget.Widget; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.textfields.DoubleField; + +public class FallbackView3D implements CanvasPanel { + + private JPanel panel; + private Icon engysLogo = ResourcesUtil.getIcon(ApplicationInfo.getVendor().toLowerCase() + ".logo.full"); + + private Runnable r = new Runnable() { + @Override + public void run() { + final ImageIcon image = (ImageIcon) engysLogo; + panel = new JPanel() { + @Override + public void paintComponent(final Graphics g) { + super.paintComponent(g); + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + if (image != null) { + // int xCoord = 30; + // int yCoord = getHeight() - image.getIconHeight() - + // 30; + int xCoord = (getWidth() / 2) - (image.getIconWidth() / 2); + int yCoord = (getHeight() / 2) - (image.getIconHeight() / 2); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f)); + g.drawImage(image.getImage(), xCoord, yCoord, null); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); + } + } + }; + panel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); + panel.add(new JLabel("3D graphics not available")); + } + }; + + @Override + public void registerController(Controller3D context) { + } + + @Override + public void layoutComponents() { + } + + @Override + public void load() { + } + + @Override + public void save() { + } + + @Override + public void start(Class klass) { + } + + @Override + public void stop(Class klass) { + } + + @Override + public void loadWidgets() { + } + + @Override + public BoundingBox computeBoundingBox(boolean visibleOnly) { + return new BoundingBox(); + } + + public void updatePatchesSelection(Patch[] selection) { + } + + public void updatePatchVisibility(Patch selection, boolean b) { + } + + public void updateCellZonesSelection(CellZone[] selection) { + } + + public void updateCellZoneVisibility(CellZone selection, boolean b) { + } + + @Override + public void clear() { + } + + public Dimension getMinimumSize() { + return new Dimension(50, 50); + } + + @Override + public JPanel getPanel() { + if (SwingUtilities.isEventDispatchThread()) { + r.run(); + } else { + try { + SwingUtilities.invokeAndWait(r); + } catch (Exception e) { + e.printStackTrace(); + } + } + return panel; + } + + @Override + public void showPoint(DoubleField[] point, String key, EventActionType action, Color color) { + } + + @Override + public void showBox(DoubleField[] min, DoubleField[] max, EventActionType actions) { + } + + @Override + public void updateMinAndMaxForFields(String varName, Point3d min, Point3d max) { + } + + @Override + public void showMinMaxFieldPoints(String key, Kind kind, boolean visible) { + } + + @Override + public void activateSelection(Selection selection, EventActionType action) { + } + + @Override + public void showQualityFields(QualityInfo qualityInfo, EventActionType action) { + } + + @Override + public void showLayersCoverage(LayerInfo layerInfo, JPanel colorBar, EventActionType action) { + } + + @Override + public void geometryToMesh(GeometryToMesh g2m) { + } + + @Override + public boolean showWidget(Widget widget) { + return false; + } + + @Override + public void showWidgetPanel(Widget widget) { + } + + @Override + public void hideWidgetPanel(Widget widget) { + } + + @Override + public void hideWidget(Widget widget) { + } + + @Override + public Geometry3DController getGeometryController() { + return new FallbackGeometry3DController(); + } + + @Override + public Mesh3DController getMeshController() { + return new FallbackMesh3DController(); + } + + @Override + public T getController(Class klass) { + return null; + } + + @Override + public void resetZoom() { + } + + @Override + public void showPlane(DoubleField[] origin, DoubleField[] normal, EventActionType action) { + } + + @Override + public void showPlaneDisplay(DoubleField[] origin, DoubleField[] normal, EventActionType actions) { + } + + @Override + public void showAxis(DoubleField[] origin, DoubleField[] normal, EventActionType actions) { + } + + @Override + public void applyContext(Class klass) { + } + + @Override + public void dumpContext(Class klass) { + } + +} diff --git a/src/eu/engys/gui/view3D/widget/Widget.java b/src/eu/engys/gui/view3D/widget/Widget.java new file mode 100644 index 0000000..d59bbee --- /dev/null +++ b/src/eu/engys/gui/view3D/widget/Widget.java @@ -0,0 +1,57 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D.widget; + +import javax.swing.JToolBar; + +import eu.engys.gui.view3D.CanvasPanel; + +public interface Widget { + + void populate(CanvasPanel view3D); + void populate(JToolBar toolbar); + + boolean canShow(); + + void show(); + void hide(); + + void clear(); + + void stop(); + + WidgetComponent getWidgetComponent(); + void load(); + + void applyContext(); + + void handleFieldChanged(); + void handleTimeStepChanged(); + void handleNewTimeStepsRead(); +// void handleInitializeFieldsStarted(); +// void handleInitializeFieldsFinished(); +} diff --git a/src/eu/engys/gui/view3D/widget/WidgetComponent.java b/src/eu/engys/gui/view3D/widget/WidgetComponent.java new file mode 100644 index 0000000..8a43a1c --- /dev/null +++ b/src/eu/engys/gui/view3D/widget/WidgetComponent.java @@ -0,0 +1,41 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.gui.view3D.widget; + +import javax.swing.JPanel; + +public interface WidgetComponent { + + void handleShow(); + + JPanel getPanel(); + + String getKey(); + + void clear(); + +} diff --git a/src/eu/engys/launcher/AbstractApplicationLauncher.java b/src/eu/engys/launcher/AbstractApplicationLauncher.java new file mode 100644 index 0000000..ee2d33a --- /dev/null +++ b/src/eu/engys/launcher/AbstractApplicationLauncher.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.launcher; + +import static eu.engys.launcher.StartUpMonitor.info; + +import java.net.URL; + +import javax.inject.Inject; +import javax.swing.Icon; +import javax.swing.SwingUtilities; + +import com.google.inject.Injector; +import com.google.inject.Module; + +import eu.engys.application.Application; +import eu.engys.application.Batch; +import eu.engys.launcher.modules.Modules; + +public abstract class AbstractApplicationLauncher implements ApplicationLauncher { + + private Injector injector; + + @Inject + public AbstractApplicationLauncher(Injector injector) { + this.injector = injector; + } + + @Override + public String getTitle() { + return ""; + } + + @Override + public Icon getIcon() { + return null; + } + + @Override + public abstract void checkLicense(); + + @Override + public void launch() throws Exception { + info("Loading application modules"); + URL url = getClass().getProtectionDomain().getCodeSource().getLocation(); + Iterable modules = Modules.loadApplicationModules(url); + + info("Starting Modules"); + Injector appInjector = injector.createChildInjector(modules); + + info("Loading Application"); + Application application = appInjector.getInstance(Application.class); + + info("Layout Application"); + SwingUtilities.invokeLater(application); + } + + @Override + public void batch() throws Exception { + info("Loading modules"); + URL url = getClass().getProtectionDomain().getCodeSource().getLocation(); + Iterable modules = Modules.loadBatchModules(url); + + info("Starting modules"); + Injector appInjector = injector.createChildInjector(modules); + + info("Loading application"); + Batch batch = appInjector.getInstance(Batch.class); + + info("Launch Batch"); + batch.run(); + } +} diff --git a/src/eu/engys/launcher/ApplicationLauncher.java b/src/eu/engys/launcher/ApplicationLauncher.java new file mode 100644 index 0000000..87f2d7f --- /dev/null +++ b/src/eu/engys/launcher/ApplicationLauncher.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.launcher; + +import javax.swing.Icon; + + +public interface ApplicationLauncher { + + + public void checkLicense() throws Exception; + public void launch() throws Exception; + public void batch() throws Exception; + + public String getTitle(); + + public Icon getIcon(); + +} + diff --git a/src/eu/engys/launcher/HELYXOSLauncher.java b/src/eu/engys/launcher/HELYXOSLauncher.java new file mode 100644 index 0000000..db9ca29 --- /dev/null +++ b/src/eu/engys/launcher/HELYXOSLauncher.java @@ -0,0 +1,50 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.launcher; + +import javax.inject.Inject; + +import com.google.inject.Injector; + +public class HELYXOSLauncher extends AbstractApplicationLauncher { + + @Inject + public HELYXOSLauncher(Injector injector) { + super(injector); + } + + @Override + public void checkLicense() { + /* do not remove this method*/ + } + + @Override + public void batch() throws Exception { + /* do not remove this method*/ + } + +} diff --git a/src/eu/engys/launcher/Launcher.java b/src/eu/engys/launcher/Launcher.java new file mode 100644 index 0000000..576c30b --- /dev/null +++ b/src/eu/engys/launcher/Launcher.java @@ -0,0 +1,138 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.launcher; + +import static eu.engys.launcher.StartUpMonitor.info; + +import java.util.List; + +import javax.swing.SwingUtilities; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; + +import eu.engys.application.Application; +import eu.engys.application.Batch; +import eu.engys.core.Arguments; +import eu.engys.core.LoggerUtil; +import eu.engys.launcher.modules.Modules; +import eu.engys.suite.Suite; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.Util; +import eu.engys.util.plaf.ILookAndFeel; +import eu.engys.util.ui.UiUtil; + +public class Launcher { + + public static void main(String[] args) throws Exception { + + info("Set Application Info"); + ApplicationInfo.init(); + + printOut(ApplicationInfo.getHeaderInfo()); + + info("Initialize Arguments"); + Arguments.init(args); + + info("Initialize Logger"); + if (Arguments.isBatch()) + LoggerUtil.initFlatLogger(); + else + LoggerUtil.initLogger(); + + info("Initialize Locale"); + LocaleUtil.initLocale(); + + Util.initScriptStyle(); + + info("Loading modules"); + List modules = Modules.loadSuiteModules(); + + if (modules.isEmpty()) { + if (Arguments.isBatch() ) { + modules = Modules.loadBatchModules(null); + + info("Starting modules"); + Injector injector = Guice.createInjector(modules); + + info("Go to Batch"); + Batch batch = injector.getInstance(Batch.class); + + info("Launch Batch"); + batch.run(); + } else { + modules = Modules.loadApplicationModules(null); + + info("Starting modules"); + Injector injector = Guice.createInjector(modules); + + info("Loading LookAndFeel"); + ILookAndFeel laf = injector.getInstance(ILookAndFeel.class); + laf.init(); + + info("Check License"); + ApplicationLauncher launcher = injector.getInstance(ApplicationLauncher.class); + launcher.checkLicense(); + + info("Loading Application"); + Application application = injector.getInstance(Application.class); + + UiUtil.renameUIThread(); + + info("Layout Application"); + SwingUtilities.invokeLater(application); + } + } else { + info("Starting modules"); + Injector injector = Guice.createInjector(modules); + + info("Loading LookAndFeel"); + ILookAndFeel laf = injector.getInstance(ILookAndFeel.class); + laf.init(); + + info("Loading Suite"); + Suite suite = injector.getInstance(Suite.class); + + if (Arguments.isBatch() ) { + info("Go to Batch"); + suite.batch(); + } else { + info("Start Suite"); + UiUtil.installExceptionHandler(); + UiUtil.renameUIThread(); + suite.launch(); + } + } + } + + private static void printOut(String msg) { + System.out.println(msg); + } + +} + diff --git a/src/eu/engys/launcher/LocaleUtil.java b/src/eu/engys/launcher/LocaleUtil.java new file mode 100644 index 0000000..9e1b57d --- /dev/null +++ b/src/eu/engys/launcher/LocaleUtil.java @@ -0,0 +1,37 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.launcher; + +import java.util.Locale; + +public class LocaleUtil { + + public static void initLocale() { + Locale.setDefault(Locale.US); + } + +} diff --git a/src/eu/engys/launcher/StartUpMonitor.java b/src/eu/engys/launcher/StartUpMonitor.java new file mode 100644 index 0000000..2069cad --- /dev/null +++ b/src/eu/engys/launcher/StartUpMonitor.java @@ -0,0 +1,224 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.launcher; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.RenderingHints; +import java.awt.SplashScreen; +import java.awt.Window; +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.net.URLDecoder; +import java.util.concurrent.atomic.AtomicBoolean; + +public class StartUpMonitor { + + private static StartUpMonitor instance; + private static int counter = 0; + private static boolean isElements = false; + private static boolean isHelyxOS = false; + + public static void info(final String msg) { + if (GraphicsEnvironment.isHeadless()) { + System.out.println("+++ " + msg + " +++"); + } else { + if (instance == null) { + instance = new StartUpMonitor(); + pwnSplashScreen(); + setApplicationType(); + } + instance.render(msg); + } + } + + private static void setApplicationType() { + try { + URL coreGuiJarURL = StartUpMonitor.class.getProtectionDomain().getCodeSource().getLocation(); + String decodedCoreGuiJarURL = URLDecoder.decode(coreGuiJarURL.getFile(), "UTF-8"); + File libDir = new File(decodedCoreGuiJarURL).getParentFile(); + isElements = new File(libDir, "ELEMENTS.jar").exists(); + isHelyxOS = new File(libDir, "HELYX-OS.jar").exists(); + } catch (UnsupportedEncodingException e) { + isElements = false; + isHelyxOS = false; + } + } + + private static void pwnSplashScreen() { + try { + Field field = Window.class.getDeclaredField("beforeFirstWindowShown"); + field.setAccessible(true); + + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + + field.set(null, new AtomicBoolean(false)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void close() { + SplashScreen splash = getSplashScreen(); + if (splash != null) { + splash.close(); + } + } + + private static SplashScreen getSplashScreen() { + try { + return SplashScreen.getSplashScreen(); + } catch (HeadlessException e) { + } + return null; + } + + private void render(final String string) { + SplashScreen splash = getSplashScreen(); + if (splash == null) { + return; + } + Graphics2D g = splash.createGraphics(); + if (g == null) { + return; + } + + if (isElements) { + paintElementsProgress(g, string); + } else { + paintHelyxProgress(g, string); + } + + splash.update(); + counter++; + } + + /* + * HELYX + */ + private void paintHelyxProgress(Graphics g, String string) { + paintHelyxProgressBar(g); + paintHelyxProgressText(g, string); + } + + private void paintHelyxProgressBar(Graphics g) { + int leftPadding = 15; + int topPadding = 205; + int splashWidth = getSplashScreen().getSize().width; + int width = Math.min(10 * counter, splashWidth - (leftPadding * 2)); + + g.setColor(isHelyxOS ? Color.BLUE.darker() : Color.RED.darker()); + g.fillRect(leftPadding, topPadding, width, 2); + g.setColor(isHelyxOS ? Color.BLUE.brighter() : Color.RED.brighter()); + g.fillRect(leftPadding, topPadding, width, 1); + } + + private void paintHelyxProgressText(Graphics g, String string) { + int leftPadding = 15; + int topPadding = 175; + + Color bgColor = Color.WHITE; + Color textColor = Color.BLACK; + + // background + int background_width = 210; + int background_height = 30; + g.setPaintMode(); + g.setColor(bgColor); + g.fillRect(leftPadding, topPadding, background_width, background_height); + + // foreground + int text_height = background_height - 5; + g.setColor(textColor); + enableAntialias(g); + g.drawString(string, leftPadding, topPadding + text_height); + disableAntialias(g); + } + + /* + * ELEMENTS + */ + private void paintElementsProgress(Graphics g, String string) { + paintElementsProgressBar(g); + paintElementsProgressText(g, string); + } + + private void paintElementsProgressBar(Graphics g) { + int leftPadding = 20; + int topPadding = 56; + int splashWidth = getSplashScreen().getSize().width; + int width = Math.min(10 * counter, splashWidth - (leftPadding * 2 + 2)); + + g.setColor(Color.GREEN.darker()); + g.fillRect(leftPadding, topPadding, width, 3); + g.setColor(Color.GREEN.brighter()); + g.fillRect(leftPadding, topPadding, width, 1); + } + + private void paintElementsProgressText(Graphics g, String string) { + int leftPadding = 15; + int topPadding = getSplashScreen().getSize().height - 35; + + Color bgColor = Color.WHITE; + Color textColor = Color.BLACK; + + // background + int background_width = 210; + int background_height = 30; + g.setPaintMode(); + g.setColor(bgColor); + g.fillRect(leftPadding, topPadding, background_width, background_height); + + // foreground + int text_height = background_height - 5; + g.setColor(textColor); + enableAntialias(g); + g.drawString(string, leftPadding, topPadding + text_height); + disableAntialias(g); + } + + /* + * Utils + */ + + private void enableAntialias(Graphics g) { + ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + } + + private void disableAntialias(Graphics g) { + ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + +} diff --git a/src/eu/engys/launcher/modules/Modules.java b/src/eu/engys/launcher/modules/Modules.java new file mode 100644 index 0000000..458acd3 --- /dev/null +++ b/src/eu/engys/launcher/modules/Modules.java @@ -0,0 +1,188 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.launcher.modules; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.inject.Module; + +public class Modules { + + private static final Logger logger = LoggerFactory.getLogger(Modules.class); + + private static ClassLoader classLoader; + private static String packageName; + private static Class interfase; + + private static URL url; + + public static List loadSuiteModules() { + return loadModules("eu.engys.suite.modules", Module.class, null); + } + + public static List loadApplicationModules(URL url) { + return loadModules("eu.engys.application.modules", Module.class, url); + } + + public static List loadBatchModules(URL url) { + return loadModules("eu.engys.batch.modules", Module.class, url); + } + + static List loadModules(String pkgName, Class interfaceClass, URL classURL) { + List modules = new ArrayList(); + + interfase = interfaceClass; + packageName = pkgName; + classLoader = Thread.currentThread().getContextClassLoader(); + url = classURL; + + try { + List> classes = findAllImplementationsInPackage(); + + for(Class clazz : classes) { + try { + M newInstance = clazz.newInstance(); + logger.info("[Modules] {} loaded", clazz.getName()); + modules.add(newInstance); + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + + return modules; + } + + public static List> findAllImplementationsInPackage() throws IOException, ClassNotFoundException { + List> implementations = new ArrayList>(); + + List> classes = getClassesFromPackage(packageName); + for (Class klass : classes) { + if (interfase.isAssignableFrom(klass) && !klass.isInterface()){ + implementations.add(klass); + } else { + logger.info("[Modules] {} is not valid.", klass.getName()); + } + } + return implementations; + } + + @SuppressWarnings("unchecked") + private static List> getClassesFromPackage(String packageName) throws ClassNotFoundException, IOException { + List classNames = getClassNamesFromPackage(packageName); + + List> classes = new ArrayList>(); + for (String className : classNames) { + try { + classes.add((Class) Class.forName(className)); + } catch (ClassNotFoundException e) { + logger.error("[Modules] Error Loading class {}", className); + } + } + return classes; + } + + + public static List getClassNamesFromPackage(String packageName) throws IOException { + assert classLoader != null; + + List names = new ArrayList(); + + packageName = packageName.replace(".", "/"); + Enumeration packageURLs = classLoader.getResources(packageName); + + for(URL packageURL : Collections.list(packageURLs)) { + if (packageURL.getProtocol().equals("jar")) { + // build jar file name + String jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8"); + jarFileName = jarFileName.substring(5, jarFileName.indexOf("!")); + if (url == null ){ + names.addAll(extractClassName(packageName, jarFileName)); + } else { + String parentJarFileName = URLDecoder.decode(url.getFile(), "UTF-8"); + + if (jarFileName.startsWith(parentJarFileName)){ + names.addAll(extractClassName(packageName, jarFileName)); + } else { + //logger.error("[Modules] Jar {} is not a child of {}. Not loaded.", jarFileName, parentJarFileName); + } + } + } else { + if (url == null ) { + File folder = new File(packageURL.getFile()); + File[] contenuti = folder.listFiles(); + String entryName; + for (File actual : contenuti) { + entryName = actual.getName(); + entryName = entryName.substring(0, entryName.lastIndexOf('.')); + entryName = packageName+"/"+entryName; + entryName = entryName.replace("/", "."); + names.add(entryName); + } + } + } + } + return names; + } + + static List extractClassName(String packageName, String jarFileName) throws IOException { + List entryNames = new ArrayList(); + Enumeration jarEntries; + String entryName = ""; + logger.info("[Modules] Looking for Modules in file {}", jarFileName); + + JarFile jf = new JarFile(jarFileName); + jarEntries = jf.entries(); + while (jarEntries.hasMoreElements()) { + entryName = jarEntries.nextElement().getName(); + if (entryName.startsWith(packageName) && entryName.length() > packageName.length() + 5) { + entryName = entryName.substring(0, entryName.lastIndexOf('.')); + entryName = entryName.replace("/", "."); + logger.info("[Modules] Module {} found.", entryName); + entryNames.add(entryName); + } + } + jf.close(); + return entryNames; + } + +} + diff --git a/src/eu/engys/resources/application.properties b/src/eu/engys/resources/application.properties new file mode 100644 index 0000000..3a0606a --- /dev/null +++ b/src/eu/engys/resources/application.properties @@ -0,0 +1,34 @@ +################################################# +# # +# PROPERTIES FILE # +# # +################################################# + +# Solver Batch Run +batch.connection.max.tries 60 +batch.connection.wait.time 1000 +batch.stopped.wait.time 2000 +batch.running.wait.time 2000 + +batch.script.refresh.time 1000 +batch.script.kill.wait.time 5000 + +batch.monitor.dialog.max.row 10000 + +batch.log.wait.time 1000 + +# 3D rendering +3d.lock.intractive.time 2000 +3d.lock.intractive.memory 4096 +3d.transparency.memory 10240 + +# LOG FILES +max.log.rows 100000 + +# PATCHES +hide.empty.patches true + +# DEFAULT HOST FILE +default.hostfile.none false + +################################################# \ No newline at end of file diff --git a/src/eu/engys/resources/bundle.properties b/src/eu/engys/resources/bundle.properties new file mode 100644 index 0000000..dd7a143 --- /dev/null +++ b/src/eu/engys/resources/bundle.properties @@ -0,0 +1,604 @@ +# +# MESH +# + +mesh.create.label Create +mesh.create.tooltip Start mesher execution +mesh.create.icon eu/engys/resources/images/start16.png + +mesh.create.edit.label Edit Script +mesh.create.edit.tooltip Edit Create Mesh Script +mesh.create.edit.icon eu/engys/resources/images/pencil16.png + +mesh.check.label Check +mesh.check.tooltip Check Mesh +mesh.check.icon eu/engys/resources/images/tick16.png + +mesh.delete.label Delete +mesh.delete.tooltip Delete Mesh +mesh.delete.icon eu/engys/resources/images/erase16.png + +block.mesh.create.label Create +block.mesh.create.tooltip Create a Preview of The Block Mesh +block.mesh.create.icon eu/engys/resources/images/start16.png + +mesh.check.edit.label Edit Script +mesh.check.edit.tooltip Edit Check Mesh Script +mesh.check.edit.icon eu/engys/resources/images/pencil16.png + +mesh.batch.label Virtualise +mesh.batch.tooltip Use Geometry Objects To Simulate The Mesh +mesh.batch.icon eu/engys/resources/images/lightning.png + +mesh.options.label Options +mesh.options.tooltip Open Advanced Options Dialog +mesh.options.icon eu/engys/resources/images/cog16.png + +mesh.import.label Import +mesh.import.tooltip Import Mesh From 3rd Party +mesh.import.icon eu/engys/resources/images/import16.png + +mesh.export.label Export +mesh.export.tooltip Export Mesh For 3rd Party +mesh.export.icon eu/engys/resources/images/export16.png + +mesh.operations.label Operate +mesh.operations.tooltip Operate on 3D geometry items +mesh.operations.icon eu/engys/resources/images/toolbox16.png + +mesh.merge.label Merge +mesh.merge.tooltip Merge Mesh From 3rd Party + +mesh.stl.label +mesh.stl.icon eu/engys/resources/images/stl24.png +mesh.stl.tooltip STL +mesh.igs.label +mesh.igs.icon eu/engys/resources/images/igs24.png +mesh.igs.tooltip IGES/STEP +mesh.box.label +mesh.box.icon eu/engys/resources/images/cube24.png +mesh.box.tooltip Box +mesh.sphere.label +mesh.sphere.icon eu/engys/resources/images/sphere24.png +mesh.sphere.tooltip Sphere +mesh.cylinder.label +mesh.cylinder.icon eu/engys/resources/images/cylinder24.png +mesh.cylinder.tooltip Cylinder +mesh.plane.label +mesh.plane.icon eu/engys/resources/images/plane24.png +mesh.plane.tooltip Plane +mesh.ring.label +mesh.ring.icon eu/engys/resources/images/ring24.png +mesh.ring.tooltip Ring + +# +# CASE_SETUP +# + +best.practices.mesh.label Setup Mesh +best.practices.mesh.icon eu/engys/resources/images/tick16.png +best.practices.mesh.tooltip Setup Mesh + +best.practices.case.label Setup Case +best.practices.case.icon eu/engys/resources/images/tick16.png +best.practices.case.tooltip Setup Case + +best.practices.all.label Apply Defaults +best.practices.all.icon eu/engys/resources/images/tick16.png +best.practices.all.tooltip Setup Case + +casesetup.decompose.label Decompose +casesetup.decompose.tooltip Decompose Case + +calculate.frontal.area.label Calculate +calculate.frontal.area.tooltip Calculate frontal area from available vehicle geometry +calculate.frontal.area.icon eu/engys/resources/images/calculator16.png + +initialise.fields.icon eu/engys/resources/images/tick16.png +initialise.fields.label Initialise +initialise.fields.tooltip Initialise Fields + +parmap.fields.icon eu/engys/resources/images/parMap16.png +parmap.fields.label Map Fields +parmap.fields.tooltip Map Fields From External Case + +initialise.fields.edit.icon eu/engys/resources/images/pencil16.png +initialise.fields.edit.label Edit Script +initialise.fields.edit.tooltip Edit Script + +extrude.to.region.icon eu/engys/resources/images/extrude16.png +extrude.to.region.label Extrude To Region +extrude.to.region.tooltip Extrude To Region + +# +# RESULTS +# +results.export.label Create Report +results.export.icon eu/engys/resources/images/exportResults16.png +results.export.tooltip Create Report + +results.export.edit.label Edit Script +results.export.edit.icon eu/engys/resources/images/pencil16.png +results.export.edit.tooltip Edit Script + +results.export.edit.python.label Edit Results +results.export.edit.python.icon eu/engys/resources/images/pencil16.png +results.export.edit.python.tooltip Edit Results + +results.show.label Show Report +results.show.icon eu/engys/resources/images/showResults16.png +results.show.tooltip Show Report + +# +# SOLVER +# +solver.run.label Run +solver.run.tooltip Run +solver.run.icon eu/engys/resources/images/start16.png + +solver.run.edit.label Edit Script +solver.run.edit.tooltip Edit Solver Launcher Script +solver.run.edit.icon eu/engys/resources/images/pencil16.png + +solver.stop.label Stop +solver.stop.tooltip Try to gracefully stop solver execution. If not possible kills the solver process. +solver.stop.icon eu/engys/resources/images/stop16.png + +solver.run.all.label Run All +solver.run.all.tooltip Run All +solver.run.all.icon eu/engys/resources/images/startAll16.png + +solver.run.all.edit.label Edit Script +solver.run.all.edit.tooltip Edit Script +solver.run.all.edit.icon eu/engys/resources/images/pencil16.png + +solver.refresh.label Refresh Now +solver.refresh.tooltip Refresh Now + +solver.refresh.rate.tooltip Refresh Rate + +solver.show.log.terminal.label Terminal +solver.show.log.terminal.tooltip Display Log Terminal Window +solver.show.log.terminal.icon eu/engys/resources/images/console16.png + +# +# UPLOAD/DOWNLOAD +# +project.download.label Download +project.download.icon eu/engys/resources/images/download16.png +project.download.tooltip Download + +project.upload.label Upload +project.upload.icon eu/engys/resources/images/upload16.png +project.upload.tooltip Upload + +project.download.results.label Download +project.download.results.icon eu/engys/resources/images/download16.png +project.download.results.tooltip Download + +project.download.zip.label Download +project.download.zip.icon eu/engys/resources/images/download16.png +project.download.zip.tooltip Download + +project.upload.zip.label Upload +project.upload.zip.icon eu/engys/resources/images/upload16.png +project.upload.zip.tooltip Upload + +project.monitor.label Monitor +project.monitor.icon eu/engys/resources/images/upload16.png +project.monitor.tooltip Upload + +remote.edit.label Properties +remote.edit.icon eu/engys/resources/images/pencil16.png +remote.edit.tooltip Properties + +queue.edit.label Properties +queue.edit.icon eu/engys/resources/images/pencil16.png +queue.edit.tooltip Properties + + +# +# APPLICATION +# +application.create.label New +application.create.tooltip Create New Case +application.create.icon eu/engys/resources/images/new16.png + +application.save.label Save +application.save.tooltip Save Case +application.save.icon eu/engys/resources/images/save16.png + +application.saveAs.label Save As... +application.saveAs.tooltip Save Case With Different Name +application.saveAs.icon eu/engys/resources/images/saveAs16.png + +application.open.label Open +application.open.tooltip Open Case +application.open.icon eu/engys/resources/images/open16.png + +application.recent.label +application.recent.tooltip Open Recent Case +application.recent.icon eu/engys/resources/images/arrow_down16.png + +application.exit.label Exit +application.exit.tooltip Exit Application +application.exit.icon eu/engys/resources/images/exit16.png + +# +# 3D +# +3d.zoom.in.tooltip Zoom In +3d.zoom.in.icon eu/engys/resources/images/zoomIn16.png + +3d.zoom.out.tooltip Zoom Out +3d.zoom.out.icon eu/engys/resources/images/zoomOut16.png + +3d.zoom.reset.tooltip Reset Zoom +3d.zoom.reset.icon eu/engys/resources/images/zoomReset16.png + +3d.zoom.tobox.tooltip Zoom To Area +3d.zoom.tobox.icon eu/engys/resources/images/zoomToArea16.png + +3d.axis.xpos.tooltip +X +3d.axis.xpos.icon eu/engys/resources/images/XPos16.png + +3d.axis.xneg.tooltip -X +3d.axis.xneg.icon eu/engys/resources/images/XNeg16.png + +3d.axis.ypos.tooltip +Y +3d.axis.ypos.icon eu/engys/resources/images/YPos16.png + +3d.axis.yneg.tooltip -Y +3d.axis.yneg.icon eu/engys/resources/images/YNeg16.png + +3d.axis.zpos.tooltip +Z +3d.axis.zpos.icon eu/engys/resources/images/ZPos16.png + +3d.axis.zneg.tooltip -Z +3d.axis.zneg.icon eu/engys/resources/images/ZNeg16.png + +3d.view.surface.tooltip Surface +3d.view.surface.icon eu/engys/resources/images/shape_surface16.png + +3d.view.edges.tooltip Surface With Edges +3d.view.edges.icon eu/engys/resources/images/shape_surface_edges16.png + +3d.view.profile.tooltip Boundary Edges +3d.view.profile.icon eu/engys/resources/images/shape_boundary_edges16.png + +3d.view.wireframe.tooltip Wireframe +3d.view.wireframe.icon eu/engys/resources/images/shape_wireframe16.png + +3d.view.outline.tooltip Outline +3d.view.outline.icon eu/engys/resources/images/shape_outline16.png + +3d.load.mesh.tooltip Load External Mesh +3d.load.mesh.icon eu/engys/resources/images/externalMesh16.png + +3d.view.projections.perspective.tooltip Parallel Projection +3d.view.projections.perspective.icon eu/engys/resources/images/transform_perspective16.png +3d.view.projections.parallel.tooltip Perspective Projection +3d.view.projections.parallel.icon eu/engys/resources/images/transform_parallel16.png + +# +# WIDGETS +# +3d.widget.plane.tooltip Plane Widget +3d.widget.plane.icon eu/engys/resources/images/planeWidget16.png + +3d.widget.ruler.icon eu/engys/resources/images/rulerWidget16.png +3d.widget.ruler.tooltip Ruler Widget + +3d.widget.times.refresh.tooltip Reload Time Steps +3d.widget.times.tooltip Time Steps + +3d.widget.times.prev.icon eu/engys/resources/images/prev_grey16.png +3d.widget.times.prev.tooltip Display PREVIOUS Time + +3d.widget.times.next.icon eu/engys/resources/images/next_grey16.png +3d.widget.times.next.tooltip Display NEXT Time + +3d.widget.times.first.icon eu/engys/resources/images/first_grey16.png +3d.widget.times.first.tooltip Display FIRST Time + +3d.widget.times.last.icon eu/engys/resources/images/last_grey16.png +3d.widget.times.last.tooltip Display LAST Time + +3d.widget.times.refresh.icon eu/engys/resources/images/refresh_grey16.png +3d.widget.times.refresh.tooltip Rescan Times + +3d.widget.export.icon eu/engys/resources/images/exportImage16.png +3d.widget.export.tooltip Export PNG + +3d.widget.scalarbar.icon eu/engys/resources/images/scalarbar16.png +3d.widget.scalarbar.tooltip Scalar Bar + +3d.widget.editscalarbar.icon eu/engys/resources/images/scalarbarEdit16.png +3d.widget.editscalarbar.tooltip Edit Scalar Bar + +3d.widget.fields.tooltip Fields +3d.widget.fields.point.icon eu/engys/resources/images/pointField16.png +3d.widget.fields.cell.icon eu/engys/resources/images/cellField16.png + +3d.widget.feature.tooltip Split Surface Widget +3d.widget.feature.icon eu/engys/resources/images/table_select_big.png + +scalarbar.rainbow.icon eu/engys/resources/images/scalarbar/rainbow16.png +scalarbar.rainbow.inverted.icon eu/engys/resources/images/scalarbar/rainbowInverted16.png + +scalarbar.bluetored.hsv.icon eu/engys/resources/images/scalarbar/HSVBlueToRed16.png +scalarbar.redtoblue.hsv.icon eu/engys/resources/images/scalarbar/HSVRedToBlue16.png +scalarbar.bluetored.rgb.icon eu/engys/resources/images/scalarbar/RGBBlueToRed16.png +scalarbar.redtoblue.rgb.icon eu/engys/resources/images/scalarbar/RGBRedToBlue16.png +scalarbar.bluetored.div.icon eu/engys/resources/images/scalarbar/DIVBlueToRed16.png +scalarbar.redtoblue.div.icon eu/engys/resources/images/scalarbar/DIVRedToBlue16.png + +scalarbar.bluetoyellow.hsv.icon eu/engys/resources/images/scalarbar/HSVBlueToYellow16.png +scalarbar.yellowtoblue.hsv.icon eu/engys/resources/images/scalarbar/HSVYellowToBlue16.png +scalarbar.bluetoyellow.rgb.icon eu/engys/resources/images/scalarbar/RGBBlueToYellow16.png +scalarbar.yellowtoblue.rgb.icon eu/engys/resources/images/scalarbar/RGBYellowToBlue16.png +scalarbar.bluetoyellow.div.icon eu/engys/resources/images/scalarbar/DIVBlueToYellow16.png +scalarbar.yellowtoblue.div.icon eu/engys/resources/images/scalarbar/DIVYellowToBlue16.png + +scalarbar.blacktowhite.icon eu/engys/resources/images/scalarbar/blackToWhite16.png +scalarbar.whitetoblack.icon eu/engys/resources/images/scalarbar/whiteToBlack16.png + +scalarbar.lock.opened.icon eu/engys/resources/images/lockOpen16.png +scalarbar.lock.closed.icon eu/engys/resources/images/lockClose16.png + +slider.locked.icon eu/engys/resources/images/sliderLock16.png +slider.unlocked.icon eu/engys/resources/images/sliderUnlock16.png + +# +# CASE MANAGER +# + +case.manager.start.label Start +case.manager.start.icon eu/engys/resources/images/file16.png + +case.manager.stop.label Stop +case.manager.stop.icon eu/engys/resources/images/file16.png + + +case.manager.start.case.label Start +case.manager.start.case.icon eu/engys/resources/images/file16.png +case.manager.stop.case.label Stop +case.manager.stop.case.icon eu/engys/resources/images/file16.png +case.manager.open.case.label Open +case.manager.open.case.icon eu/engys/resources/images/file16.png +case.manager.view.case.label View +case.manager.view.case.icon eu/engys/resources/images/file16.png +case.manager.add.label Add +case.manager.add.icon eu/engys/resources/images/file16.png +case.manager.remove.label Remove +case.manager.remove.icon eu/engys/resources/images/file16.png +case.manager.clone.label Clone +case.manager.clone.icon eu/engys/resources/images/file16.png + +# +# EXTERNAL APPLICATIONS +# + +paraview.label ParaView +paraview.icon eu/engys/resources/images/paraview16.png +paraview.tooltip Open ParaView + +fieldview.label FieldView +fieldview.icon eu/engys/resources/images/fieldview16.png +fieldview.tooltip Open FieldView + +ensight.label EnSight +ensight.icon eu/engys/resources/images/ensight16.png +ensight.tooltip Open EnSight + +fluent.label Fluent +fluent.icon eu/engys/resources/images/fluent16.png +fluent.import.tooltip Import From Fluent +fluent.merge.tooltip Merge From Fluent +fluent.export.tooltip Export To Fluent + +starcd.label STAR-CD +starcd.icon eu/engys/resources/images/starcd16.png +starcd.tooltip Export To STAR-CD + +pointwise.label PointWise +pointwise.icon eu/engys/resources/images/gridgen16.png +pointwise.import.tooltip Import From PointWise +pointwise.merge.tooltip Merge From PointWise + +openfoam.label OpenFOAM +openfoam.icon eu/engys/resources/images/openFoam16.png +openfoam.import.tooltip Import From OpenFOAM +openfoam.merge.tooltip Merge From OpenFOAM + +# +# ICONS +# + +fit.boundingbox.icon eu/engys/resources/images/fit16.png +script.edit.icon eu/engys/resources/images/edit16.png +browse.file eu/engys/resources/images/browseFile16.png +save.log.file eu/engys/resources/images/fileSave16.png + +general.options.icon eu/engys/resources/images/cog16.png +import.icon eu/engys/resources/images/import16.png +merge.icon eu/engys/resources/images/merge16.png +decompose.icon eu/engys/resources/images/decompose16.png + +solver.start.icon eu/engys/resources/images/start16.png +solver.stop.icon eu/engys/resources/images/stop16.png +solver.refresh.icon eu/engys/resources/images/refresh16.png + +application.exit.big.icon eu/engys/resources/images/exit32.png + +console.stop.icon eu/engys/resources/images/stop16.png +console.copy.icon eu/engys/resources/images/copy16.png +console.email.icon eu/engys/resources/images/email16.png +console.browse.icon eu/engys/resources/images/browseFile16.png +console.scroll.icon eu/engys/resources/images/scroll_pane16.png +console.scroll.lock.icon eu/engys/resources/images/scroll_pane_lock16.png +console.tab.icon eu/engys/resources/images/console16.png +console.tab.close.icon eu/engys/resources/images/win_close16.png +console.tab.closeall.icon eu/engys/resources/images/win_closeAll16.png +console.tab.max.icon eu/engys/resources/images/win_maximize16.png +console.tab.restore.icon eu/engys/resources/images/win_restore16.png + +application.open.terminal.label Terminal +application.open.terminal.tooltip Open Terminal in case folder +application.open.terminal.icon eu/engys/resources/images/terminal16.png + +application.browse.case.label Browse +application.browse.case.tooltip Browse Case Folder +application.browse.case.icon eu/engys/resources/images/browseFolder16.png + +engys.logo eu/engys/resources/engys_logo.png +engys.logo.medium eu/engys/resources/engys_logo_medium.png +engys.logo.big eu/engys/resources/engys_logo_big.png +engys.logo.full eu/engys/resources/engys_logo_full.png +engys.terminal.icon eu/engys/resources/engys_terminal_logo.png + +helyx.banner eu/engys/resources/helyx_banner.png +helyx.startup eu/engys/resources/helyx_startup.png + +helyxsas.banner eu/engys/resources/helyxsas_banner.png +helyxsas.startup eu/engys/resources/helyxsas_startup.png + +helyxmesh.banner eu/engys/resources/helyxmesh_banner.png +helyxmesh.startup eu/engys/resources/helyxmesh_startup.png + +helyxos.banner eu/engys/resources/helyxos_banner.png +helyxos.startup eu/engys/resources/helyxos_startup.png +helyxos.faq eu/engys/resources/helyxos_faq.png +helyxos.products eu/engys/resources/helyxos_products.png +helyxos.helyx.box eu/engys/resources/helyxBox.png +helyxos.helyxos.box eu/engys/resources/helyxosBox.png +helyxos.elements.box eu/engys/resources/elementsBox.png + +streamlinesolutions.logo eu/engys/resources/elements_logo.png +streamlinesolutions.logo.medium eu/engys/resources/elements_logo_medium.png +streamlinesolutions.logo.big eu/engys/resources/elements_logo_big.png +streamlinesolutions.logo.full eu/engys/resources/elements_logo_full.png +elements.logo.full eu/engys/resources/elements_logo_full.png +streamlinesolutions.terminal.icon eu/engys/resources/streamlinesolutions_terminal_logo.png + +elements.banner eu/engys/resources/elements_banner.png +elements.background.image eu/engys/resources/elements_startup.png + +file.pdf eu/engys/resources/images/pdf16.png +file.excel eu/engys/resources/images/excel16.png +file.png eu/engys/resources/images/png16.png +info.icon eu/engys/resources/images/info16.png +license.icon eu/engys/resources/images/license16.png +preferences.icon eu/engys/resources/images/preferences16.png +monitoring.functions eu/engys/resources/images/monitoringFunction16.png +crosshair.icon eu/engys/resources/images/crosshair16.png + +chart.refresh.gray.icon eu/engys/resources/images/refreshChartGray32.png +chart.refresh.white.icon eu/engys/resources/images/refreshChartWhite32.png +search.table.icon eu/engys/resources/images/searchTable16.png + +helyx.gui.label HELYX GUI +helyxsas.gui.label HELYX-SAS GUI +helyxmesh.gui.label HELYX-MESH GUI + +helyx.core.label HELYX Core + +doc.helyx.gui.tooltip Open HELYX GUI Documentation +doc.helyx.core.tooltip Open HELYX Core Documentation +doc.helyxsas.gui.tooltip Open HELYX-SAS GUI Documentation +doc.helyxmesh.gui.tooltip Open HELYX-MESH GUI Documentation + +relnotes.helyx.gui.tooltip Open HELYX GUI Release Notes +relnotes.helyx.core.tooltip Open HELYX Core Release Notes +relnotes.helyxsas.gui.tooltip Open HELYX-SAS GUI Release Notes +relnotes.helyxmesh.gui.tooltip Open HELYX-MESH GUI Release Notes + +# +# FILE CHOOSER +# + +new.folder.label New Folder +new.folder.icon eu/engys/resources/images/folder_add16.png + +delete.file.label Delete File +delete.file.icon eu/engys/resources/images/folder_delete16.png + +extract.archive.label Extract +extract.archive.icon eu/engys/resources/images/extract16.png + +authenticator.browse Browse +authenticator.domain Domain +authenticator.enterCredentials Enter credentials +authenticator.enterCredentialsForUrl Enter credentials for URL {0} +authenticator.password Password: +authenticator.selectSshKey Select SSH key file +authenticator.sshKeyFile SSH key file: +authenticator.sshKeyFileDescription Your key has to be without paraphrase +authenticator.username User name: +browser.checkingSFtpLinksTask Checking for symbolic links +favorites.favorites Favorites +browser.folderContainsXElements Folder contains {0} elements +preview.loadedX Loaded {0}{1} +preview.loadedXOf Loaded {0} of {1} {2} +browser.loading Loading +browser.loading... Loading... +model.dateLastMod Last modification +model.name Name +model.size Size +model.type Type +preview.n/a N/A +nav.AddToFavorites Add current location to favorites +nav.goFolderUp Go folder up +nav.pathTooltip Path +nav.refreshActionLabelText Refresh +nav.ToolBarName Navigation tool bar +preview.enable Enable preview +preview.errorLoadingFile Error loading file +preview.fileContent File content: +preview.label Preview +authenticator.savePassword Save password +browser.skipCheckingLinks Skip checking links +favorites.systemLocations System locations +favorites.action Edit/rename +favorites.name Name: +favorites.url URL: +favorites.title Edit favorite +favorites.tooltip Edit selected favorite location + +arrowCircleDouble eu/engys/resources/images/update16.png +arrowTurn90 eu/engys/resources/images/arrow-turn16.png +computer eu/engys/resources/images/computer16.png +drive eu/engys/resources/images/drive16.png +sambaShare eu/engys/resources/images/share16.png +favorites.edit eu/engys/resources/images/edit16.png +file eu/engys/resources/images/file16.png +folderOpen eu/engys/resources/images/folder-open16.png +folderNew eu/engys/resources/images/folder_add16.png +folderZipper eu/engys/resources/images/zip16.png +minusButton eu/engys/resources/images/folder_delete16.png +jarIcon eu/engys/resources/images/jar16.png +networkCloud eu/engys/resources/images/network-cloud16.png +shortCut eu/engys/resources/images/shortcut16.png +star eu/engys/resources/images/favourites16.png +starPlus eu/engys/resources/images/favouritesAdd16.png +home eu/engys/resources/images/homeFolder16.png +desktop eu/engys/resources/images/desktop16.png +documents eu/engys/resources/images/documents16.png +engys.case eu/engys/resources/images/engys16.png +streamlinesolutions.case eu/engys/resources/images/streamlinesolutions16.png + +application.support.window.label Support +application.support.window.icon eu/engys/resources/images/info16.png +application.support.window.tooltip Obtain support for HELYX-OS + +application.connection.window.label Run Mode +application.connection.window.icon eu/engys/resources/images/runMode16.png +application.connection.window.tooltip Edit Connection Parameters + +# +# REPORT +# + +elements.report.watermark eu/engys/resources/report/elementsWatermark.png +elements.report.frontpage.watermark eu/engys/resources/report/elementsFrontPageWatermark.png +elements.report.logo.full eu/engys/resources/report/elements_logo_full.png diff --git a/src/eu/engys/resources/driver.pbs b/src/eu/engys/resources/driver.pbs new file mode 100644 index 0000000..13a3c83 --- /dev/null +++ b/src/eu/engys/resources/driver.pbs @@ -0,0 +1,12 @@ + +#module add openmpi/1.4.5 +#module load paraview + +#Initialize Environments +source $ENV_LOADER +source $PY_LOADER + +### Set OpenFOAM Environment +export WM_64=ON +export MPI_OPTIONS="-mca btl openib,sm,self" + \ No newline at end of file diff --git a/src/eu/engys/resources/elementsBox.png b/src/eu/engys/resources/elementsBox.png new file mode 100644 index 0000000..c25dd87 Binary files /dev/null and b/src/eu/engys/resources/elementsBox.png differ diff --git a/src/eu/engys/resources/elements_logo_full.png b/src/eu/engys/resources/elements_logo_full.png new file mode 100644 index 0000000..0be705b Binary files /dev/null and b/src/eu/engys/resources/elements_logo_full.png differ diff --git a/src/eu/engys/resources/engys_logo.png b/src/eu/engys/resources/engys_logo.png new file mode 100644 index 0000000..c7a0c9a Binary files /dev/null and b/src/eu/engys/resources/engys_logo.png differ diff --git a/src/eu/engys/resources/engys_logo_big.png b/src/eu/engys/resources/engys_logo_big.png new file mode 100644 index 0000000..044bb26 Binary files /dev/null and b/src/eu/engys/resources/engys_logo_big.png differ diff --git a/src/eu/engys/resources/engys_logo_full.png b/src/eu/engys/resources/engys_logo_full.png new file mode 100644 index 0000000..12555c5 Binary files /dev/null and b/src/eu/engys/resources/engys_logo_full.png differ diff --git a/src/eu/engys/resources/engys_logo_medium.png b/src/eu/engys/resources/engys_logo_medium.png new file mode 100644 index 0000000..d33f1e8 Binary files /dev/null and b/src/eu/engys/resources/engys_logo_medium.png differ diff --git a/src/eu/engys/resources/helyxBox.png b/src/eu/engys/resources/helyxBox.png new file mode 100644 index 0000000..5645eab Binary files /dev/null and b/src/eu/engys/resources/helyxBox.png differ diff --git a/src/eu/engys/resources/helyxosBox.png b/src/eu/engys/resources/helyxosBox.png new file mode 100644 index 0000000..facf81a Binary files /dev/null and b/src/eu/engys/resources/helyxosBox.png differ diff --git a/src/eu/engys/resources/helyxos_banner.png b/src/eu/engys/resources/helyxos_banner.png new file mode 100644 index 0000000..853e9b0 Binary files /dev/null and b/src/eu/engys/resources/helyxos_banner.png differ diff --git a/src/eu/engys/resources/helyxos_faq.png b/src/eu/engys/resources/helyxos_faq.png new file mode 100644 index 0000000..3f4c4e4 Binary files /dev/null and b/src/eu/engys/resources/helyxos_faq.png differ diff --git a/src/eu/engys/resources/helyxos_products.png b/src/eu/engys/resources/helyxos_products.png new file mode 100644 index 0000000..682ea2b Binary files /dev/null and b/src/eu/engys/resources/helyxos_products.png differ diff --git a/src/eu/engys/resources/helyxos_startup.png b/src/eu/engys/resources/helyxos_startup.png new file mode 100644 index 0000000..85c2428 Binary files /dev/null and b/src/eu/engys/resources/helyxos_startup.png differ diff --git a/src/eu/engys/resources/images/XNeg16.png b/src/eu/engys/resources/images/XNeg16.png new file mode 100644 index 0000000..17957b8 Binary files /dev/null and b/src/eu/engys/resources/images/XNeg16.png differ diff --git a/src/eu/engys/resources/images/XPos16.png b/src/eu/engys/resources/images/XPos16.png new file mode 100644 index 0000000..71cb8cb Binary files /dev/null and b/src/eu/engys/resources/images/XPos16.png differ diff --git a/src/eu/engys/resources/images/YNeg16.png b/src/eu/engys/resources/images/YNeg16.png new file mode 100644 index 0000000..59cb6f0 Binary files /dev/null and b/src/eu/engys/resources/images/YNeg16.png differ diff --git a/src/eu/engys/resources/images/YPos16.png b/src/eu/engys/resources/images/YPos16.png new file mode 100644 index 0000000..edefecc Binary files /dev/null and b/src/eu/engys/resources/images/YPos16.png differ diff --git a/src/eu/engys/resources/images/ZNeg16.png b/src/eu/engys/resources/images/ZNeg16.png new file mode 100644 index 0000000..3b8d324 Binary files /dev/null and b/src/eu/engys/resources/images/ZNeg16.png differ diff --git a/src/eu/engys/resources/images/ZPos16.png b/src/eu/engys/resources/images/ZPos16.png new file mode 100644 index 0000000..8dd664d Binary files /dev/null and b/src/eu/engys/resources/images/ZPos16.png differ diff --git a/src/eu/engys/resources/images/application_view_list16.png b/src/eu/engys/resources/images/application_view_list16.png new file mode 100644 index 0000000..8a08b52 Binary files /dev/null and b/src/eu/engys/resources/images/application_view_list16.png differ diff --git a/src/eu/engys/resources/images/arrow-turn16.png b/src/eu/engys/resources/images/arrow-turn16.png new file mode 100644 index 0000000..425dcb2 Binary files /dev/null and b/src/eu/engys/resources/images/arrow-turn16.png differ diff --git a/src/eu/engys/resources/images/arrow_down16.png b/src/eu/engys/resources/images/arrow_down16.png new file mode 100644 index 0000000..9dbe8f6 Binary files /dev/null and b/src/eu/engys/resources/images/arrow_down16.png differ diff --git a/src/eu/engys/resources/images/browseFile16.png b/src/eu/engys/resources/images/browseFile16.png new file mode 100644 index 0000000..ef8c5e2 Binary files /dev/null and b/src/eu/engys/resources/images/browseFile16.png differ diff --git a/src/eu/engys/resources/images/browseFolder16.png b/src/eu/engys/resources/images/browseFolder16.png new file mode 100644 index 0000000..c830338 Binary files /dev/null and b/src/eu/engys/resources/images/browseFolder16.png differ diff --git a/src/eu/engys/resources/images/calculator16.png b/src/eu/engys/resources/images/calculator16.png new file mode 100644 index 0000000..005fdd1 Binary files /dev/null and b/src/eu/engys/resources/images/calculator16.png differ diff --git a/src/eu/engys/resources/images/cellField16.png b/src/eu/engys/resources/images/cellField16.png new file mode 100644 index 0000000..44279dc Binary files /dev/null and b/src/eu/engys/resources/images/cellField16.png differ diff --git a/src/eu/engys/resources/images/clip24.png b/src/eu/engys/resources/images/clip24.png new file mode 100644 index 0000000..986e1eb Binary files /dev/null and b/src/eu/engys/resources/images/clip24.png differ diff --git a/src/eu/engys/resources/images/cog16.png b/src/eu/engys/resources/images/cog16.png new file mode 100644 index 0000000..8f4eeb7 Binary files /dev/null and b/src/eu/engys/resources/images/cog16.png differ diff --git a/src/eu/engys/resources/images/computer16.png b/src/eu/engys/resources/images/computer16.png new file mode 100644 index 0000000..d07d5fd Binary files /dev/null and b/src/eu/engys/resources/images/computer16.png differ diff --git a/src/eu/engys/resources/images/console16.png b/src/eu/engys/resources/images/console16.png new file mode 100644 index 0000000..36f1da9 Binary files /dev/null and b/src/eu/engys/resources/images/console16.png differ diff --git a/src/eu/engys/resources/images/copy16.png b/src/eu/engys/resources/images/copy16.png new file mode 100644 index 0000000..7ad7b0d Binary files /dev/null and b/src/eu/engys/resources/images/copy16.png differ diff --git a/src/eu/engys/resources/images/crinkle24.png b/src/eu/engys/resources/images/crinkle24.png new file mode 100644 index 0000000..94430b5 Binary files /dev/null and b/src/eu/engys/resources/images/crinkle24.png differ diff --git a/src/eu/engys/resources/images/crosshair16.png b/src/eu/engys/resources/images/crosshair16.png new file mode 100644 index 0000000..2875a7c Binary files /dev/null and b/src/eu/engys/resources/images/crosshair16.png differ diff --git a/src/eu/engys/resources/images/cube24.png b/src/eu/engys/resources/images/cube24.png new file mode 100644 index 0000000..5329b95 Binary files /dev/null and b/src/eu/engys/resources/images/cube24.png differ diff --git a/src/eu/engys/resources/images/cursor16.png b/src/eu/engys/resources/images/cursor16.png new file mode 100644 index 0000000..0382407 Binary files /dev/null and b/src/eu/engys/resources/images/cursor16.png differ diff --git a/src/eu/engys/resources/images/cyclic16.png b/src/eu/engys/resources/images/cyclic16.png new file mode 100644 index 0000000..7eb7362 Binary files /dev/null and b/src/eu/engys/resources/images/cyclic16.png differ diff --git a/src/eu/engys/resources/images/cyclicAMI16.png b/src/eu/engys/resources/images/cyclicAMI16.png new file mode 100644 index 0000000..3154a2a Binary files /dev/null and b/src/eu/engys/resources/images/cyclicAMI16.png differ diff --git a/src/eu/engys/resources/images/cylinder24.png b/src/eu/engys/resources/images/cylinder24.png new file mode 100644 index 0000000..6b5e3d0 Binary files /dev/null and b/src/eu/engys/resources/images/cylinder24.png differ diff --git a/src/eu/engys/resources/images/decompose16.png b/src/eu/engys/resources/images/decompose16.png new file mode 100644 index 0000000..e611bd5 Binary files /dev/null and b/src/eu/engys/resources/images/decompose16.png differ diff --git a/src/eu/engys/resources/images/desktop16.png b/src/eu/engys/resources/images/desktop16.png new file mode 100644 index 0000000..6bee5ee Binary files /dev/null and b/src/eu/engys/resources/images/desktop16.png differ diff --git a/src/eu/engys/resources/images/documents16.png b/src/eu/engys/resources/images/documents16.png new file mode 100644 index 0000000..502122a Binary files /dev/null and b/src/eu/engys/resources/images/documents16.png differ diff --git a/src/eu/engys/resources/images/download16.png b/src/eu/engys/resources/images/download16.png new file mode 100644 index 0000000..9553b2d Binary files /dev/null and b/src/eu/engys/resources/images/download16.png differ diff --git a/src/eu/engys/resources/images/downloadZip16.png b/src/eu/engys/resources/images/downloadZip16.png new file mode 100644 index 0000000..1920b1b Binary files /dev/null and b/src/eu/engys/resources/images/downloadZip16.png differ diff --git a/src/eu/engys/resources/images/drive16.png b/src/eu/engys/resources/images/drive16.png new file mode 100644 index 0000000..e3979a8 Binary files /dev/null and b/src/eu/engys/resources/images/drive16.png differ diff --git a/src/eu/engys/resources/images/edit16.png b/src/eu/engys/resources/images/edit16.png new file mode 100644 index 0000000..bca3433 Binary files /dev/null and b/src/eu/engys/resources/images/edit16.png differ diff --git a/src/eu/engys/resources/images/email16.png b/src/eu/engys/resources/images/email16.png new file mode 100644 index 0000000..8327873 Binary files /dev/null and b/src/eu/engys/resources/images/email16.png differ diff --git a/src/eu/engys/resources/images/empty16.png b/src/eu/engys/resources/images/empty16.png new file mode 100644 index 0000000..47c761c Binary files /dev/null and b/src/eu/engys/resources/images/empty16.png differ diff --git a/src/eu/engys/resources/images/engys16.png b/src/eu/engys/resources/images/engys16.png new file mode 100644 index 0000000..3d364a0 Binary files /dev/null and b/src/eu/engys/resources/images/engys16.png differ diff --git a/src/eu/engys/resources/images/ensight16.png b/src/eu/engys/resources/images/ensight16.png new file mode 100644 index 0000000..74a0d9f Binary files /dev/null and b/src/eu/engys/resources/images/ensight16.png differ diff --git a/src/eu/engys/resources/images/erase16.png b/src/eu/engys/resources/images/erase16.png new file mode 100644 index 0000000..f2eca21 Binary files /dev/null and b/src/eu/engys/resources/images/erase16.png differ diff --git a/src/eu/engys/resources/images/excel16.png b/src/eu/engys/resources/images/excel16.png new file mode 100644 index 0000000..3cf3f34 Binary files /dev/null and b/src/eu/engys/resources/images/excel16.png differ diff --git a/src/eu/engys/resources/images/exit16.png b/src/eu/engys/resources/images/exit16.png new file mode 100644 index 0000000..1903e23 Binary files /dev/null and b/src/eu/engys/resources/images/exit16.png differ diff --git a/src/eu/engys/resources/images/exit32.png b/src/eu/engys/resources/images/exit32.png new file mode 100644 index 0000000..a65ed58 Binary files /dev/null and b/src/eu/engys/resources/images/exit32.png differ diff --git a/src/eu/engys/resources/images/export16.png b/src/eu/engys/resources/images/export16.png new file mode 100644 index 0000000..e0df9e6 Binary files /dev/null and b/src/eu/engys/resources/images/export16.png differ diff --git a/src/eu/engys/resources/images/exportImage16.png b/src/eu/engys/resources/images/exportImage16.png new file mode 100644 index 0000000..07af88b Binary files /dev/null and b/src/eu/engys/resources/images/exportImage16.png differ diff --git a/src/eu/engys/resources/images/exportResults16.png b/src/eu/engys/resources/images/exportResults16.png new file mode 100644 index 0000000..5cc236a Binary files /dev/null and b/src/eu/engys/resources/images/exportResults16.png differ diff --git a/src/eu/engys/resources/images/externalMesh16.png b/src/eu/engys/resources/images/externalMesh16.png new file mode 100644 index 0000000..650396f Binary files /dev/null and b/src/eu/engys/resources/images/externalMesh16.png differ diff --git a/src/eu/engys/resources/images/extract16.png b/src/eu/engys/resources/images/extract16.png new file mode 100644 index 0000000..672b4a4 Binary files /dev/null and b/src/eu/engys/resources/images/extract16.png differ diff --git a/src/eu/engys/resources/images/extrude16.png b/src/eu/engys/resources/images/extrude16.png new file mode 100644 index 0000000..94dbad7 Binary files /dev/null and b/src/eu/engys/resources/images/extrude16.png differ diff --git a/src/eu/engys/resources/images/eye16.png b/src/eu/engys/resources/images/eye16.png new file mode 100644 index 0000000..973a4a0 Binary files /dev/null and b/src/eu/engys/resources/images/eye16.png differ diff --git a/src/eu/engys/resources/images/eye_no16.png b/src/eu/engys/resources/images/eye_no16.png new file mode 100644 index 0000000..ce6ed31 Binary files /dev/null and b/src/eu/engys/resources/images/eye_no16.png differ diff --git a/src/eu/engys/resources/images/favourites16.png b/src/eu/engys/resources/images/favourites16.png new file mode 100644 index 0000000..ae8fded Binary files /dev/null and b/src/eu/engys/resources/images/favourites16.png differ diff --git a/src/eu/engys/resources/images/favouritesAdd16.png b/src/eu/engys/resources/images/favouritesAdd16.png new file mode 100644 index 0000000..883e4de Binary files /dev/null and b/src/eu/engys/resources/images/favouritesAdd16.png differ diff --git a/src/eu/engys/resources/images/fieldview16.png b/src/eu/engys/resources/images/fieldview16.png new file mode 100644 index 0000000..3d5b7dd Binary files /dev/null and b/src/eu/engys/resources/images/fieldview16.png differ diff --git a/src/eu/engys/resources/images/file16.png b/src/eu/engys/resources/images/file16.png new file mode 100644 index 0000000..95a4185 Binary files /dev/null and b/src/eu/engys/resources/images/file16.png differ diff --git a/src/eu/engys/resources/images/fileSave16.png b/src/eu/engys/resources/images/fileSave16.png new file mode 100644 index 0000000..b08686d Binary files /dev/null and b/src/eu/engys/resources/images/fileSave16.png differ diff --git a/src/eu/engys/resources/images/first16.png b/src/eu/engys/resources/images/first16.png new file mode 100644 index 0000000..172a73c Binary files /dev/null and b/src/eu/engys/resources/images/first16.png differ diff --git a/src/eu/engys/resources/images/first_grey16.png b/src/eu/engys/resources/images/first_grey16.png new file mode 100644 index 0000000..1319cbb Binary files /dev/null and b/src/eu/engys/resources/images/first_grey16.png differ diff --git a/src/eu/engys/resources/images/fit16.png b/src/eu/engys/resources/images/fit16.png new file mode 100644 index 0000000..d4625ec Binary files /dev/null and b/src/eu/engys/resources/images/fit16.png differ diff --git a/src/eu/engys/resources/images/fluent16.png b/src/eu/engys/resources/images/fluent16.png new file mode 100644 index 0000000..c93510a Binary files /dev/null and b/src/eu/engys/resources/images/fluent16.png differ diff --git a/src/eu/engys/resources/images/folder-open16.png b/src/eu/engys/resources/images/folder-open16.png new file mode 100644 index 0000000..f1ed9ab Binary files /dev/null and b/src/eu/engys/resources/images/folder-open16.png differ diff --git a/src/eu/engys/resources/images/folder_add16.png b/src/eu/engys/resources/images/folder_add16.png new file mode 100644 index 0000000..83761c2 Binary files /dev/null and b/src/eu/engys/resources/images/folder_add16.png differ diff --git a/src/eu/engys/resources/images/folder_delete16.png b/src/eu/engys/resources/images/folder_delete16.png new file mode 100644 index 0000000..bb56a9e Binary files /dev/null and b/src/eu/engys/resources/images/folder_delete16.png differ diff --git a/src/eu/engys/resources/images/freeSurface16.png b/src/eu/engys/resources/images/freeSurface16.png new file mode 100644 index 0000000..7215c45 Binary files /dev/null and b/src/eu/engys/resources/images/freeSurface16.png differ diff --git a/src/eu/engys/resources/images/gridgen16.png b/src/eu/engys/resources/images/gridgen16.png new file mode 100644 index 0000000..80851b4 Binary files /dev/null and b/src/eu/engys/resources/images/gridgen16.png differ diff --git a/src/eu/engys/resources/images/homeFolder16.png b/src/eu/engys/resources/images/homeFolder16.png new file mode 100644 index 0000000..2cd2841 Binary files /dev/null and b/src/eu/engys/resources/images/homeFolder16.png differ diff --git a/src/eu/engys/resources/images/igs24.png b/src/eu/engys/resources/images/igs24.png new file mode 100644 index 0000000..10e4c45 Binary files /dev/null and b/src/eu/engys/resources/images/igs24.png differ diff --git a/src/eu/engys/resources/images/import16.png b/src/eu/engys/resources/images/import16.png new file mode 100644 index 0000000..691f6e0 Binary files /dev/null and b/src/eu/engys/resources/images/import16.png differ diff --git a/src/eu/engys/resources/images/import_disk16.png b/src/eu/engys/resources/images/import_disk16.png new file mode 100644 index 0000000..9e98b6f Binary files /dev/null and b/src/eu/engys/resources/images/import_disk16.png differ diff --git a/src/eu/engys/resources/images/info16.png b/src/eu/engys/resources/images/info16.png new file mode 100644 index 0000000..85c1876 Binary files /dev/null and b/src/eu/engys/resources/images/info16.png differ diff --git a/src/eu/engys/resources/images/inlet16.png b/src/eu/engys/resources/images/inlet16.png new file mode 100644 index 0000000..fbdc48f Binary files /dev/null and b/src/eu/engys/resources/images/inlet16.png differ diff --git a/src/eu/engys/resources/images/jar16.png b/src/eu/engys/resources/images/jar16.png new file mode 100644 index 0000000..8662344 Binary files /dev/null and b/src/eu/engys/resources/images/jar16.png differ diff --git a/src/eu/engys/resources/images/last16.png b/src/eu/engys/resources/images/last16.png new file mode 100644 index 0000000..88dc738 Binary files /dev/null and b/src/eu/engys/resources/images/last16.png differ diff --git a/src/eu/engys/resources/images/last_grey16.png b/src/eu/engys/resources/images/last_grey16.png new file mode 100644 index 0000000..9f5a749 Binary files /dev/null and b/src/eu/engys/resources/images/last_grey16.png differ diff --git a/src/eu/engys/resources/images/license16.png b/src/eu/engys/resources/images/license16.png new file mode 100644 index 0000000..7174b5d Binary files /dev/null and b/src/eu/engys/resources/images/license16.png differ diff --git a/src/eu/engys/resources/images/lightbulb16.png b/src/eu/engys/resources/images/lightbulb16.png new file mode 100644 index 0000000..117285f Binary files /dev/null and b/src/eu/engys/resources/images/lightbulb16.png differ diff --git a/src/eu/engys/resources/images/lightbulb_off16.png b/src/eu/engys/resources/images/lightbulb_off16.png new file mode 100644 index 0000000..5cf32c0 Binary files /dev/null and b/src/eu/engys/resources/images/lightbulb_off16.png differ diff --git a/src/eu/engys/resources/images/lightning.png b/src/eu/engys/resources/images/lightning.png new file mode 100644 index 0000000..c933224 Binary files /dev/null and b/src/eu/engys/resources/images/lightning.png differ diff --git a/src/eu/engys/resources/images/lockClose16.png b/src/eu/engys/resources/images/lockClose16.png new file mode 100644 index 0000000..ddf83d9 Binary files /dev/null and b/src/eu/engys/resources/images/lockClose16.png differ diff --git a/src/eu/engys/resources/images/lockOpen16.png b/src/eu/engys/resources/images/lockOpen16.png new file mode 100644 index 0000000..b09e418 Binary files /dev/null and b/src/eu/engys/resources/images/lockOpen16.png differ diff --git a/src/eu/engys/resources/images/merge16.png b/src/eu/engys/resources/images/merge16.png new file mode 100644 index 0000000..5a066e5 Binary files /dev/null and b/src/eu/engys/resources/images/merge16.png differ diff --git a/src/eu/engys/resources/images/merge_disk16.png b/src/eu/engys/resources/images/merge_disk16.png new file mode 100644 index 0000000..113927e Binary files /dev/null and b/src/eu/engys/resources/images/merge_disk16.png differ diff --git a/src/eu/engys/resources/images/monitor16.png b/src/eu/engys/resources/images/monitor16.png new file mode 100644 index 0000000..e4ba988 Binary files /dev/null and b/src/eu/engys/resources/images/monitor16.png differ diff --git a/src/eu/engys/resources/images/monitoringFunction16.png b/src/eu/engys/resources/images/monitoringFunction16.png new file mode 100644 index 0000000..fafb7e1 Binary files /dev/null and b/src/eu/engys/resources/images/monitoringFunction16.png differ diff --git a/src/eu/engys/resources/images/network-cloud16.png b/src/eu/engys/resources/images/network-cloud16.png new file mode 100644 index 0000000..51fce7e Binary files /dev/null and b/src/eu/engys/resources/images/network-cloud16.png differ diff --git a/src/eu/engys/resources/images/new16.png b/src/eu/engys/resources/images/new16.png new file mode 100644 index 0000000..018816b Binary files /dev/null and b/src/eu/engys/resources/images/new16.png differ diff --git a/src/eu/engys/resources/images/next16.png b/src/eu/engys/resources/images/next16.png new file mode 100644 index 0000000..184be23 Binary files /dev/null and b/src/eu/engys/resources/images/next16.png differ diff --git a/src/eu/engys/resources/images/next_grey16.png b/src/eu/engys/resources/images/next_grey16.png new file mode 100644 index 0000000..ce7e4cc Binary files /dev/null and b/src/eu/engys/resources/images/next_grey16.png differ diff --git a/src/eu/engys/resources/images/open16.png b/src/eu/engys/resources/images/open16.png new file mode 100644 index 0000000..f1ed9ab Binary files /dev/null and b/src/eu/engys/resources/images/open16.png differ diff --git a/src/eu/engys/resources/images/openFoam16.png b/src/eu/engys/resources/images/openFoam16.png new file mode 100644 index 0000000..55293f8 Binary files /dev/null and b/src/eu/engys/resources/images/openFoam16.png differ diff --git a/src/eu/engys/resources/images/opening16.png b/src/eu/engys/resources/images/opening16.png new file mode 100644 index 0000000..2d868eb Binary files /dev/null and b/src/eu/engys/resources/images/opening16.png differ diff --git a/src/eu/engys/resources/images/outlet16.png b/src/eu/engys/resources/images/outlet16.png new file mode 100644 index 0000000..ac53425 Binary files /dev/null and b/src/eu/engys/resources/images/outlet16.png differ diff --git a/src/eu/engys/resources/images/parMap16.png b/src/eu/engys/resources/images/parMap16.png new file mode 100644 index 0000000..a442ed2 Binary files /dev/null and b/src/eu/engys/resources/images/parMap16.png differ diff --git a/src/eu/engys/resources/images/paraview16.png b/src/eu/engys/resources/images/paraview16.png new file mode 100644 index 0000000..153fd84 Binary files /dev/null and b/src/eu/engys/resources/images/paraview16.png differ diff --git a/src/eu/engys/resources/images/patch16.png b/src/eu/engys/resources/images/patch16.png new file mode 100644 index 0000000..2d868eb Binary files /dev/null and b/src/eu/engys/resources/images/patch16.png differ diff --git a/src/eu/engys/resources/images/pdf16.png b/src/eu/engys/resources/images/pdf16.png new file mode 100644 index 0000000..ef52e6a Binary files /dev/null and b/src/eu/engys/resources/images/pdf16.png differ diff --git a/src/eu/engys/resources/images/pencil16.png b/src/eu/engys/resources/images/pencil16.png new file mode 100644 index 0000000..d5ba3d5 Binary files /dev/null and b/src/eu/engys/resources/images/pencil16.png differ diff --git a/src/eu/engys/resources/images/plane24.png b/src/eu/engys/resources/images/plane24.png new file mode 100644 index 0000000..9f646e8 Binary files /dev/null and b/src/eu/engys/resources/images/plane24.png differ diff --git a/src/eu/engys/resources/images/planeWidget16.png b/src/eu/engys/resources/images/planeWidget16.png new file mode 100644 index 0000000..5adbbef Binary files /dev/null and b/src/eu/engys/resources/images/planeWidget16.png differ diff --git a/src/eu/engys/resources/images/png16.png b/src/eu/engys/resources/images/png16.png new file mode 100644 index 0000000..0e2f0e9 Binary files /dev/null and b/src/eu/engys/resources/images/png16.png differ diff --git a/src/eu/engys/resources/images/pointField16.png b/src/eu/engys/resources/images/pointField16.png new file mode 100644 index 0000000..b9c8e02 Binary files /dev/null and b/src/eu/engys/resources/images/pointField16.png differ diff --git a/src/eu/engys/resources/images/preferences16.png b/src/eu/engys/resources/images/preferences16.png new file mode 100644 index 0000000..305e2ca Binary files /dev/null and b/src/eu/engys/resources/images/preferences16.png differ diff --git a/src/eu/engys/resources/images/prev_grey16.png b/src/eu/engys/resources/images/prev_grey16.png new file mode 100644 index 0000000..aa7d07a Binary files /dev/null and b/src/eu/engys/resources/images/prev_grey16.png differ diff --git a/src/eu/engys/resources/images/reconstruct16.png b/src/eu/engys/resources/images/reconstruct16.png new file mode 100644 index 0000000..51e7de9 Binary files /dev/null and b/src/eu/engys/resources/images/reconstruct16.png differ diff --git a/src/eu/engys/resources/images/refresh16.png b/src/eu/engys/resources/images/refresh16.png new file mode 100644 index 0000000..bc323e3 Binary files /dev/null and b/src/eu/engys/resources/images/refresh16.png differ diff --git a/src/eu/engys/resources/images/refreshChartGray32.png b/src/eu/engys/resources/images/refreshChartGray32.png new file mode 100644 index 0000000..5590f12 Binary files /dev/null and b/src/eu/engys/resources/images/refreshChartGray32.png differ diff --git a/src/eu/engys/resources/images/refreshChartWhite32.png b/src/eu/engys/resources/images/refreshChartWhite32.png new file mode 100644 index 0000000..0ccce8d Binary files /dev/null and b/src/eu/engys/resources/images/refreshChartWhite32.png differ diff --git a/src/eu/engys/resources/images/refresh_grey16.png b/src/eu/engys/resources/images/refresh_grey16.png new file mode 100644 index 0000000..b9717ad Binary files /dev/null and b/src/eu/engys/resources/images/refresh_grey16.png differ diff --git a/src/eu/engys/resources/images/ring24.png b/src/eu/engys/resources/images/ring24.png new file mode 100644 index 0000000..a75b251 Binary files /dev/null and b/src/eu/engys/resources/images/ring24.png differ diff --git a/src/eu/engys/resources/images/rulerWidget16.png b/src/eu/engys/resources/images/rulerWidget16.png new file mode 100644 index 0000000..38c6c42 Binary files /dev/null and b/src/eu/engys/resources/images/rulerWidget16.png differ diff --git a/src/eu/engys/resources/images/runMode16.png b/src/eu/engys/resources/images/runMode16.png new file mode 100644 index 0000000..4d8bb59 Binary files /dev/null and b/src/eu/engys/resources/images/runMode16.png differ diff --git a/src/eu/engys/resources/images/save16.png b/src/eu/engys/resources/images/save16.png new file mode 100644 index 0000000..d0d400e Binary files /dev/null and b/src/eu/engys/resources/images/save16.png differ diff --git a/src/eu/engys/resources/images/saveAs16.png b/src/eu/engys/resources/images/saveAs16.png new file mode 100644 index 0000000..48c5ae7 Binary files /dev/null and b/src/eu/engys/resources/images/saveAs16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/DIVBlueToRed16.png b/src/eu/engys/resources/images/scalarbar/DIVBlueToRed16.png new file mode 100644 index 0000000..c4819af Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/DIVBlueToRed16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/DIVBlueToYellow16.png b/src/eu/engys/resources/images/scalarbar/DIVBlueToYellow16.png new file mode 100644 index 0000000..9d98932 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/DIVBlueToYellow16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/DIVRedToBlue16.png b/src/eu/engys/resources/images/scalarbar/DIVRedToBlue16.png new file mode 100644 index 0000000..525aa58 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/DIVRedToBlue16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/DIVYellowToBlue16.png b/src/eu/engys/resources/images/scalarbar/DIVYellowToBlue16.png new file mode 100644 index 0000000..13fcbd8 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/DIVYellowToBlue16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/HSVBlueToRed16.png b/src/eu/engys/resources/images/scalarbar/HSVBlueToRed16.png new file mode 100644 index 0000000..b360fc4 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/HSVBlueToRed16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/HSVBlueToYellow16.png b/src/eu/engys/resources/images/scalarbar/HSVBlueToYellow16.png new file mode 100644 index 0000000..6877523 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/HSVBlueToYellow16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/HSVRedToBlue16.png b/src/eu/engys/resources/images/scalarbar/HSVRedToBlue16.png new file mode 100644 index 0000000..1f8d74e Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/HSVRedToBlue16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/HSVYellowToBlue16.png b/src/eu/engys/resources/images/scalarbar/HSVYellowToBlue16.png new file mode 100644 index 0000000..d269202 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/HSVYellowToBlue16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/RGBBlueToRed16.png b/src/eu/engys/resources/images/scalarbar/RGBBlueToRed16.png new file mode 100644 index 0000000..3f6d418 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/RGBBlueToRed16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/RGBBlueToYellow16.png b/src/eu/engys/resources/images/scalarbar/RGBBlueToYellow16.png new file mode 100644 index 0000000..08b321d Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/RGBBlueToYellow16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/RGBRedToBlue16.png b/src/eu/engys/resources/images/scalarbar/RGBRedToBlue16.png new file mode 100644 index 0000000..13b74d3 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/RGBRedToBlue16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/RGBYellowToBlue16.png b/src/eu/engys/resources/images/scalarbar/RGBYellowToBlue16.png new file mode 100644 index 0000000..0426420 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/RGBYellowToBlue16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/blackToWhite16.png b/src/eu/engys/resources/images/scalarbar/blackToWhite16.png new file mode 100644 index 0000000..326d480 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/blackToWhite16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/rainbow16.png b/src/eu/engys/resources/images/scalarbar/rainbow16.png new file mode 100644 index 0000000..57c384b Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/rainbow16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/rainbowInverted16.png b/src/eu/engys/resources/images/scalarbar/rainbowInverted16.png new file mode 100644 index 0000000..ad2f41b Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/rainbowInverted16.png differ diff --git a/src/eu/engys/resources/images/scalarbar/whiteToBlack16.png b/src/eu/engys/resources/images/scalarbar/whiteToBlack16.png new file mode 100644 index 0000000..db23658 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar/whiteToBlack16.png differ diff --git a/src/eu/engys/resources/images/scalarbar16.png b/src/eu/engys/resources/images/scalarbar16.png new file mode 100644 index 0000000..4af75ed Binary files /dev/null and b/src/eu/engys/resources/images/scalarbar16.png differ diff --git a/src/eu/engys/resources/images/scalarbarEdit16.png b/src/eu/engys/resources/images/scalarbarEdit16.png new file mode 100644 index 0000000..07288f3 Binary files /dev/null and b/src/eu/engys/resources/images/scalarbarEdit16.png differ diff --git a/src/eu/engys/resources/images/scroll_pane16.png b/src/eu/engys/resources/images/scroll_pane16.png new file mode 100644 index 0000000..d74ab0a Binary files /dev/null and b/src/eu/engys/resources/images/scroll_pane16.png differ diff --git a/src/eu/engys/resources/images/scroll_pane_lock16.png b/src/eu/engys/resources/images/scroll_pane_lock16.png new file mode 100644 index 0000000..347577b Binary files /dev/null and b/src/eu/engys/resources/images/scroll_pane_lock16.png differ diff --git a/src/eu/engys/resources/images/searchTable16.png b/src/eu/engys/resources/images/searchTable16.png new file mode 100644 index 0000000..e3eeec9 Binary files /dev/null and b/src/eu/engys/resources/images/searchTable16.png differ diff --git a/src/eu/engys/resources/images/shape_boundary_edges16.png b/src/eu/engys/resources/images/shape_boundary_edges16.png new file mode 100644 index 0000000..a560b67 Binary files /dev/null and b/src/eu/engys/resources/images/shape_boundary_edges16.png differ diff --git a/src/eu/engys/resources/images/shape_outline16.png b/src/eu/engys/resources/images/shape_outline16.png new file mode 100644 index 0000000..d0923a8 Binary files /dev/null and b/src/eu/engys/resources/images/shape_outline16.png differ diff --git a/src/eu/engys/resources/images/shape_surface16.png b/src/eu/engys/resources/images/shape_surface16.png new file mode 100644 index 0000000..aa47e08 Binary files /dev/null and b/src/eu/engys/resources/images/shape_surface16.png differ diff --git a/src/eu/engys/resources/images/shape_surface_edges16.png b/src/eu/engys/resources/images/shape_surface_edges16.png new file mode 100644 index 0000000..8df4b70 Binary files /dev/null and b/src/eu/engys/resources/images/shape_surface_edges16.png differ diff --git a/src/eu/engys/resources/images/shape_wireframe16.png b/src/eu/engys/resources/images/shape_wireframe16.png new file mode 100644 index 0000000..7217249 Binary files /dev/null and b/src/eu/engys/resources/images/shape_wireframe16.png differ diff --git a/src/eu/engys/resources/images/share16.png b/src/eu/engys/resources/images/share16.png new file mode 100644 index 0000000..5b76929 Binary files /dev/null and b/src/eu/engys/resources/images/share16.png differ diff --git a/src/eu/engys/resources/images/shortcut16.png b/src/eu/engys/resources/images/shortcut16.png new file mode 100644 index 0000000..11e06e4 Binary files /dev/null and b/src/eu/engys/resources/images/shortcut16.png differ diff --git a/src/eu/engys/resources/images/showResults16.png b/src/eu/engys/resources/images/showResults16.png new file mode 100644 index 0000000..5bd9491 Binary files /dev/null and b/src/eu/engys/resources/images/showResults16.png differ diff --git a/src/eu/engys/resources/images/slice24.png b/src/eu/engys/resources/images/slice24.png new file mode 100644 index 0000000..23874c4 Binary files /dev/null and b/src/eu/engys/resources/images/slice24.png differ diff --git a/src/eu/engys/resources/images/sliderLock16.png b/src/eu/engys/resources/images/sliderLock16.png new file mode 100644 index 0000000..9063ec6 Binary files /dev/null and b/src/eu/engys/resources/images/sliderLock16.png differ diff --git a/src/eu/engys/resources/images/sliderUnlock16.png b/src/eu/engys/resources/images/sliderUnlock16.png new file mode 100644 index 0000000..70f23cf Binary files /dev/null and b/src/eu/engys/resources/images/sliderUnlock16.png differ diff --git a/src/eu/engys/resources/images/sphere24.png b/src/eu/engys/resources/images/sphere24.png new file mode 100644 index 0000000..2e1e8fb Binary files /dev/null and b/src/eu/engys/resources/images/sphere24.png differ diff --git a/src/eu/engys/resources/images/starcd16.png b/src/eu/engys/resources/images/starcd16.png new file mode 100644 index 0000000..dc66cb1 Binary files /dev/null and b/src/eu/engys/resources/images/starcd16.png differ diff --git a/src/eu/engys/resources/images/start16.png b/src/eu/engys/resources/images/start16.png new file mode 100644 index 0000000..184be23 Binary files /dev/null and b/src/eu/engys/resources/images/start16.png differ diff --git a/src/eu/engys/resources/images/startAll16.png b/src/eu/engys/resources/images/startAll16.png new file mode 100644 index 0000000..d66725a Binary files /dev/null and b/src/eu/engys/resources/images/startAll16.png differ diff --git a/src/eu/engys/resources/images/stl24.png b/src/eu/engys/resources/images/stl24.png new file mode 100644 index 0000000..0c9e9ee Binary files /dev/null and b/src/eu/engys/resources/images/stl24.png differ diff --git a/src/eu/engys/resources/images/stop16.png b/src/eu/engys/resources/images/stop16.png new file mode 100644 index 0000000..f602055 Binary files /dev/null and b/src/eu/engys/resources/images/stop16.png differ diff --git a/src/eu/engys/resources/images/streamlinesolutions16.png b/src/eu/engys/resources/images/streamlinesolutions16.png new file mode 100644 index 0000000..d1071aa Binary files /dev/null and b/src/eu/engys/resources/images/streamlinesolutions16.png differ diff --git a/src/eu/engys/resources/images/symmetry16.png b/src/eu/engys/resources/images/symmetry16.png new file mode 100644 index 0000000..eb29a89 Binary files /dev/null and b/src/eu/engys/resources/images/symmetry16.png differ diff --git a/src/eu/engys/resources/images/symmetryPlane16.png b/src/eu/engys/resources/images/symmetryPlane16.png new file mode 100644 index 0000000..a0c25e9 Binary files /dev/null and b/src/eu/engys/resources/images/symmetryPlane16.png differ diff --git a/src/eu/engys/resources/images/table_select_big.png b/src/eu/engys/resources/images/table_select_big.png new file mode 100644 index 0000000..e4bea5f Binary files /dev/null and b/src/eu/engys/resources/images/table_select_big.png differ diff --git a/src/eu/engys/resources/images/terminal16.png b/src/eu/engys/resources/images/terminal16.png new file mode 100644 index 0000000..fac36a1 Binary files /dev/null and b/src/eu/engys/resources/images/terminal16.png differ diff --git a/src/eu/engys/resources/images/tick16.png b/src/eu/engys/resources/images/tick16.png new file mode 100644 index 0000000..c277e6b Binary files /dev/null and b/src/eu/engys/resources/images/tick16.png differ diff --git a/src/eu/engys/resources/images/toolbox16.png b/src/eu/engys/resources/images/toolbox16.png new file mode 100644 index 0000000..ae4d8a9 Binary files /dev/null and b/src/eu/engys/resources/images/toolbox16.png differ diff --git a/src/eu/engys/resources/images/transform_parallel16.png b/src/eu/engys/resources/images/transform_parallel16.png new file mode 100644 index 0000000..3f53a60 Binary files /dev/null and b/src/eu/engys/resources/images/transform_parallel16.png differ diff --git a/src/eu/engys/resources/images/transform_perspective16.png b/src/eu/engys/resources/images/transform_perspective16.png new file mode 100644 index 0000000..ccb2402 Binary files /dev/null and b/src/eu/engys/resources/images/transform_perspective16.png differ diff --git a/src/eu/engys/resources/images/update16.png b/src/eu/engys/resources/images/update16.png new file mode 100644 index 0000000..b7639f1 Binary files /dev/null and b/src/eu/engys/resources/images/update16.png differ diff --git a/src/eu/engys/resources/images/upload16.png b/src/eu/engys/resources/images/upload16.png new file mode 100644 index 0000000..cb267e1 Binary files /dev/null and b/src/eu/engys/resources/images/upload16.png differ diff --git a/src/eu/engys/resources/images/uploadZip16.png b/src/eu/engys/resources/images/uploadZip16.png new file mode 100644 index 0000000..93589e4 Binary files /dev/null and b/src/eu/engys/resources/images/uploadZip16.png differ diff --git a/src/eu/engys/resources/images/wall16.png b/src/eu/engys/resources/images/wall16.png new file mode 100644 index 0000000..431ebc5 Binary files /dev/null and b/src/eu/engys/resources/images/wall16.png differ diff --git a/src/eu/engys/resources/images/wedge16.png b/src/eu/engys/resources/images/wedge16.png new file mode 100644 index 0000000..593613d Binary files /dev/null and b/src/eu/engys/resources/images/wedge16.png differ diff --git a/src/eu/engys/resources/images/win_close16.png b/src/eu/engys/resources/images/win_close16.png new file mode 100644 index 0000000..e44a306 Binary files /dev/null and b/src/eu/engys/resources/images/win_close16.png differ diff --git a/src/eu/engys/resources/images/win_closeAll16.png b/src/eu/engys/resources/images/win_closeAll16.png new file mode 100644 index 0000000..2c82f08 Binary files /dev/null and b/src/eu/engys/resources/images/win_closeAll16.png differ diff --git a/src/eu/engys/resources/images/win_maximize16.png b/src/eu/engys/resources/images/win_maximize16.png new file mode 100644 index 0000000..3a04256 Binary files /dev/null and b/src/eu/engys/resources/images/win_maximize16.png differ diff --git a/src/eu/engys/resources/images/win_restore16.png b/src/eu/engys/resources/images/win_restore16.png new file mode 100644 index 0000000..9df9498 Binary files /dev/null and b/src/eu/engys/resources/images/win_restore16.png differ diff --git a/src/eu/engys/resources/images/zip16.png b/src/eu/engys/resources/images/zip16.png new file mode 100644 index 0000000..183511d Binary files /dev/null and b/src/eu/engys/resources/images/zip16.png differ diff --git a/src/eu/engys/resources/images/zoomIn16.png b/src/eu/engys/resources/images/zoomIn16.png new file mode 100644 index 0000000..73924a7 Binary files /dev/null and b/src/eu/engys/resources/images/zoomIn16.png differ diff --git a/src/eu/engys/resources/images/zoomOut16.png b/src/eu/engys/resources/images/zoomOut16.png new file mode 100644 index 0000000..ab862b7 Binary files /dev/null and b/src/eu/engys/resources/images/zoomOut16.png differ diff --git a/src/eu/engys/resources/images/zoomReset16.png b/src/eu/engys/resources/images/zoomReset16.png new file mode 100644 index 0000000..f3d1753 Binary files /dev/null and b/src/eu/engys/resources/images/zoomReset16.png differ diff --git a/src/eu/engys/resources/images/zoomToArea16.png b/src/eu/engys/resources/images/zoomToArea16.png new file mode 100644 index 0000000..7097ccf Binary files /dev/null and b/src/eu/engys/resources/images/zoomToArea16.png differ diff --git a/src/eu/engys/resources/old/splash.png b/src/eu/engys/resources/old/splash.png new file mode 100644 index 0000000..e07df8e Binary files /dev/null and b/src/eu/engys/resources/old/splash.png differ diff --git a/src/eu/engys/resources/old/splash_HelyxOS.gif b/src/eu/engys/resources/old/splash_HelyxOS.gif new file mode 100644 index 0000000..0b3b88e Binary files /dev/null and b/src/eu/engys/resources/old/splash_HelyxOS.gif differ diff --git a/src/eu/engys/resources/pbs.run b/src/eu/engys/resources/pbs.run new file mode 100644 index 0000000..25b5bb0 --- /dev/null +++ b/src/eu/engys/resources/pbs.run @@ -0,0 +1,173 @@ +#!/bin/bash + +echo +echo "---------------------------------" +echo " PBS QUEUE LAUNCHER " +echo "---------------------------------" + +HEADER() { + [[ -e ~/.profile ]] && source ~/.profile + [[ -e ~/.bash_profile ]] && source ~/.bash_profile + + echo " Environment" + echo "---------------------------------" + echo " APPLICATION = $APPLICATION" + echo " APP_OPT = $APP_OPT" + echo " ENV_LOADER = $ENV_LOADER" + echo " HOSTFILE = $HOSTFILE" + echo " CASE = $CASE" + echo " LOG = $LOG" + echo " NP = $NP" + echo " OPTIONS = $1" + echo "---------------------------------" + echo " PBS_O_WORKDIR = $PBS_O_WORKDIR" + echo " PBS_NODEFILE = $PBS_NODEFILE" + echo "---------------------------------" + echo " SYSTEM = `uname -a`" + echo " PWD = `pwd`" + echo " HOSTNAME = `hostname`" + echo " TIME = `date`" + echo " PWD = `pwd`" + +} + +setJobId() { + # Save job ID information + if [[ -e JOBID.log ]] + then + JOBID=$(cat JOBID.log) + echo " JOBID = $JOBID" + echo "---------------------------------" + else + echo "No running jobs. Aborting." + exit 1 + fi +} + +do_kill() { + JOB_STATUS=$(qstat $JOBID | awk 'NR==3''{print $5}') + echo ">> Deleting $JOBID" + qdel $JOBID + echo ">> Job DELETED" + exit 0 +} + +do_monitor() { + typeset -i n=0 + typeset -i TIMEOUT=1000 + + # Check job status and wait for job start + while : + do + JOB_STATUS=$(qstat $JOBID | awk 'NR==3''{print $5}') + STATUS=${JOB_STATUS:=E} + #echo "STATUS = '$STATUS'" + case "$STATUS" in + C) + #tail -n +1 out.log + echo ">> Job $JOBID COMPLETED!" + + JOB_EXIT_STATUS=$(qstat -f $JOBID | awk '/exit_status/''{print $3}') + echo ">> Exit Status: $JOB_EXIT_STATUS" + exit $JOB_EXIT_STATUS + ;; + E) + echo ">> Job $JOBID ERROR!?" + + JOB_EXIT_STATUS=$(qstat -f $JOBID | awk '/exit_status/''{print $3}') + echo ">> Exit Status: $JOB_EXIT_STATUS" + exit $JOB_EXIT_STATUS + ;; + R) + echo ">> Job $JOBID RUNNING" + break 1 + ;; + *) + sleep 10 + echo ">> Job $JOBID QUEUED. Waiting." + ;; + esac + + if [[ $n -gt $TIMEOUT ]] + then + echo ">> EXIT: Timeout Exceeded!" + exit 1 + fi + n=$(echo "$n+1" | bc -l) + done + + #tail -n +1 -F out.log & + #PID=$! + while : + do + JOB_STATUS=$(qstat $JOBID | awk 'NR==3''{print $5}') + STATUS=${JOB_STATUS:=E} + #echo "STATUS = '$STATUS'" + case "$STATUS" in + C) + sleep 10 + echo ">> Job COMPLETED!" + JOB_EXIT_STATUS=$(qstat -f $JOBID | awk '/exit_status/''{print $3}') + echo ">> Exit Status: $JOB_EXIT_STATUS" + kill -9 $PID + exit $JOB_EXIT_STATUS + ;; + E) + echo ">> Job $JOBID ERROR!?" + + JOB_EXIT_STATUS=$(qstat -f $JOBID | awk '/exit_status/''{print $3}') + echo ">> Exit Status: $JOB_EXIT_STATUS" + exit $JOB_EXIT_STATUS + ;; + *) + sleep 10 + echo ">> Job RUNNING." + ;; + esac + done +} + +check_command() { + echo -n "Check command '$1': " + # Check if pbs commands are available + command -v $1 >/dev/null 2>&1 || { echo >&2 "Not installed! Aborting."; exit 1; } + echo "OK" +} + +do_launch() { + check_command "qsub" + check_command "qdel" + check_command "qstat" + + # Submit ELEMENTS job to PBS queue system + qsub < driver.pbs > JOBID.log + + setJobId + echo ">> Job SUBMITTED." +} + +case "$1" in + -kill) + HEADER + setJobId + do_kill + ;; + -launch) + HEADER + do_launch + do_monitor + ;; + -monitor) + HEADER + setJobId + do_monitor + ;; + *) + HEADER + do_launch + do_monitor + ;; +esac + +echo "Fail: Unexpected termination" +exit 1 \ No newline at end of file diff --git a/src/eu/engys/standardVOF/StandardVOFBoundaryConditionsView.java b/src/eu/engys/standardVOF/StandardVOFBoundaryConditionsView.java new file mode 100644 index 0000000..568c422 --- /dev/null +++ b/src/eu/engys/standardVOF/StandardVOFBoundaryConditionsView.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.standardVOF; + +import eu.engys.core.modules.boundaryconditions.BoundaryConditionsView; +import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel; +import eu.engys.core.modules.boundaryconditions.IBoundaryConditionsPanel; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.BoundaryType; +import eu.engys.gui.casesetup.boundaryconditions.panels.patch.MomentumPatch; +import eu.engys.gui.casesetup.boundaryconditions.panels.wall.StandardMomentumWall; + +public class StandardVOFBoundaryConditionsView implements BoundaryConditionsView { + + private static final String MOMENTUM = " " + BoundaryTypePanel.MOMENTUM + " "; + private StandardVOFModule module; + + public StandardVOFBoundaryConditionsView(StandardVOFModule module) { + this.module = module; + } + + @Override + public void configure(BoundaryTypePanel panel) { + if (panel.getType() == BoundaryType.WALL) { + panel.addPanel(MOMENTUM, new VOFStandardMomentumWall(panel), 0); + } else if (panel.getType() == BoundaryType.PATCH) { + panel.addPanel(MOMENTUM, new VOFStandardMomentumPatch(panel), 0); + } + } + + class VOFStandardMomentumWall extends StandardMomentumWall { + public VOFStandardMomentumWall(BoundaryTypePanel parent) { + super(parent); + } + + @Override + public boolean isEnabled(Model model) { + return module.isVOF(); + } + } + + class VOFStandardMomentumPatch extends MomentumPatch { + + public VOFStandardMomentumPatch(BoundaryTypePanel parent) { + super(parent); + } + + @Override + public boolean isEnabled(Model model) { + return module.isVOF(); + } + } + + @Override + public void configure(IBoundaryConditionsPanel panel) { + } + +} diff --git a/src/eu/engys/standardVOF/StandardVOFModule.java b/src/eu/engys/standardVOF/StandardVOFModule.java new file mode 100644 index 0000000..cabe261 --- /dev/null +++ b/src/eu/engys/standardVOF/StandardVOFModule.java @@ -0,0 +1,194 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.standardVOF; + +import java.util.HashSet; +import java.util.Set; + +import javax.inject.Inject; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.FieldElement; +import eu.engys.core.modules.ApplicationModuleAdapter; +import eu.engys.core.modules.ModuleDefaults; +import eu.engys.core.modules.ModulePanel; +import eu.engys.core.modules.boundaryconditions.BoundaryConditionsView; +import eu.engys.core.modules.solutionmodelling.SolutionView; +import eu.engys.core.modules.tree.TreeView; +import eu.engys.core.project.Model; +import eu.engys.core.project.defaults.DefaultsProvider; +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.core.project.state.Solver; +import eu.engys.core.project.state.State; +import eu.engys.core.project.state.StateBuilder; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.fields.FieldsDefaults; +import eu.engys.gui.casesetup.phases.PhasesPanel; + +public class StandardVOFModule extends ApplicationModuleAdapter { + + private static final String MODULE_NAME = "standardVOF"; + + public static final String VOF_LABEL = "VOF"; + public static final String VOF_KEY = "VOF"; + + public static final Solver INTER_FOAM = new Solver("interFoam"); + public static final MultiphaseModel VOF_MODEL = new MultiphaseModel(VOF_LABEL, VOF_KEY, true, true); + + private StandardVOFSolutionView solutionView; + private StandardVOFBoundaryConditionsView boundaryConditionsView; + + private PhasesPanel phasesPanel; + private TreeView treeView; + + private double sigma; + + private Model model; + + private DefaultsProvider defaults; + private StandardVOFReader reader; + + @Inject + public StandardVOFModule(Model model) { + this.model = model; + this.solutionView = new StandardVOFSolutionView(this); + this.boundaryConditionsView = new StandardVOFBoundaryConditionsView(this); + + this.phasesPanel = new PhasesPanel(model, new StandardVOFPhasesView(this, model)); + this.treeView = new StandardVOFTreeView(this, phasesPanel); + + this.reader = new StandardVOFReader(model, this); + + this.defaults = new ModuleDefaults(this, model.getDefaults(), model.getDefaults().getDefaultStateData()) { + @Override + public Dictionary getDefaultsFieldMapsFor(State state, String region) { + Dictionary fieldMaps = super.getDefaultsFieldMapsFor(state, region); + fixAlphaFieldName(fieldMaps); + return fieldMaps; + } + }; + } + + private void fixAlphaFieldName(Dictionary fieldMaps) { + if (model.getState().getMultiphaseModel().isMultiphase() && model.getState().getPhases() > 1 && fieldMaps != null && fieldMaps.found(Fields.ALPHA)) { + String alpha = ((FieldElement) fieldMaps.remove(Fields.ALPHA)).getValue(); + fieldMaps.add(Fields.ALPHA + "." + model.getMaterials().getFirstMaterialName(), alpha); + } + } + + @Override + public String getName() { + return MODULE_NAME; + } + + @Override + public TreeView getTreeView() { + return treeView; + } + + @Override + public Set getCaseSetupPanels() { + Set panels = new HashSet<>(); + panels.add(phasesPanel); + return panels; + } + + @Override + public void updateSolver(State state) { + if (state.isTransient()) { + if (state.isIncompressible()) { + if (state.getMultiphaseModel().equals(VOF_MODEL)) { + state.setSolver(INTER_FOAM); + } + } + } + } + + @Override + public void loadState() { + reader.loadState(); + } + + @Override + public void loadMaterials() { + reader.loadMaterials(); + } + + @Override + public void save() { + new StandardVOFWriter(model, this).write(); + } + + @Override + public void write() { + } + + @Override + public void saveDefaultsToProject() { + if (isVOF()) { + StateBuilder.saveDefaultsToProject(model, defaults); + } else { + } + } + + @Override + public Fields loadDefaultsFields(String region) { + if (isVOF()) { + return FieldsDefaults.loadFieldsFromDefaults(model.getState(), defaults, model.getPatches(), region); + } else { + return new Fields(); + } + } + + @Override + public SolutionView getSolutionView() { + return solutionView; + } + + @Override + public BoundaryConditionsView getBoundaryConditionsView() { + return boundaryConditionsView; + } + + public boolean isVOF() { + return model.getState().getMultiphaseModel().equals(VOF_MODEL); + } + + public void setSigma(double sigma) { + this.sigma = sigma; + } + + public double getSigma() { + return sigma; + } + + /* + * For test purposes only + */ + public PhasesPanel getPhasesPanel() { + return phasesPanel; + } +} diff --git a/src/eu/engys/standardVOF/StandardVOFPhasesView.java b/src/eu/engys/standardVOF/StandardVOFPhasesView.java new file mode 100644 index 0000000..dcfbb5c --- /dev/null +++ b/src/eu/engys/standardVOF/StandardVOFPhasesView.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.standardVOF; + +import static eu.engys.core.project.constant.TransportProperties.SIGMA_KEY; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DimensionedScalar; +import eu.engys.core.dictionary.model.DictionaryModel; +import eu.engys.core.project.Model; +import eu.engys.gui.casesetup.phases.PhasesView; +import eu.engys.util.DimensionalUnits; +import eu.engys.util.ui.builder.PanelBuilder; + +public class StandardVOFPhasesView implements PhasesView { + + public static final String SURFACE_TENSION_LABEL = "Surface Tension [N/m]"; + + private static final Logger logger = LoggerFactory.getLogger(StandardVOFPhasesView.class); + + private Model model; + private StandardVOFModule module; + private DictionaryModel sigmaModel = new DictionaryModel(new Dictionary("")); + + private PanelBuilder parametersBuilder; + + public StandardVOFPhasesView(StandardVOFModule module, Model model) { + this.module = module; + this.model = model; + } + + @Override + public void layoutComponents(PanelBuilder parametersBuilder) { + this.parametersBuilder = parametersBuilder; + } + + @Override + public void load(Model model) { + if (module.isVOF()) { + _layoutComponents(); + _load(model); + } + } + + private void _layoutComponents() { + parametersBuilder.clear(); + parametersBuilder.addComponent(SURFACE_TENSION_LABEL, sigmaModel.bindDimensionedDouble(SIGMA_KEY, DimensionalUnits.KG_S2, 0D, Double.MAX_VALUE)); + } + + private void _load(Model model) { + Dictionary dict = new Dictionary(""); + dict.add(new DimensionedScalar(SIGMA_KEY, String.valueOf(module.getSigma()), DimensionalUnits.KG_S2)); + sigmaModel.setDictionary(dict); + } + + @Override + public void save(Model model) { + if (module.isVOF()) { + _save(model); + } + } + + private void _save(Model model) { + Dictionary sigmaDict = sigmaModel.getDictionary(); + if (sigmaDict.found(SIGMA_KEY)) { + module.setSigma(sigmaDict.lookupScalar(SIGMA_KEY).doubleValue()); + } + } + +} diff --git a/src/eu/engys/standardVOF/StandardVOFReader.java b/src/eu/engys/standardVOF/StandardVOFReader.java new file mode 100644 index 0000000..40e7111 --- /dev/null +++ b/src/eu/engys/standardVOF/StandardVOFReader.java @@ -0,0 +1,139 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.standardVOF; + +import static eu.engys.core.project.constant.ThermophysicalProperties.MATERIAL_NAME_KEY; +import static eu.engys.core.project.constant.TransportProperties.PHASES_KEY; +import static eu.engys.core.project.constant.TransportProperties.SIGMA_KEY; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.project.Model; +import eu.engys.core.project.constant.ConstantFolder; +import eu.engys.core.project.constant.TransportProperties; +import eu.engys.core.project.materials.Material; +import eu.engys.core.project.materials.Materials; + +public class StandardVOFReader { + + private static final Logger logger = LoggerFactory.getLogger(StandardVOFReader.class); + + private Model model; + private StandardVOFModule module; + + private TransportProperties transportProperties; + + public StandardVOFReader(Model model, StandardVOFModule module) { + this.model = model; + this.module = module; + } + + public void loadState() { + if (isVOF()) { + model.getState().setMultiphaseModel(StandardVOFModule.VOF_MODEL); + model.getState().setPhases(2); + } + } + + public void loadMaterials() { + if (isVOF()) { + if (model.getState().isIncompressible()) { + readIncompressibleMaterials(); + } else { + readCompressibleMaterials(); + } + } + } + + boolean isVOF() { + ConstantFolder constantFolder = model.getProject().getConstantFolder(); + TransportProperties transportProperties = constantFolder.getTransportProperties(); + if (transportProperties != null) { + if ((transportProperties.found(PHASES_KEY))) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + private void readIncompressibleMaterials() { + Materials materials = model.getMaterials(); + ConstantFolder constantFolder = model.getProject().getConstantFolder(); + transportProperties = constantFolder.getTransportProperties(); + + if (transportProperties.found(PHASES_KEY)) { + model.getState().setPhases(2); + + String phases = transportProperties.lookup(PHASES_KEY).replaceAll("\\(", "").replaceAll("\\)", "").trim(); + + Dictionary dict1 = new Dictionary(transportProperties.subDict(phases.split(" ")[0])); + if (!dict1.isEmpty()) { + if (!dict1.found(MATERIAL_NAME_KEY)) { + dict1.add(MATERIAL_NAME_KEY, "material1"); + } + String name1 = dict1.lookup(MATERIAL_NAME_KEY); + dict1.setName(name1); + materials.add(new Material(name1, dict1)); + } + + Dictionary dict2 = new Dictionary(transportProperties.subDict(phases.split(" ")[1])); + if (!dict2.isEmpty()) { + if (!dict2.found(MATERIAL_NAME_KEY)) { + dict2.add(MATERIAL_NAME_KEY, "material2"); + } + String name2 = dict2.lookup(MATERIAL_NAME_KEY); + dict2.setName(name2); + materials.add(new Material(name2, dict2)); + } + + if (transportProperties.found(SIGMA_KEY)) { + double sigma = transportProperties.lookupScalar(SIGMA_KEY).doubleValue(); + module.setSigma(sigma); + } else if (dict1.found(SIGMA_KEY)) { + double sigma = dict1.lookupScalar(SIGMA_KEY).doubleValue(); + module.setSigma(sigma); + } else if (dict2.found(SIGMA_KEY)) { + double sigma = dict2.lookupScalar(SIGMA_KEY).doubleValue(); + module.setSigma(sigma); + } + + model.materialsChanged(); + + } else { + logger.warn("Multiphase case but no phases found in transportProperties"); + } + } + + public void readCompressibleMaterials() { + logger.error("Multiphase Compressible not supported"); + } + +} diff --git a/src/eu/engys/standardVOF/StandardVOFSolutionView.java b/src/eu/engys/standardVOF/StandardVOFSolutionView.java new file mode 100644 index 0000000..d059de6 --- /dev/null +++ b/src/eu/engys/standardVOF/StandardVOFSolutionView.java @@ -0,0 +1,75 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.standardVOF; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.modules.solutionmodelling.AbstractSolutionView; +import eu.engys.core.modules.solutionmodelling.MultiphaseBuilder; +import eu.engys.core.project.state.MultiphaseModel; +import eu.engys.core.project.state.SolutionState; +import eu.engys.util.ui.textfields.SpinnerField; + +public class StandardVOFSolutionView extends AbstractSolutionView { + + private static final Logger logger = LoggerFactory.getLogger(StandardVOFSolutionView.class); + + private StandardVOFModule module; + private MultiphaseBuilder builder; + + public StandardVOFSolutionView(StandardVOFModule module) { + this.module = module; + } + + @Override + public void buildMultiphase(MultiphaseBuilder builder) { + this.builder = builder; + builder.addMultiphaseChoice(StandardVOFModule.VOF_MODEL); + } + + @Override + public void fixSolutionState(SolutionState ss) { + if (ss.areSolverTypeAndTimeAndFlowAndTurbulenceChoosen()) { + boolean isVOFState = ss.isTransient() && ss.isIncompressible(); + if (isVOFState) { + builder.enableChoice(StandardVOFModule.VOF_MODEL); + } else { + builder.disableChoice(StandardVOFModule.VOF_MODEL); + } + } + } + + @Override + public void fixMultiphase(MultiphaseModel mm) { + SpinnerField phasesNumber = builder.getPhasesField(); + if (mm.equals(StandardVOFModule.VOF_MODEL)) { + phasesNumber.setIntValue(2); + phasesNumber.setEnabled(false); + } + } + +} diff --git a/src/eu/engys/standardVOF/StandardVOFTreeView.java b/src/eu/engys/standardVOF/StandardVOFTreeView.java new file mode 100644 index 0000000..50b5f4f --- /dev/null +++ b/src/eu/engys/standardVOF/StandardVOFTreeView.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.standardVOF; + +import eu.engys.core.modules.ModulePanel; +import eu.engys.core.modules.tree.ModuleElementPanel; +import eu.engys.core.modules.tree.TreeView; +import eu.engys.gui.casesetup.phases.PhasesPanel; + +public class StandardVOFTreeView implements TreeView { + + private StandardVOFModule module; + private ModulePanel phasesPanel; + + public StandardVOFTreeView(StandardVOFModule module, PhasesPanel phasesPanel) { + this.module = module; + this.phasesPanel = phasesPanel; + } + + @Override + public void updateTree(ModuleElementPanel viewElementPanel) { + if (module.isVOF()) { + viewElementPanel.addPanel(phasesPanel); + } else { + viewElementPanel.removePanel(phasesPanel); + } + } + +} diff --git a/src/eu/engys/standardVOF/StandardVOFWriter.java b/src/eu/engys/standardVOF/StandardVOFWriter.java new file mode 100644 index 0000000..aa15350 --- /dev/null +++ b/src/eu/engys/standardVOF/StandardVOFWriter.java @@ -0,0 +1,101 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.standardVOF; + +import static eu.engys.core.project.constant.TransportProperties.PHASES_KEY; +import static eu.engys.core.project.constant.TransportProperties.SIGMA_KEY; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.dictionary.Dictionary; +import eu.engys.core.dictionary.DimensionedScalar; +import eu.engys.core.project.Model; +import eu.engys.core.project.constant.ConstantFolder; +import eu.engys.core.project.constant.TransportProperties; +import eu.engys.core.project.materials.Material; +import eu.engys.core.project.materials.Materials; + +public class StandardVOFWriter { + + private static final Logger logger = LoggerFactory.getLogger(StandardVOFWriter.class); + + private Model model; + private StandardVOFModule module; + + public StandardVOFWriter(Model model, StandardVOFModule module) { + this.model = model; + this.module = module; + + } + + public void write() { + if (module.isVOF()) { + if (model.getState().isIncompressible()) { + writeIncompressibleMaterials(); + } else { + writeCompressibleMaterials(); + } + } + } + + private void writeCompressibleMaterials() { + logger.error("Multiphase Compressible not supported"); + } + + private void writeIncompressibleMaterials() { + Materials materials = model.getMaterials(); + ConstantFolder constantFolder = model.getProject().getConstantFolder(); + TransportProperties transportProperties = constantFolder.getTransportProperties(); + + if (materials.size() == 2) { + transportProperties.clear(); + + Material mat1 = materials.get(0); + String mat1Name = mat1.getName(); + Material mat2 = materials.get(1); + String mat2Name = mat2.getName(); + + transportProperties.add(PHASES_KEY, "(" + mat1Name + " " + mat2Name + ")"); + + Dictionary dict1 = new Dictionary(mat1.getDictionary()); + dict1.remove(SIGMA_KEY); + dict1.setName(mat1Name); + transportProperties.add(dict1); + + Dictionary dict2 = new Dictionary(mat2.getDictionary()); + dict2.remove(SIGMA_KEY); + dict2.setName(mat2Name); + transportProperties.add(dict2); + + double sigmaValue = module.getSigma(); + transportProperties.add(new DimensionedScalar(SIGMA_KEY, String.valueOf(sigmaValue), "[1 0 -2 0 0 0 0 ]")); + + } else { + logger.warn("Multiphase solution choosen but '{}' materials found", materials.size()); + } + } +} diff --git a/src/eu/engys/standardVOF/resources/standardVOF.fields b/src/eu/engys/standardVOF/resources/standardVOF.fields new file mode 100644 index 0000000..6a910a8 --- /dev/null +++ b/src/eu/engys/standardVOF/resources/standardVOF.fields @@ -0,0 +1,130 @@ +U +{ + allowedFieldInitialisationMethods (default fixedValue ); + + initialisation + { + type default; + } + + + fieldDefinition + { + type vector; + dimensions [ 0 1 -1 0 0 0 0 ]; + internalField uniform (0 0 0); + + boundaryConditions + { + regionDefaults + { + wall {type fixedValue; value uniform (0 0 0);} + + outlet {type inletOutlet; inletValue uniform (0 0 0); value uniform (0 0 0);} + + inlet {type inletOutlet; inletValue uniform (0 0 0); value uniform (0 0 0);} + + patch {type pressureInletOutletVelocity; value uniform (0 0 0);} + + processor {type processor; value uniform (0 0 0);} + } + + partialNamed {} + + exactNamed{} + } + } +} + +pmultiphase +{ + allowedFieldInitialisationMethods (default fixedValue ); + + initialisation + { + type default; + } + + + fieldDefinition + { + type scalar; + dimensions [ 1 -1 -2 0 0 0 0 ]; + internalField uniform 0; + + boundaryConditions + { + regionDefaults + { + wall + { + type fixedFluxPressure; + value uniform 0; + } + + outlet {type fixedValue; value uniform 0;} + + inlet + { + type fixedFluxPressure; + value uniform 0; + } + + patch + { + type totalPressure; + p0 uniform 0; + U U; + value uniform 0; + phi phi; + rho rho; + psi none; + gamma 1; + } + + processor {type processor; value uniform 0;} + } + + partialNamed {} + + exactNamed{} + } + } +} + +phase +{ + allowedFieldInitialisationMethods (default fixedValue cellSet); + + initialisation + { + type fixedValue; value uniform 0; + } + + fieldDefinition + { + type scalar; + dimensions [ 0 0 0 0 0 0 0 ]; + internalField uniform 0; + + boundaryConditions + { + regionDefaults + { + wall {type zeroGradient;} + + outlet {type inletOutlet; inletValue uniform 0; value uniform 0;} + + inlet {type fixedValue; value uniform 0;} + + patch {type inletOutlet; inletValue uniform 0; value uniform 0;} + + processor {type processor; value uniform 0;} + } + + partialNamed {} + + exactNamed{} + } + } +} \ No newline at end of file diff --git a/src/eu/engys/standardVOF/resources/standardVOF.stateData b/src/eu/engys/standardVOF/resources/standardVOF.stateData new file mode 100644 index 0000000..4e7dffb --- /dev/null +++ b/src/eu/engys/standardVOF/resources/standardVOF.stateData @@ -0,0 +1,470 @@ +states +{ + interFoamRAS (transient incompressible ras VOF); + interFoamRAS2 (PIMPLE incompressible ras VOF); + interFoamRAS3 (PIMPLE incompressible ras multiphaseVOF); + + interFoamLES (transient incompressible les VOF); + interFoamLES2 (PIMPLE incompressible les VOF); + interFoamLES3 (PIMPLE incompressible les multiphaseVOF); + +} + + +"interFoamRAS.*" +{ + fieldMaps + { + U U; + p_rgh pmultiphase; + alpha phase; + } + materialProperties + { + air{} + water{} + } + system + { + controlDict + { + startFrom startTime; + startTime 0; + stopAt endTime; + endTime 10; + deltaT 0.001; + writeControl adjustableRunTime; + writeInterval 0.1; + purgeWrite 0; + writeFormat ascii; + writePrecision 10; + writeCompression uncompressed; + timeFormat general; + timePrecision 6; + graphFormat raw; + runTimeModifiable yes; + adjustTimeStep yes; + maxCo 0.5; + maxAlphaCo 0.25; + maxDeltaT 1.0; + } + fvSchemes + { + ddtSchemes {$fvSchemes_ddtSchemes_ras_trans;} + + gradSchemes + { + $fvSchemes_gradSchemes; + grad(U) cellLimited Gauss linear 1; + grad(rho) cellLimited Gauss linear 1; + grad(p_rgh) cellLimited Gauss linear 1; + grad(pcorr) cellLimited Gauss linear 1; + } + + divSchemes + { + $fvSchemes_divSchemes_trans; + div(rhoPhi,U) Gauss linearUpwindV grad(U); + div(phi,alpha) Gauss vanLeer; + div(phirb,alpha) Gauss interfaceCompression; + div((nuEff*dev(T(grad(U))))) Gauss linear; + } + + $fvSchemes_misc; + fluxRequired + { + default no; + p_rgh; + pcorr; + "alpha.*"; + } + } + fvSolution + { + PIMPLE + { + momentumPredictor no; + nCorrectors 2; + nOuterCorrectors 1; + nNonOrthogonalCorrectors 0; + nAlphaCorr 1; + nAlphaSubCycles 3; + cAlpha 1.5; + correctPhi yes; + pRefCell 0; + pRefValue 0; + + residualControl + { + "(U|k|epsilon|omega|nuTilda|T|p_rgh|p)" + { + relTol 0; + tolerance 1e-5; + } + "alpha.*" + { + relTol 0; + tolerance 1e-5; + } + } + + } + solvers + { + + $fvSolution_solvers_PIMPLE; + + pcorr + { + solver PCG; + preconditioner + { + preconditioner GAMG; + tolerance 1e-5; + relTol 0; + smoother DICGaussSeidel; + nPreSweeps 0; + nPostSweeps 2; + nFinestSweeps 2; + cacheAgglomeration false; + nCellsInCoarsestLevel 10; + agglomerator faceAreaPair; + mergeLevels 1; + } + + tolerance 1e-05; + relTol 0; + maxIter 100; + minIter 1; + } + + "alpha.*" + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0; + nSweeps 1; + minIter 1; + nAlphaCorr 1; + nAlphaSubCycles 3; + cAlpha 1.5; + } + } + relaxationFactors {$fvSolution_relaxationFactors_trans;} + + } + } + + constant + { + g{$g;} + transportProperties + { + sigma sigma [1 0 -2 0 0 0 0 ] 0.0; + } + } +} + +"interFoamLES.*" +{ + fieldMaps + { + U U; + p_rgh pmultiphase; + alpha phase; + } + materialProperties + { + air{} + water{} + } + system + { + controlDict + { + startFrom startTime; + startTime 0; + stopAt endTime; + endTime 10; + deltaT 0.001; + writeControl adjustableRunTime; + writeInterval 0.1; + purgeWrite 0; + writeFormat ascii; + writePrecision 10; + writeCompression uncompressed; + timeFormat general; + timePrecision 6; + graphFormat raw; + runTimeModifiable yes; + adjustTimeStep yes; + maxCo 0.5; + maxAlphaCo 0.25; + maxDeltaT 1.0; + } + fvSchemes + { + ddtSchemes {$fvSchemes_ddtSchemes_les;} + + gradSchemes + { + $fvSchemes_gradSchemes; + grad(U) cellLimited Gauss linear 1; + grad(rho) cellLimited Gauss linear 1; + grad(p_rgh) cellLimited Gauss linear 1; + grad(pcorr) cellLimited Gauss linear 1; + } + + divSchemes + { + $fvSchemes_divSchemes_trans; + div(rhoPhi,U) Gauss LUST grad(U); + div(phi,alpha) Gauss vanLeer; + div(phirb,alpha) Gauss interfaceCompression; + div((nuEff*dev(T(grad(U))))) Gauss linear; + } + + $fvSchemes_misc; + fluxRequired + { + default no; + p_rgh; + pcorr; + "alpha.*"; + } + } + fvSolution + { + PIMPLE + { + momentumPredictor no; + nCorrectors 5; + nOuterCorrectors 1; + nNonOrthogonalCorrectors 1; + nAlphaCorr 1; + nAlphaSubCycles 5; + cAlpha 1.5; + correctPhi yes; + pRefCell 0; + pRefValue 0; + + residualControl + { + "(U|k|epsilon|omega|nuTilda|T|p_rgh|p)" + { + relTol 0; + tolerance 1e-5; + } + "alpha.*" + { + relTol 0; + tolerance 1e-5; + } + } + + } + solvers + { + pcorr + { + solver PCG; + preconditioner + { + preconditioner GAMG; + tolerance 1e-5; + relTol 0; + smoother DICGaussSeidel; + nPreSweeps 0; + nPostSweeps 2; + nFinestSweeps 2; + cacheAgglomeration false; + nCellsInCoarsestLevel 10; + agglomerator faceAreaPair; + mergeLevels 1; + } + + tolerance 1e-05; + relTol 0; + maxIter 100; + minIter 1; + } + + p_rgh + { + solver GAMG; + tolerance 1e-8; + relTol 0.01; + smoother DIC; + nPreSweeps 0; + nPostSweeps 2; + nFinestSweeps 2; + cacheAgglomeration true; + nCellsInCoarsestLevel 10; + agglomerator faceAreaPair; + mergeLevels 1; + minIter 1; + } + + p_rghFinal + { + solver PCG; + preconditioner + { + preconditioner GAMG; + tolerance 1e-8; + relTol 0; + nVcycles 2; + smoother DICGaussSeidel; + nPreSweeps 2; + nPostSweeps 2; + nFinestSweeps 2; + cacheAgglomeration true; + nCellsInCoarsestLevel 10; + agglomerator faceAreaPair; + mergeLevels 1; + } + + tolerance 1e-8; + relTol 0; + maxIter 20; + minIter 1; + } + + U + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0.1; + nSweeps 1; + minIter 1; + } + k + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0.1; + nSweeps 1; + minIter 1; + } + kl + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0.1; + nSweeps 1; + minIter 1; + } + epsilon + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0.1; + nSweeps 1; + minIter 1; + } + nuTilda + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0.1; + nSweeps 1; + minIter 1; + } + omega + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0.1; + nSweeps 1; + minIter 1; + } + + + UFinal + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0; + nSweeps 1; + minIter 1; + } + kFinal + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0; + nSweeps 1; + minIter 1; + } + klFinal + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0; + nSweeps 1; + minIter 1; + } + epsilonFinal + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0; + nSweeps 1; + minIter 1; + } + nuTildaFinal + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0; + nSweeps 1; + minIter 1; + } + omegaFinal + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0; + nSweeps 1; + minIter 1; + } + "alpha.*" + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-6; + relTol 0; + nSweeps 1; + minIter 1; + nAlphaCorr 1; + nAlphaSubCycles 3; + cAlpha 1.5; + } + } + relaxationFactors {$fvSolution_relaxationFactors_trans;} + } + } + + constant + { + g{$g;} + transportProperties + { + sigma sigma [1 0 -2 0 0 0 0 ] 0.0; + } + } + +} \ No newline at end of file diff --git a/src/eu/engys/suite/Suite.java b/src/eu/engys/suite/Suite.java new file mode 100644 index 0000000..34058ce --- /dev/null +++ b/src/eu/engys/suite/Suite.java @@ -0,0 +1,138 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.suite; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.inject.Named; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import com.google.inject.Inject; + +import eu.engys.core.Arguments; +import eu.engys.launcher.ApplicationLauncher; +import eu.engys.util.ui.UiUtil; + +public class Suite { + + private String product; + private ImageIcon icon; + private Set applications; + + @Inject + public Suite(@Named("Product") String product, @Named("Product") ImageIcon icon, Set applications) { + this.product = product; + this.icon = icon; + this.applications = applications; + } + + protected Set getApplications() { + return applications; + } + + public void batch() { +// if (applications.size() == 1) { + try { + ApplicationLauncher application = applications.iterator().next(); + application.batch(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(-1); + } +// } else { +// System.err.println("Only suites with one application can run batch. Exit"); +// System.exit(0); +// } + } + + public void launch() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (applications.size() == 1 || Arguments.baseDir != null) { + try { + ApplicationLauncher application = applications.iterator().next(); + application.checkLicense(); + application.launch(); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + JFrame frame = createAndShowFrame(); + UiUtil.centerAndShow(frame); + } + } + }); + } + + protected JFrame createAndShowFrame() { + JFrame frame = new JFrame(product); + List actions = createActions(); + + frame.getContentPane().setLayout(new BorderLayout()); + frame.getContentPane().add(new SuitePanel(actions, "Select Application"), BorderLayout.CENTER); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setIconImage(icon.getImage()); + frame.setResizable(false); + return frame; + } + + private List createActions() { + List actions = new ArrayList(); + for (final ApplicationLauncher app : applications) { + AbstractAction action = new AbstractAction(app.getTitle(), app.getIcon()) { + @Override + public void actionPerformed(ActionEvent e) { + SwingUtilities.getWindowAncestor((Component) e.getSource()).setVisible(false); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + try { + app.checkLicense(); + app.launch(); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + }); + } + }; + actions.add(action); + } + return actions; + } + +} diff --git a/src/eu/engys/suite/SuitePanel.java b/src/eu/engys/suite/SuitePanel.java new file mode 100644 index 0000000..829fb1c --- /dev/null +++ b/src/eu/engys/suite/SuitePanel.java @@ -0,0 +1,141 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.suite; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JPanel; + +import com.google.inject.Inject; + +public class SuitePanel extends JPanel { + + public static final ImageIcon BANNER = new ImageIcon(SuitePanel.class.getClassLoader().getResource("eu/engys/resources/elements_banner.png")); + public static final ImageIcon BG_IMAGE = new ImageIcon(SuitePanel.class.getClassLoader().getResource("eu/engys/resources/elements_startup.png")); + + private List actions; + private String title; + + @Inject + public SuitePanel(List actions, String title) { + super(new BorderLayout()); + this.actions = actions; + this.title = title; + layoutComponents(); + } + + public void layoutComponents() { + JPanel topPanel = createTopPanel(); + JPanel centerPanel = createCenterPanel(); + add(topPanel, BorderLayout.NORTH); + add(centerPanel, BorderLayout.CENTER); + } + + private JPanel createTopPanel() { + JPanel panel = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + setOpaque(false); + g.drawImage(BANNER.getImage(), (getWidth() - BANNER.getImage().getWidth(null)) / 2, 0, null); + super.paintComponent(g); + } + }; + panel.setPreferredSize(new Dimension(BANNER.getImage().getWidth(null), BANNER.getImage().getHeight(null))); + return panel; + } + + protected JPanel createCenterPanel() { + JPanel containerPanel = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + setOpaque(false); + g.drawImage(BG_IMAGE.getImage(), (getWidth() - BG_IMAGE.getImage().getWidth(null)) - 10, getHeight() - BG_IMAGE.getImage().getHeight(null), null); + super.paintComponent(g); + } + }; + containerPanel.setLayout(new BorderLayout()); + containerPanel.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25)); + + int width = actions.size() >= 3 ? 700 : BG_IMAGE.getImage().getWidth(null); + int height= 260 * (((actions.size() - 1) / 3) + 1); + containerPanel.setPreferredSize(new Dimension(width, height)); + + JPanel titlePanel = new JPanel(new GridBagLayout()); + titlePanel.setBorder(BorderFactory.createTitledBorder(title)); + titlePanel.setOpaque(false); + containerPanel.add(titlePanel, BorderLayout.CENTER); + + JPanel buttonsPanel = createButtonsPanel(); + titlePanel.add(buttonsPanel, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + + return containerPanel; + } + + private JPanel createButtonsPanel() { + List buttons = createButtons(); + + int colNumber = 3; + int rows = ((buttons.size() - 1) / colNumber) + 1; + int cols = Math.min(buttons.size(), colNumber); + + JPanel panel = new JPanel(new GridLayout(rows, cols, 30, 30)); + panel.setOpaque(false); + + for (JButton button : buttons) { + button.setName("suite." + button.getText()); + button.setHorizontalTextPosition(JButton.CENTER); + button.setVerticalTextPosition(JButton.BOTTOM); + button.setFocusable(false); + panel.add(button); + } + return panel; + } + + private List createButtons() { + List buttons = new ArrayList(); + for (Action action : actions) { + final JButton button = new JButton(); + button.setAction(action); + //button.setOpaque(true); + buttons.add(button); + } + return buttons; + } + +} diff --git a/src/eu/engys/util/ApplicationInfo.java b/src/eu/engys/util/ApplicationInfo.java new file mode 100644 index 0000000..b98f2a7 --- /dev/null +++ b/src/eu/engys/util/ApplicationInfo.java @@ -0,0 +1,257 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util; + +import java.io.File; +import java.net.InetAddress; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.UnknownHostException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.ResourceBundle; +import java.util.Scanner; + +import org.apache.commons.io.FileUtils; + +import eu.engys.util.ui.ASCIIArt; + +public class ApplicationInfo { + + private static final String DEFAULT_COPYRIGHT = "productCopyright"; + private static final String DEFAULT_SITE = "productSite"; + private static final String DEFAULT_MAIL = "productMail"; + private static final String DEFAULT_NUMBER = "-1"; + private static final String DEFAULT_VENDOR = "productVendor"; + private static final String DEFAULT_NAME = "productName"; + private static final String BUILD_KEY = "build"; + private static final String VERSION_KEY = "version"; + private static final String COPYRIGHT_KEY = "copyright"; + private static final String SITE_KEY = "site"; + private static final String MAIL_KEY = "mail"; + private static final String VENDOR_KEY = "vendor"; + private static final String NAME_KEY = "name"; + + private static String name; + private static String vendor; + private static String versionNumber; + private static String majorNumber; + private static String minorNumber; + private static String buildDate; + private static String mail; + private static String site; + private static String copyright; + + public static void init() { + try { + ResourceBundle version = ResourceBundle.getBundle("eu.engys.resources.version"); + name = version.getString(NAME_KEY); + vendor = version.getString(VENDOR_KEY); + mail = version.getString(MAIL_KEY); + site = version.getString(SITE_KEY); + copyright = version.getString(COPYRIGHT_KEY); + + String v = version.getString(VERSION_KEY); + + try (Scanner s = new Scanner(v)) { + s.useDelimiter("\\."); + versionNumber = s.next(); + majorNumber = s.next(); + minorNumber = s.next(); + } catch (Exception e) { + name = DEFAULT_NAME; + vendor = DEFAULT_VENDOR; + versionNumber = DEFAULT_NUMBER; + majorNumber = DEFAULT_NUMBER; + minorNumber = DEFAULT_NUMBER; + mail = DEFAULT_MAIL; + site = DEFAULT_SITE; + copyright = DEFAULT_COPYRIGHT; + } + + buildDate = version.getString(BUILD_KEY); + } catch (Exception e) { + e.printStackTrace(); + name = DEFAULT_NAME; + vendor = DEFAULT_VENDOR; + versionNumber = DEFAULT_NUMBER; + majorNumber = DEFAULT_NUMBER; + minorNumber = DEFAULT_NUMBER; + mail = DEFAULT_MAIL; + site = DEFAULT_SITE; + copyright = DEFAULT_COPYRIGHT; + } + } + + public static String getTitle() { + return name != null ? ASCIIArt.toAA(name) : ""; + } + + public static String getName() { + return name != null ? name : DEFAULT_NAME; + } + + public static String getLicenseServerName() { + return name != null ? name + "_LICENSE_SERVER_NAME" : DEFAULT_NAME; + } + + public static String getLicenseServerPort() { + return name != null ? name + "_LICENSE_SERVER_PORT" : DEFAULT_NAME; + } + + public static String getVendor() { + return vendor != null ? vendor : DEFAULT_VENDOR; + } + + public static String getMail() { + return mail != null ? mail : DEFAULT_MAIL; + } + + public static String getSite() { + return site != null ? site : DEFAULT_SITE; + } + + public static String getCopyright() { + return copyright != null ? copyright : DEFAULT_COPYRIGHT; + } + + public static String getVersionRelease() { + return versionNumber; + } + + public static String getVersionMajor() { + return majorNumber; + } + + public static String getVersionMinor() { + return minorNumber; + } + + public static String getBuildDate() { + return buildDate; + } + + public static String getVersion() { + return "v" + versionNumber + "." + majorNumber + "." + minorNumber; + } + + public static String getRootPath() { + URL appJarURL = ApplicationInfo.class.getProtectionDomain().getCodeSource().getLocation(); + File appJarFile; + try { + appJarFile = new File(appJarURL.toURI()); + } catch (URISyntaxException e) { + appJarFile = new File(appJarURL.getPath()); + } + return appJarFile.getParentFile().getParent(); + } + + public static File getHome() { + String userHome = FileUtils.getUserDirectoryPath(); + File userDir; + try { + userDir = new File(userHome, "." + getName()); + } catch (Exception e) { + userDir = new File(userHome, ".test"); + } + + if (!userDir.exists()) { + userDir.mkdirs(); + } + + return userDir; + } + + public static File getPrefsFile() { + final File userHome = getHome(); + final File userPrefs = new File(userHome, "application.properties"); + return userPrefs; + } + + public static String getHeaderInfo() { + StringBuilder sb = new StringBuilder(); + sb.append(getTitle()); + sb.append("\n PRODUCT"); + sb.append("\n -----------------------------------------------------"); + sb.append("\n Name: " + getName()); + sb.append("\n Vendor: " + getVendor()); + sb.append("\n Release Date: " + getBuildDate()); + sb.append("\n Version: " + getVersion()); + sb.append("\n Mail: " + getMail()); + sb.append("\n Site: " + getSite()); + sb.append("\n Copyright: " + getCopyright()); + sb.append("\n"); + sb.append("\n SYSTEM"); + sb.append("\n -----------------------------------------------------"); + sb.append("\n Date: " + new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy").format(new Date())); + sb.append("\n OS: " + System.getProperty("os.name") + " " + System.getProperty("os.version") + " " + System.getProperty("os.arch")); + sb.append("\n Language " + Locale.getDefault().getLanguage()); + sb.append("\n Country " + Locale.getDefault().getCountry()); + sb.append("\n"); + String hostName = ""; + String hostIp = ""; + try { + InetAddress address = InetAddress.getLocalHost(); + hostName = address.getHostName(); + hostIp = address.getHostAddress(); + } catch (UnknownHostException ex) { + hostName = "UNKNOWN"; + hostIp = "UNKNOWN"; + } + sb.append("\n NETWORK"); + sb.append("\n -----------------------------------------------------"); + sb.append("\n Hostname " + hostName); + sb.append("\n Ip " + hostIp); + sb.append("\n"); + sb.append("\n JAVA"); + sb.append("\n -----------------------------------------------------"); + sb.append("\n Version " + System.getProperty("java.version")); + sb.append("\n Vendor " + System.getProperty("java.vendor")); + sb.append("\n Home " + System.getProperty("java.home")); + sb.append("\n ClassVersion " + System.getProperty("java.class.version")); + sb.append("\n ClassPath " + getClassPath()); + sb.append("\n"); + sb.append("\n USER"); + sb.append("\n -----------------------------------------------------"); + sb.append("\n Name " + System.getProperty("user.name")); + sb.append("\n Home " + System.getProperty("user.home")); + sb.append("\n Dir " + System.getProperty("user.dir")); + if (System.getProperty("license.status") != null) { + sb.append("\n LICENSE"); + sb.append("\n -----------------------------------------------------"); + sb.append("\n " + System.getProperty("license.status")); + sb.append("\n Register " + System.getProperty("license.register")); + sb.append("\n Exp. Date " + System.getProperty("license.exp.date")); + } + return sb.toString(); + } + + public static String getClassPath() { + return System.getProperty("java.class.path").replace(File.pathSeparator, "\n "); + } +} diff --git a/src/eu/engys/util/ArchiveUtils.java b/src/eu/engys/util/ArchiveUtils.java new file mode 100644 index 0000000..9fa5568 --- /dev/null +++ b/src/eu/engys/util/ArchiveUtils.java @@ -0,0 +1,363 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; +import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream; +import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; +import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; +import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.io.FilenameUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ArchiveUtils { + + private final static int BUFFER = 2048; + + public static final String ZIP = "zip"; + public static final String BZ2 = "bz2"; + public static final String TAR = "tar"; + public static final String GZ = "gz"; + + private static final Logger logger = LoggerFactory.getLogger(ArchiveUtils.class); + + public static List unarchive(File archiveFile, File destinationDir) { + return unarchive(archiveFile, destinationDir, ""); + } + + public static List unarchive(File archiveFile, File destinationDir, String prefix) { + String fileName = archiveFile.getName(); + if (isZip(fileName)) { + return unzip(archiveFile, destinationDir, prefix); + } + if (isTarGz(fileName)) { + return untarGZ(archiveFile, destinationDir, prefix); + } + if (isTarBz2(fileName)) { + return untarBZ2(archiveFile, destinationDir, prefix); + } + if (isGz(fileName)) { + return unGZ(archiveFile, destinationDir, prefix); + } + logger.error("Unknown archive type"); + return new ArrayList<>(); + } + + /* + * ZIP + */ + + public static void zip(File zipFile, File... sourceFiles) { + try { + ZipArchiveOutputStream zOut = new ZipArchiveOutputStream(zipFile); + for (File file : sourceFiles) { + addToZipArchive(zOut, file, ""); + } + IOUtils.closeQuietly(zOut); + } catch (IOException e) { + logger.error("Error creating archive", e); + } + } + + public static List unzip(File zipFile, File destinationDir) { + return unzip(zipFile, destinationDir, ""); + } + + public static List unzip(File zipFile, File destinationDir, String prefix) { + try { + ZipFile zip = new ZipFile(zipFile); + return extractFromZipArchive(destinationDir, zip, prefix); + } catch (IOException e) { + logger.error("Error creating archive", e); + } + return new ArrayList<>(); + } + + /* + * TAR.BZ2 + */ + + public static void tarBZ2(File tarBZ2File, File... sourceFiles) { + try { + FileOutputStream fOut = new FileOutputStream(tarBZ2File); + BufferedOutputStream bOut = new BufferedOutputStream(fOut); + BZip2CompressorOutputStream bz2Out = new BZip2CompressorOutputStream(bOut); + TarArchiveOutputStream tOut = new TarArchiveOutputStream(bz2Out); + + for (File file : sourceFiles) { + addToTarArchive(tOut, file, ""); + } + + IOUtils.closeQuietly(tOut); + IOUtils.closeQuietly(bz2Out); + IOUtils.closeQuietly(bOut); + IOUtils.closeQuietly(fOut); + } catch (IOException e) { + logger.error("Error creating archive", e); + } + } + + public static List untarBZ2(File tarBZ2File, File destinationDir) { + return untarBZ2(tarBZ2File, destinationDir, ""); + } + + public static List untarBZ2(File tarBZ2File, File destinationDir, String prefix) { + try { + InputStream fin = new FileInputStream(tarBZ2File); + InputStream in = new BufferedInputStream(fin); + InputStream bz2In = new BZip2CompressorInputStream(in); + return extractFromTarArchive(destinationDir, new TarArchiveInputStream(bz2In), prefix); + } catch (IOException e) { + logger.error("Error creating archive", e); + } + return new ArrayList<>(); + } + + /* + * TAR.GZ + */ + + public static void tarGZ(File tarGZFile, File... sourceFiles) { + try { + FileOutputStream fOut = new FileOutputStream(tarGZFile); + BufferedOutputStream bOut = new BufferedOutputStream(fOut); + GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(bOut); + TarArchiveOutputStream tOut = new TarArchiveOutputStream(gzOut); + + for (File file : sourceFiles) { + addToTarArchive(tOut, file, ""); + } + + IOUtils.closeQuietly(tOut); + IOUtils.closeQuietly(gzOut); + IOUtils.closeQuietly(bOut); + IOUtils.closeQuietly(fOut); + } catch (IOException e) { + logger.error("Error creating archive", e); + } + } + + public static List untarGZ(File tarGZFile, File destinationDir) { + return untarGZ(tarGZFile, destinationDir, ""); + } + + public static List untarGZ(File tarGZFile, File destinationDir, String prefix) { + try { + FileInputStream fin = new FileInputStream(tarGZFile); + BufferedInputStream in = new BufferedInputStream(fin); + GzipCompressorInputStream gzIn = new GzipCompressorInputStream(in); + return extractFromTarArchive(destinationDir, new TarArchiveInputStream(gzIn), prefix); + } catch (IOException e) { + logger.error("Error creating archive", e); + } + return new ArrayList<>(); + } + + /* + * GZ + */ + + public static void gz(File gzFile, File sourceFile) { + try { + FileOutputStream fOut = new FileOutputStream(gzFile); + BufferedOutputStream bOut = new BufferedOutputStream(fOut); + GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(bOut); + FileInputStream fin = new FileInputStream(sourceFile); + + IOUtils.copy(fin, gzOut); + + IOUtils.closeQuietly(fin); + IOUtils.closeQuietly(gzOut); + IOUtils.closeQuietly(bOut); + IOUtils.closeQuietly(fOut); + } catch (IOException e) { + logger.error("Error creating archive", e); + } + } + + public static List unGZ(File tarGZFile, File destinationDir) { + return unGZ(tarGZFile, destinationDir, ""); + } + + public static List unGZ(File gzFile, File destinationDir, String prefix) { + try { + FileInputStream fin = new FileInputStream(gzFile); + BufferedInputStream in = new BufferedInputStream(fin); + GzipCompressorInputStream gzIn = new GzipCompressorInputStream(in); + + File newFile = new File(destinationDir, prefix + FilenameUtils.removeExtension(gzFile.getName())); + copyInputStreamToOutputStream(gzIn, newFile); + + IOUtils.closeQuietly(gzIn); + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(fin); + + return Arrays.asList(new File[] { newFile }); + + } catch (IOException e) { + logger.error("Error creating archive", e); + } + return new ArrayList<>(); + } + + /* + * Utils + */ + + private static boolean isZip(String fileName) { + return FilenameUtils.getExtension(fileName).equalsIgnoreCase(ZIP); + } + + private static boolean isGz(String fileName) { + String firstExtension = FilenameUtils.getExtension(fileName); + String secondExtension = FilenameUtils.getExtension(FilenameUtils.removeExtension(fileName)); + return firstExtension.equals(GZ) && !secondExtension.equals(TAR); + } + + private static boolean isTarGz(String fileName) { + String firstExtension = FilenameUtils.getExtension(fileName); + String secondExtension = FilenameUtils.getExtension(FilenameUtils.removeExtension(fileName)); + return firstExtension.equals(GZ) && secondExtension.equals(TAR); + } + + private static boolean isTarBz2(String fileName) { + String firstExtension = FilenameUtils.getExtension(fileName); + String secondExtension = FilenameUtils.getExtension(FilenameUtils.removeExtension(fileName)); + return firstExtension.equals(BZ2) && secondExtension.equals(TAR); + } + + public static boolean isArchive(File file) { + return isZip(file.getName()) || isGz(file.getName()) || isTarGz(file.getName()) || isTarBz2(file.getName()); + } + + private static void addToZipArchive(ArchiveOutputStream zOut, File fileToAdd, String basePath) throws IOException { + String entryName = basePath + fileToAdd.getName(); + + ArchiveEntry entry = new ZipArchiveEntry(fileToAdd, entryName); + zOut.putArchiveEntry(entry); + + if (fileToAdd.isFile()) { + FileInputStream fInputStream = new FileInputStream(fileToAdd); + IOUtils.copy(fInputStream, zOut); + zOut.closeArchiveEntry(); + IOUtils.closeQuietly(fInputStream); + } else { + zOut.closeArchiveEntry(); + for (File child : fileToAdd.listFiles()) { + addToZipArchive(zOut, child, entryName + File.separator); + } + } + } + + private static void addToTarArchive(ArchiveOutputStream zOut, File fileToAdd, String basePath) throws IOException { + String entryName = basePath + fileToAdd.getName(); + + ArchiveEntry entry = new TarArchiveEntry(fileToAdd, entryName); + zOut.putArchiveEntry(entry); + + if (fileToAdd.isFile()) { + FileInputStream fInputStream = new FileInputStream(fileToAdd); + IOUtils.copy(fInputStream, zOut); + zOut.closeArchiveEntry(); + IOUtils.closeQuietly(fInputStream); + } else { + zOut.closeArchiveEntry(); + for (File child : fileToAdd.listFiles()) { + addToTarArchive(zOut, child, entryName + File.separator); + } + } + } + + private static List extractFromTarArchive(File destinationDir, TarArchiveInputStream tarIn, String prefix) throws IOException { + List extractedFiles = new ArrayList<>(); + ArchiveEntry entry = null; + while ((entry = (ArchiveEntry) tarIn.getNextEntry()) != null) { + File entryFile = new File(destinationDir, prefix + entry.getName()); + if (entry.isDirectory()) { + entryFile.mkdirs(); + } else { + entryFile.getParentFile().mkdirs(); + entryFile.createNewFile(); + copyInputStreamToOutputStream(tarIn, entryFile); + + extractedFiles.add(entryFile); + } + } + tarIn.close(); + return extractedFiles; + } + + private static List extractFromZipArchive(File destinationDir, ZipFile zipFile, String prefix) throws IOException { + List extractedFiles = new ArrayList<>(); + List entries = Collections.list(zipFile.getEntries()); + for (ZipArchiveEntry entry : entries) { + File entryFile = new File(destinationDir, prefix + entry.getName()); + if (entry.isDirectory()) { + entryFile.mkdirs(); + } else { + entryFile.getParentFile().mkdirs(); + entryFile.createNewFile(); + + InputStream is = zipFile.getInputStream(entry); + copyInputStreamToOutputStream(is, entryFile); + IOUtils.closeQuietly(is); + + extractedFiles.add(entryFile); + } + } + zipFile.close(); + return extractedFiles; + } + + private static void copyInputStreamToOutputStream(InputStream is, File outputFile) throws IOException { + FileOutputStream fos = new FileOutputStream(outputFile); + BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER); + IOUtils.copy(is, bos); + IOUtils.closeQuietly(bos); + } + +} diff --git a/src/eu/engys/util/ColorUtil.java b/src/eu/engys/util/ColorUtil.java new file mode 100644 index 0000000..e07c4f9 --- /dev/null +++ b/src/eu/engys/util/ColorUtil.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; + +public class ColorUtil { + + private static final List colors = new ArrayList<>(); + + static { + colors.add(Color.RED); + colors.add(Color.BLUE); + colors.add(Color.GREEN); + colors.add(Color.YELLOW); + colors.add(Color.PINK); + colors.add(Color.CYAN); + colors.add(Color.MAGENTA); + colors.add(Color.ORANGE); + colors.add(Color.RED.darker()); + colors.add(Color.BLUE.darker()); + colors.add(Color.GREEN.darker()); + colors.add(Color.YELLOW.darker()); + colors.add(Color.PINK.darker()); + colors.add(Color.CYAN.darker()); + colors.add(Color.MAGENTA.darker()); + colors.add(Color.ORANGE.darker()); + } + + public static Color getColor(int index) { + Color color = colors.size() > index ? colors.get(index) : null; + return color; + } + +} diff --git a/src/eu/engys/util/CompactCharSequence.java b/src/eu/engys/util/CompactCharSequence.java new file mode 100644 index 0000000..ba2b094 --- /dev/null +++ b/src/eu/engys/util/CompactCharSequence.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; + +public class CompactCharSequence implements CharSequence, Serializable { + + static final long serialVersionUID = 1L; + + private static final String ENCODING = "ISO-8859-1"; + private final int offset; + private final int end; + private final byte[] data; + + public CompactCharSequence(String str) { + try { + data = str.getBytes(ENCODING); + offset = 0; + end = data.length; + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Unexpected: " + ENCODING + " not supported!"); + } + } + + public CompactCharSequence(byte[] data, int offset, int end) { + this.data = data; + this.offset = offset; + this.end = end; + } + + public char charAt(int index) { + int ix = index+offset; + if (ix >= end) { + throw new StringIndexOutOfBoundsException("Invalid index " + + index + " length " + length()); + } + return (char) (data[ix] & 0xff); + } + + public int length() { + return end - offset; + } + + public CharSequence subSequence(int start, int end) { + if (start < 0 || end > (this.end-offset)) { + throw new IllegalArgumentException("Illegal range " + + start + "-" + end + " for sequence of length " + length()); + } + return new CompactCharSequence(data, start + offset, end + offset); + } + + public String toString() { + try { + return new String(data, offset, end-offset, ENCODING); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Unexpected: " + ENCODING + " not supported"); + } + } + + public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) + { + if (srcBegin < 0) + throw new StringIndexOutOfBoundsException(srcBegin); + if ((srcEnd < 0) || (srcEnd > end)) + throw new StringIndexOutOfBoundsException(srcEnd); + if (srcBegin > srcEnd) + throw new StringIndexOutOfBoundsException("srcBegin > srcEnd"); + + System.arraycopy(data, srcBegin, dst, dstBegin, srcEnd - srcBegin); + } +} diff --git a/src/eu/engys/util/CompactStringBuilder.java b/src/eu/engys/util/CompactStringBuilder.java new file mode 100644 index 0000000..fd2a247 --- /dev/null +++ b/src/eu/engys/util/CompactStringBuilder.java @@ -0,0 +1,107 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import java.util.Arrays; + + +public class CompactStringBuilder { + + /** + * The value is used for character storage. + */ + byte[] value; + + /** + * The count is the number of characters used. + */ + int count; + + /** + * Creates an CompactStringBuilder of 16 . + */ + public CompactStringBuilder() { + value = new byte[16]; + } + + /** + * Creates an CompactStringBuilder of the specified capacity. + */ + public CompactStringBuilder(int capacity) { + value = new byte[capacity]; + } + + public int length() { + return count; + } + + public void append(String str) { + if (str == null) str = "null"; + int len = str.length(); + + ensureCapacityInternal(count + len); + + CompactCharSequence compactString = new CompactCharSequence(str); + compactString.getBytes(0, len, value, count); + + count += len; + } + + /** + * This method has the same contract as ensureCapacity, but is + * never synchronized. + */ + private void ensureCapacityInternal(int minimumCapacity) { + // overflow-conscious code + if (minimumCapacity - value.length > 0) + expandCapacity(minimumCapacity); + } + + /** + * This implements the expansion semantics of ensureCapacity with no + * size check or synchronization. + */ + void expandCapacity(int minimumCapacity) { + int newCapacity = value.length * 2 + 2; + if (newCapacity - minimumCapacity < 0) + newCapacity = minimumCapacity; + if (newCapacity < 0) { + if (minimumCapacity < 0) // overflow + throw new OutOfMemoryError(); + newCapacity = Integer.MAX_VALUE; + } + value = Arrays.copyOf(value, newCapacity); + } + + @Override + public String toString() { + return new CompactCharSequence(value, 0, count).toString(); + } + + public CharSequence toCompactCharSequence() { + return new CompactCharSequence(value, 0, count); + } +} diff --git a/src/eu/engys/util/DimensionalUnits.java b/src/eu/engys/util/DimensionalUnits.java new file mode 100644 index 0000000..7bab234 --- /dev/null +++ b/src/eu/engys/util/DimensionalUnits.java @@ -0,0 +1,59 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +public class DimensionalUnits { + + /* + * [ + * 0 -> Mass [kg] + * 0 -> Length [m] + * 0 -> Time [s] + * 0 -> Temperature [K] + * 0 -> Quantity [kg-mol] + * 0 -> Current [A] + * 0 -> Luminous Intensity (cd) + * ] + */ + + public static final String NONE = "[0 0 0 0 0 0 0]"; + public static final String _K = "[0 0 0 -1 0 0 0]"; + public static final String K = "[0 0 0 1 0 0 0]"; + public static final String S = "[0 0 1 0 0 0 0]"; + public static final String _M = "[0 -1 0 0 0 0 0]"; + public static final String _M2 = "[0 -2 0 0 0 0 0]"; + public static final String M2_S = "[0 2 -1 0 0 0 0]"; + public static final String M2_S2 = "[0 2 -2 0 0 0 0]"; + public static final String M2_S2K = "[0 2 -2 -1 0 0 0]"; + + public static final String KG_S2 = "[1 0 -2 0 0 0 0]"; + public static final String KG_M3 = "[1 -3 0 0 0 0 0]"; + public static final String KG_MS = "[1 -1 -1 0 0 0 0]"; + public static final String KG_MS2 = "[1 -1 -2 0 0 0 0]"; + public static final String KGM_S3K = "[1 1 -3 -1 0 0 0]"; + + +} diff --git a/src/eu/engys/util/FormatUtil.java b/src/eu/engys/util/FormatUtil.java new file mode 100644 index 0000000..f6bc9fb --- /dev/null +++ b/src/eu/engys/util/FormatUtil.java @@ -0,0 +1,115 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +public class FormatUtil { + + private static final DecimalFormat decFormat = new DecimalFormat("#.#", new DecimalFormatSymbols(Locale.US)); + private static final DecimalFormat centsFormat = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US)); + private static final DecimalFormat millisFormat = new DecimalFormat("#.###", new DecimalFormatSymbols(Locale.US)); + + public interface Formatter { + String toCents(); + String toMillis(); + } + + private static class FormatterImpl implements Formatter { + + private double value; + + public FormatterImpl(double value) { + this.value = value; + } + + @Override + public String toCents() { + return centsFormat.format(value); + } + + @Override + public String toMillis() { + return millisFormat.format(value); + } + + @Override + public String toString() { + return toCents(); + } + } + + private static class ArrayFormatterImpl implements Formatter { + + private double[] value; + + public ArrayFormatterImpl(double[] value) { + this.value = value; + } + + @Override + public String toCents() { + return format(centsFormat); + } + + @Override + public String toMillis() { + return format(millisFormat); + } + + private String format(DecimalFormat format){ + StringBuilder b = new StringBuilder(); + b.append('['); + for (int i=0; i lines = Arrays.asList(text.split(lineEnding)); + writeLinesToFile(file, lines); + } + + public static void writeLinesToFile(File file, List lines) { + String lineEnding = Util.isWindowsScriptStyle() ? WIN_EOL : EOL; + try { + FileUtils.writeLines(file, null, lines, lineEnding); + } catch (IOException e) { + logger.error("Error writing file {}: {} ", file, e.getMessage()); + } + } + + /* + * Read File + */ + + public static List readLinesFromFile(File file) { + try { + return FileUtils.readLines(file, (Charset) null); + } catch (IOException e) { + logger.error("Error reading file {}: {} ", file, e.getMessage()); + } + return Collections.emptyList(); + } + + public static String readStringFromFile(File file) { + try { + return FileUtils.readFileToString(file, (Charset) null); + } catch (IOException e) { + logger.error("Error reading file {}: {} ", file, e.getMessage()); + } + return ""; + } + + public static String readStringFromStream(InputStream input) throws IOException { + return org.apache.commons.io.IOUtils.toString(input); + } + + public static File getSupportFile(File pwd) { + String extension = Util.isWindows() ? ".bat" : ".run"; + String name = "temp" + System.currentTimeMillis() + extension; + return new File(pwd, name); + } + +} diff --git a/src/eu/engys/util/LineSeparator.java b/src/eu/engys/util/LineSeparator.java new file mode 100644 index 0000000..cbae5f5 --- /dev/null +++ b/src/eu/engys/util/LineSeparator.java @@ -0,0 +1,64 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +public enum LineSeparator { + + DOS("\r\n", "DOS (CR+LF)"), + UNIX("\n", "UNIX (LF)"), + MAC("\r", "Mac (CR)"), + PLATFORM_DEPENDENT(System.getProperty("line.separator"), "Platform dependent"); + + private String separator; + private String label; + + LineSeparator(String separator, String label) { + this.separator = separator; + this.label = label; + } + + public String getSeparator() { + return separator; + } + + public String getLabel() { + return label; + } + + public static LineSeparator getLineSeparator(String separator) { + for (LineSeparator lineSeparator : LineSeparator.values()) { + if (separator.equals(lineSeparator.getSeparator())) { + return lineSeparator; + } + } + throw new IllegalArgumentException("Unknown line separator: " + separator); + } + + public static LineSeparator getDefaultLineSeparator() { + return getLineSeparator(System.getProperty("line.separator")); + } + +} diff --git a/src/eu/engys/util/MemoryWidget.java b/src/eu/engys/util/MemoryWidget.java new file mode 100644 index 0000000..dd0808f --- /dev/null +++ b/src/eu/engys/util/MemoryWidget.java @@ -0,0 +1,153 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ +package eu.engys.util; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.font.FontRenderContext; +import java.awt.font.LineMetrics; +import java.awt.geom.Rectangle2D; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.Timer; +import javax.swing.ToolTipManager; + +public class MemoryWidget extends JComponent implements ActionListener { + + public static final String PROTOTYPE_STRING = " 9999 / 9999 MB "; + + private final LineMetrics lm; + private final Color progressForeground = new JTable().getSelectionForeground(); + private final Color progressBackground = new JTable().getSelectionBackground(); + + private Timer timer; + + private long free = Runtime.getRuntime().freeMemory(); + private long total = Runtime.getRuntime().totalMemory(); + private long max = Runtime.getRuntime().maxMemory(); + + class MouseHandler extends MouseAdapter { + @Override + public void mousePressed(MouseEvent evt) { + if (evt.getClickCount() == 2) { + System.gc(); + repaint(); + } + } + } + + public MemoryWidget() { + Font font = new JLabel().getFont(); + setFont(font); + + FontRenderContext frc = new FontRenderContext(null, false, false); + Rectangle2D bounds = font.getStringBounds(PROTOTYPE_STRING, frc); + Dimension dim = new Dimension((int) bounds.getWidth(), (int) bounds.getHeight()); + setPreferredSize(dim); + setMaximumSize(dim); + lm = font.getLineMetrics(PROTOTYPE_STRING, frc); + + setForeground(new JLabel().getForeground()); + setBackground(new JLabel().getBackground()); + +// progressForeground = jEdit.getColorProperty("view.status.memory.foreground"); +// progressBackground = jEdit.getColorProperty("view.status.memory.background"); + + addMouseListener(new MouseHandler()); + } + + @Override + public void addNotify() { + super.addNotify(); + timer = new Timer(2000, this); + timer.start(); + ToolTipManager.sharedInstance().registerComponent(this); + } + + @Override + public void removeNotify() { + timer.stop(); + ToolTipManager.sharedInstance().unregisterComponent(this); + super.removeNotify(); + } + + /** + * see specification at http://stackoverflow.com/a/18375641 + */ + public void actionPerformed(ActionEvent evt) { + Runtime runtime = Runtime.getRuntime(); + this.free = runtime.freeMemory(); + this.total = runtime.totalMemory(); + this.max = runtime.maxMemory(); + repaint(); + } + + @Override + public void paintComponent(Graphics g) { + Insets insets = new Insets(0, 0, 0, 0);// MemoryStatus.this.getBorder().getBorderInsets(this); + + long used = total - free; + + int width = getWidth() - insets.left - insets.right; + int height = getHeight() - insets.top - insets.bottom - 1; + + float fraction = ((float) used) / max; + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(progressBackground); + g2.fillRect(insets.left, insets.top, (int) (width * fraction), height); + + String str = (used / 1024 / 1024) + " / " + (max / 1024 / 1024) + " MB"; + FontRenderContext frc = new FontRenderContext(null, false, false); + Rectangle2D bounds = g2.getFont().getStringBounds(str, frc); + + Graphics g3 = g2.create(); + g3.setClip(insets.left, insets.top, (int) (width * fraction), height); + g3.setColor(progressForeground); + + int textX = insets.left + ((int) (width - bounds.getWidth()) / 2); + int textY = (int) (insets.top + height/2 + lm.getAscent() / 2); + g3.drawString(str, textX, textY); + g3.dispose(); + + g3 = g2.create(); + g3.setClip(insets.left + (int) (width * fraction), insets.top, getWidth() - insets.left - (int) (width * fraction), height); + g3.setColor(getForeground()); + g3.drawString(str, insets.left + ((int) (width - bounds.getWidth()) >> 1), textY); + g3.dispose(); + } +} diff --git a/src/eu/engys/util/OpenFOAMCommands.java b/src/eu/engys/util/OpenFOAMCommands.java new file mode 100644 index 0000000..722aa32 --- /dev/null +++ b/src/eu/engys/util/OpenFOAMCommands.java @@ -0,0 +1,249 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import static eu.engys.util.IOUtils.WIN_EOL; + +import java.io.File; + +public class OpenFOAMCommands { + + private static final String _ALL_REGIONS = "-allRegions"; + private static final String _NO_FUNCTION_OBJECTS = "-noFunctionObjects"; + private static final String _FORCE = "-force"; + private static final String _CONSTANT = "-constant"; + private static final String _ZERO_TIME = "-zeroTime"; + private static final String _WITH_ZERO = "-withZero"; + private static final String _OVERWRITE = "-overwrite"; + private static final String _SCALE = "-scale"; + private static final String _PARALLEL = "-parallel"; + + // Flag to solve a problem with mpirun on OpenSUSE 12.3 where a default file is not installed correctly + private static final String _DEFAULT_HOST_FILE = PrefUtil.getBoolean(PrefUtil.DEFAULT_HOSTFILE_NONE) ? "--default-hostfile none" : ""; + + private static final String GENVLIST = "-genvlist HOME,PATH,USERNAME,WM_PROJECT_DIR,WM_PROJECT_INST_DIR,WM_OPTIONS,FOAM_LIBBIN,FOAM_APPBIN,FOAM_USER_APPBIN,FOAM_CONFIG,MPI_BUFFER_SIZE"; + + private static final String CASE() { + return Util.isWindowsScriptStyle() ? "\"%CASE%\"" : "$CASE"; + } + + private static final String SOLVER() { + return Util.isWindowsScriptStyle() ? "\"%SOLVER%\"" : "$SOLVER"; + } + + private static final String _CASE() { + return "-case " + CASE(); + } + + private static final String _TEE_LOG() { + return "2>&1 | " + (Util.isWindowsScriptStyle() ? "wtee -a \"%LOG%\"" : "tee -a $LOG"); + } + + private static final String _MPI_NP() { + return Util.isWindowsScriptStyle() ? "mpiexec -n %NP% %MACHINEFILE% %MPI_ACCESSORY_OPTIONS% " + GENVLIST : "mpirun " + _DEFAULT_HOST_FILE + " -np $NP $MACHINEFILE"; + } + + private static final String _BLOCK_MESH_DICT() { + return "-dict " + (Util.isWindowsScriptStyle() ? "system\\blockMeshDict" : "system/blockMeshDict"); + } + + private static final String COMMAND(String command, String log) { + if (Util.isWindowsScriptStyle()) { + String errorFile = "errorcode.txt"; + StringBuilder sb = new StringBuilder(); + sb.append("set COMMAND=" + command + WIN_EOL); + sb.append(WIN_EOL); + sb.append("set ERROR_HANDLER=call echo %%^^errorlevel%% ^>" + errorFile + WIN_EOL); + sb.append(WIN_EOL); + sb.append("(%COMMAND% & %%ERROR_HANDLER%%) " + log + WIN_EOL); + sb.append(WIN_EOL); + sb.append("set /p ERR=<" + errorFile + WIN_EOL); + sb.append("del " + errorFile + WIN_EOL); + sb.append(WIN_EOL); + sb.append("IF %ERR% NEQ 0 exit %ERR%" + WIN_EOL); + return sb.toString(); + } else { + return command + " " + log; + } + } + + /* + * MESH Commands + */ + public static final String BLOCK_MESH() { + return COMMAND("blockMesh " + _BLOCK_MESH_DICT() + " " + _CASE(), _TEE_LOG()); + } + + public static final String MERGE_MESHES(String filePath) { + return COMMAND("mergeMeshes " + _OVERWRITE + " " + _NO_FUNCTION_OBJECTS + " " + _CASE() + " " + CASE() + " \"" + filePath + "\"", _TEE_LOG()); + } + + public static final String RECONSTRUCT_PAR_MESH() { + return COMMAND("reconstructParMesh " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String RECONSTRUCT_PAR_MESH_CONSTANT() { + return COMMAND("reconstructParMesh " + _NO_FUNCTION_OBJECTS + " " + _CASE() + " " + _CONSTANT, _TEE_LOG()); + } + + public static final String RECONSTRUCT_PAR_MESH_ALLREGIONS() { + return COMMAND("reconstructParMesh " + " " + _NO_FUNCTION_OBJECTS + " " + _CASE() + " " + _ALL_REGIONS, _TEE_LOG()); + } + + public static final String RECONSTRUCT_PAR_MESH_CONSTANT_ALLREGIONS() { + return COMMAND("reconstructParMesh " + " " + _NO_FUNCTION_OBJECTS + " " + _CASE() + " " + _CONSTANT + " " + _ALL_REGIONS, _TEE_LOG()); + } + + public static final String CHECK_MESH_SERIAL() { + return COMMAND("checkMesh " + _CASE(), _TEE_LOG()); + } + + public static final String CHECK_MESH_PARALLEL() { + return COMMAND(_MPI_NP() + " checkMesh " + _PARALLEL + " " + _CASE(), _TEE_LOG()); + } + + public static final String SNAPPY_CHECK_MESH_SERIAL() { + return COMMAND("snappyCheckMesh -writeAllMetrics " + _CASE(), _TEE_LOG()); + } + + public static final String SNAPPY_CHECK_MESH_PARALLEL() { + return COMMAND(_MPI_NP() + " snappyCheckMesh -writeAllMetrics " + _PARALLEL + " " + _CASE(), _TEE_LOG()); + } + + public static final String RUN_MESH_SERIAL() { + return COMMAND("snappyHexMesh " + _OVERWRITE + " " + _CASE(), _TEE_LOG()); + } + + public static final String RUN_MESH_PARALLEL() { + return COMMAND(_MPI_NP() + " snappyHexMesh " + _PARALLEL + " " + _OVERWRITE + " " + _CASE(), _TEE_LOG()); + } + + public static final String EXTRUDE_REGION_TO_MESH() { + return COMMAND("extrudeToRegionMesh " + _OVERWRITE + " " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + /* + * Solver + */ + public static final String RUN_CASE_SERIAL() { + return COMMAND(SOLVER() + " " + _CASE(), _TEE_LOG()); + } + + public static final String RUN_CASE_PARALLEL() { + return COMMAND(_MPI_NP() + " " + SOLVER() + " " + _PARALLEL + " " + _CASE(), _TEE_LOG()); + } + + /* + * Fields + */ + + public static final String SET_FIELDS_SERIAL() { + return COMMAND("setFields " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String SET_FIELDS_PARALLEL() { + return COMMAND(_MPI_NP() + " setFields " + _PARALLEL + " " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String INITIALISE_FIELDS_SERIAL() { + return COMMAND("caseSetup " + _CASE(), _TEE_LOG()); + } + + public static final String INITIALISE_FIELDS_PARALLEL() { + return COMMAND(_MPI_NP() + " caseSetup " + _PARALLEL + " " + _CASE(), _TEE_LOG()); + } + + public static final String PAR_MAP_FIELDS_SERIAL() { + return COMMAND("parMapFields " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String PAR_MAP_FIELDS_PARALLEL() { + return COMMAND(_MPI_NP() + " parMapFields " + _PARALLEL + " " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + /* + * Other + */ + + public static final String DECOMPOSE_PAR() { + return COMMAND("decomposePar " + _FORCE + " " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String DECOMPOSE_PAR_CONSTANT() { + return COMMAND("decomposePar " + _FORCE + " " + _NO_FUNCTION_OBJECTS + " " + _CASE() + " " + _CONSTANT, _TEE_LOG()); + } + + public static final String DECOMPOSE_PAR_ALLREGIONS() { + return COMMAND("decomposePar " + _FORCE + " " + _NO_FUNCTION_OBJECTS + " " + _CASE() + " " + _ALL_REGIONS, _TEE_LOG()); + } + + public static final String DECOMPOSE_PAR_CONSTANT_ALLREGIONS() { + return COMMAND("decomposePar " + _FORCE + " " + _NO_FUNCTION_OBJECTS + " " + _CASE() + " " + _CONSTANT + " " + _ALL_REGIONS, _TEE_LOG()); + } + + public static final String RECONSTRUCT_PAR(boolean useWithZeroFlag) { + return COMMAND("reconstructPar " + (useWithZeroFlag ? _WITH_ZERO : _ZERO_TIME) + " " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String RECONSTRUCT_PAR_ALLREGIONS(boolean useWithZeroFlag) { + return COMMAND("reconstructPar " + (useWithZeroFlag ? _WITH_ZERO : _ZERO_TIME) + " " + _NO_FUNCTION_OBJECTS + " " + _CASE() + " " + _ALL_REGIONS, _TEE_LOG()); + } + + public static final String FLUENT_TO_FOAM(Double scale, String fluentFileName) { + String separator = Util.isWindowsScriptStyle() ? "\\" : "/"; + return COMMAND("fluent3DMeshToFoam " + _SCALE + " " + scale + " " + _NO_FUNCTION_OBJECTS + " " + _CASE() + " " + CASE() + separator + fluentFileName, _TEE_LOG()); + } + + public static final String RENUMBER_SERIAL() { + return COMMAND("renumberMesh " + _OVERWRITE + " " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String RENUMBER_PARALLEL() { + return COMMAND(_MPI_NP() + " renumberMesh " + _PARALLEL + " " + _OVERWRITE + " " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String FOAM_MESH_TO_STAR() { + return COMMAND("foamToStarMesh " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String FOAM_MESH_TO_FLUENT() { + return COMMAND("foamMeshToFluent " + _NO_FUNCTION_OBJECTS + " " + _CASE(), _TEE_LOG()); + } + + public static final String CAD_TOOL(boolean split, double precision, File input, File output) { + String byComponentFlag = split ? " -byComponent" : ""; + String precisionFlag = "-relativeSpacing " + precision; + String inputFlag = "-inputFile " + input.getName(); + String outputFlag = "-outputFile " + output.getName(); + + return COMMAND("CADtoSurface" + byComponentFlag + " " + precisionFlag + " " + inputFlag + " " + outputFlag, _TEE_LOG()); + } + + public static final String FRONTAL_AREA = "frontalArea"; + public static final String MOVE_TO_CASE_FOLDER_WIN = "cd /D \"%CASE%\""; + public static final String PARA_FOAM = "paraFoam"; + +} diff --git a/src/eu/engys/util/PDFFileFilter.java b/src/eu/engys/util/PDFFileFilter.java new file mode 100644 index 0000000..392fdae --- /dev/null +++ b/src/eu/engys/util/PDFFileFilter.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import java.io.File; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.filefilter.IOFileFilter; + +public class PDFFileFilter implements IOFileFilter { + + private String toBeContained; + + public PDFFileFilter(String toBeContained) { + this.toBeContained = toBeContained; + } + + @Override + public boolean accept(File file) { + boolean isPDF = FilenameUtils.getExtension(file.getAbsolutePath()).equals("pdf"); + boolean containsKey = file.getName().contains(toBeContained); + return isPDF && containsKey; + } + + @Override + public boolean accept(File parentDir, String fileName) { + return false; + } + +} diff --git a/src/eu/engys/util/PrefUtil.java b/src/eu/engys/util/PrefUtil.java new file mode 100644 index 0000000..a086f0f --- /dev/null +++ b/src/eu/engys/util/PrefUtil.java @@ -0,0 +1,257 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util; + +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.io.FileUtils; + +public class PrefUtil { + + public static final String USER_NAME = System.getProperty("user.name"); + public static final String USER_HOME = System.getProperty("user.home"); + public static final String USER_DIR = System.getProperty("user.dir"); + + public static final String FAVORITES_KEY = "filechooser.favorites"; + +// public static final String DOC_KEY = "doc.basedir"; + public static final String OPENFOAM_KEY = "openfoam.basedir"; + public static final String PARAVIEW_KEY = "paraview.basedir"; + public static final String FIELDVIEW_KEY = "fieldview.basedir"; + public static final String ENSIGHT_KEY = "ensight.basedir"; + + // batch + public static final String SERVER_CONNECTION_MAX_TRIES = "batch.connection.max.tries"; + public static final String SERVER_CONNECTION_REFRESH_TIME = "batch.connection.wait.time"; + public static final String SERVER_WAIT_FOR_RUN_REFRESH_TIME = "batch.running.wait.time"; + + public static final String SCRIPT_RUN_REFRESH_TIME = "batch.script.refresh.time"; + public static final String SCRIPT_WAIT_FOR_KILL_REFRESH_TIME = "batch.script.kill.wait.time"; + + public static final String BATCH_MONITOR_DIALOG_MAX_ROW = "batch.monitor.dialog.max.row"; + + // 3d + public static final String _3D_LOCK_INTRACTIVE_MEMORY = "3d.lock.intractive.memory"; + public static final String _3D_LOCK_INTRACTIVE_TIME = "3d.lock.intractive.time"; + public static final String _3D_TRANSPARENCY_MEMORY = "3d.transparency.memory"; + + // misc + public static final String RECENT_PROJECTS = "recent.projects"; + public static final String HELYX_DEFAULT_TERMINAL = "helyx.default.terminal"; + public static final String DEFAULT_HOSTFILE_NONE = "default.hostfile.none"; + public static final String HELYX_DEFAULT_FILE_MANAGER = "default.file.manager"; + public static final String HELYX_DEFAULT_FILE_OPENER = "default.file.opener"; + public static final String MATERIALS_USER_LIB = "materials.user.lib."; + public static final String HIDE_EMPTY_PATCHES = "hide.empty.patches"; + + // files + public static final String WORK_DIR = "last.open.dir"; + public static final String LAST_IMPORT_DIR = "last.import.dir"; + public static final String LAST_OPEN_EXPORT_DIR = "last.export.dir"; + + // license + public static final String LICENSE_SERVER_NAME = "license.server.name"; + public static final String LICENSE_SERVER_PORT = "license.server.port"; + + private static CompositeConfiguration configuration; + + private static CompositeConfiguration configuration() { + if (configuration == null) { + reload(); + } + return configuration; + } + + public static void reload() { + try { + deleteOldPrefsFolders(); + removeDuplicatedLines(ApplicationInfo.getPrefsFile()); + + PropertiesConfiguration defaults = new PropertiesConfiguration("eu/engys/resources/application.properties"); + + PropertiesConfiguration preferences = new PropertiesConfiguration(ApplicationInfo.getPrefsFile()); + preferences.setDelimiterParsingDisabled(true); + preferences.setAutoSave(true); + + configuration = new CompositeConfiguration(); + configuration.setDelimiterParsingDisabled(true); + configuration.addConfiguration(preferences, true); + configuration.addConfiguration(defaults); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void deleteOldPrefsFolders() throws IOException { + File home = new File(PrefUtil.USER_HOME); + File java = new File(home, ".java"); + if (java.exists()) { + File userPrefs = new File(java, ".userPrefs"); + if (userPrefs.exists()) { + File eu = new File(userPrefs, "eu"); + if (eu.exists()) { + FileUtils.deleteQuietly(eu); + } + } + } + File helyx = new File(home, ".HELYX"); + if (helyx.exists()) { + File userPrefs = new File(helyx, ".userPrefs"); + if (userPrefs.exists()) { + FileUtils.deleteQuietly(userPrefs); + } + } + } + + private static void removeDuplicatedLines(File file) throws IOException { + if (file.exists()) { + List fileLines = FileUtils.readLines(file); + Set lines = new LinkedHashSet<>(fileLines); + boolean hasDuplicateLines = fileLines.size() > lines.size(); + if(hasDuplicateLines){ + String lineEnding = Util.isWindowsScriptStyle() ? LineSeparator.DOS.getSeparator() : LineSeparator.UNIX.getSeparator(); + FileUtils.writeLines(file, null, lines, lineEnding); + } + } + } + + public static File getWorkDir(String key) { + return Util.isWindows() ? getFile(key, USER_HOME) : new File(USER_DIR); + } + + private static File getFile(String key) { + return getFile(key, null); + } + + private static File getFile(String key, String def) { + String path = configuration().getString(key, def); + return path == null ? null : new File(path); + } + + public static void putFile(String key, File file) { + configuration().setProperty(key, file == null ? "" : file.getAbsolutePath()); + } + + public static String getString(String key) { + return getString(key, ""); + } + + public static String getString(String key, String def) { + return configuration().getString(key, def); + } + + public static void putString(String key, String value) { + configuration().setProperty(key, value); + } + + public static int getInt(String key) { + return configuration().getInt(key, 0); + } + + public static int getInt(String key, int def) { + return configuration().getInt(key, def); + } + + public static void putInt(String key, int value) { + configuration().setProperty(key, String.valueOf(value)); + } + + public static void putBoolean(String key, boolean value) { + configuration().setProperty(key, Boolean.valueOf(value)); + } + + public static Boolean getBoolean(String key) { + return configuration().getBoolean(key); + } + + public static InetAddress getInetAddress(String key, InetAddress def) { + try { + return InetAddress.getByName(configuration().getString(key, def.getHostAddress())); + } catch (Exception e) { + return def; + } + } + + public static void putInetAddress(String key, InetAddress value) { + configuration().setProperty(key, value.getHostAddress()); + } + + public static File getFieldViewEntry() { + return getFile(FIELDVIEW_KEY); + } + + public static void setFieldViewEntry(File value) { + putFile(FIELDVIEW_KEY, value); + } + + public static File getEnsightEntry() { + return getFile(ENSIGHT_KEY); + } + + public static void setEnsightEntry(File value) { + putFile(ENSIGHT_KEY, value); + } + + public static File getParaViewEntry() { + return getFile(PARAVIEW_KEY); + } + + public static void setParaViewEntry(File value) { + putFile(PARAVIEW_KEY, value); + } + + public static File getOpenFoamEntry() { + return getFile(OPENFOAM_KEY); + } + + public static void setOpenFoamEntry(File value) { + putFile(OPENFOAM_KEY, value); + } + + public static void remove(String key) { + configuration().clearProperty(key); + } + + public static Object getDefaultValue(String key) { + try { + PropertiesConfiguration defaults = new PropertiesConfiguration("eu/engys/resources/application.properties"); + Object defaultProp = defaults.getProperty(key); + return defaultProp; + } catch (ConfigurationException e) { + return null; + } + + } +} diff --git a/src/eu/engys/util/RegexpUtils.java b/src/eu/engys/util/RegexpUtils.java new file mode 100644 index 0000000..5562f13 --- /dev/null +++ b/src/eu/engys/util/RegexpUtils.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +public class RegexpUtils { + + public static final String DOUBLE = "\\-?\\d+\\.?\\d*(?:[eE][+-]?\\d+)?"; + public static final String INTEGER = "\\-?\\d+[^.eE\\d+]"; + + public static final String POINT = "\\(\\s*" + DOUBLE + "\\s" + DOUBLE + "\\s" + DOUBLE + "\\s*\\)"; + + public static final String SPACES = "\\s*"; + + public static final String OPEN_BRACKET = "\\("; + public static final String CLOSED_BRACKET = "\\)"; + + public static final String OPEN_TAG_BRACKET = "\\<"; + public static final String CLOSED_TAG_BRACKET = "\\>"; + public static final String COMA = "\\s*,\\s*"; + +} diff --git a/src/eu/engys/util/Symbols.java b/src/eu/engys/util/Symbols.java new file mode 100644 index 0000000..34d6f10 --- /dev/null +++ b/src/eu/engys/util/Symbols.java @@ -0,0 +1,123 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util; + +public class Symbols { + + public static final String THETA = "\u03B8"; + public static final String PHI = "\u03C6"; + + public static final String CUBE = "\u00B3"; + public static final String SQUARE = "\u00B2"; + public static final String SUBSCRIPT_2 = "\u2082"; + public static final String MINUS_ONE = "\u02C9\u00B9"; + public static final String DOT = "\u00B7"; + + public static final String PASCAL = "[Pa]"; + public static final String KELVIN = "[K]"; + public static final String KELVIN_ON_SECONDS = "[K/s]"; + public static final String KELVIN_PER_VOLUME_ON_SECONDS = "[K"+DOT+"m"+CUBE+"/s]"; + public static final String M2_S2 = "[m" + SQUARE + "/s" + SQUARE + "]"; + public static final String M2_S = "[m" + SQUARE + "/s]"; + + public static final String M_S = "[m/s]"; + public static final String K_SYMBOL = "[m" + SQUARE + "/s" + SQUARE + "]"; + public static final String EPSILON_SYMBOL = "[m" + SQUARE + "/s" + CUBE + "]"; + public static final String OMEGA_SYMBOL = "[1/s]"; + + public static final String MU_MEASURE = "[Pa" + DOT + "s]"; + public static final String NU_MEASURE = "[m" + SQUARE + "/s]"; + public static final String LAMBDA_MEASURE = "[W/m" + DOT + "K]"; + + public static final String WATT = "[W]"; + public static final String WATT_ON_KELVIN = "[W/K]"; + public static final String WATT_ON_VOLUME = "[W/m"+CUBE+"]"; + public static final String WATT_ON_VOLUME_PER_KELVIN = "[W/K"+DOT+"m"+CUBE+"]"; + + public static final String LAMBDA = "\u03BB"; + public static final String MU = "\u03BC"; + public static final String NU = "\u03BD"; + public static final String RHO = "\u03C1"; + + public static final String CP = "[J/Kg" + DOT + "K]"; + public static final String HF = "[J/Kg]"; + public static final String DENSITY = "[Kg/m" + CUBE + "]"; + public static final String MASS_ON_SECONDS_PER_VOLUME = "[kg/s"+DOT+"m"+CUBE+"]"; + public static final String VOLUME_ON_SECONDS = "[m"+CUBE+"/s]"; + public static final String MASS_ON_SECONDS = "[Kg/s]"; + public static final String AREA = "[m" + SQUARE + "]"; + + public static final String HOURS = "hrs"; + + public static final String COPYRIGHT = "\u00A9"; + public static final String REGISTERED = "\u00AE"; + public static final String DELTA = "\u0394"; + public static final String DELTA_T = DELTA + "t"; + public static final String DOTS = "\u2026"; + public static final String ESC = "\u001b"; + public static final String TILDE = "\u223C"; + + public static final String PLUS_UPPERCASE = "\u207A"; + public static final String DOUBLE_ARROW = "\u2194"; + public static final String DEGREE_SIGN = "\u00B0"; + + public static String PEDICE(int number) { + String numberToString = String.valueOf(number); + String pedice = ""; + for (char c : numberToString.toCharArray()) { + pedice += PEDICE(c); + } + return pedice; + } + + public static char PEDICE(char c) { + switch (c) { + case '0': + return '\u2080'; + case '1': + return '\u2081'; + case '2': + return '\u2082'; + case '3': + return '\u2083'; + case '4': + return '\u2084'; + case '5': + return '\u2085'; + case '7': + return '\u2086'; + case '8': + return '\u2087'; + case '9': + return '\u2088'; + default: + return ' '; + } + + } + +} diff --git a/src/eu/engys/util/TempFolder.java b/src/eu/engys/util/TempFolder.java new file mode 100644 index 0000000..6ae3eb7 --- /dev/null +++ b/src/eu/engys/util/TempFolder.java @@ -0,0 +1,80 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ +package eu.engys.util; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TempFolder { + + private static final Logger logger = LoggerFactory.getLogger(TempFolder.class); + + private static final String sessionID; + + static { + sessionID = String.valueOf(System.currentTimeMillis() / 1000); + } + + public static File get(String... folders) { + File userTemp = new File(ApplicationInfo.getHome(), "tmp"); + if (!userTemp.exists()) { + userTemp.mkdirs(); + } + + final File sessionTemp = new File(userTemp, "tmp_" + sessionID); + if (!sessionTemp.exists()) { + if (sessionTemp.mkdirs()) { + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + public void run() { + FileUtils.deleteQuietly(sessionTemp); + } + })); + } else { + logger.error("Cannot create session temporary folder: {}"); + } + } + + if (folders.length > 0) { + Path path = Paths.get(sessionTemp.getAbsolutePath(), folders); + try { + Files.createDirectories(path); + return path.toFile(); + } catch (IOException e) { + logger.error("Cannot create path: {}", path); + throw new RuntimeException(e); + } + } else { + return sessionTemp; + } + } + +} diff --git a/src/eu/engys/util/TooltipUtils.java b/src/eu/engys/util/TooltipUtils.java new file mode 100644 index 0000000..068a251 --- /dev/null +++ b/src/eu/engys/util/TooltipUtils.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import java.util.ArrayList; +import java.util.List; + +public class TooltipUtils { + + private static final int TOOLTIP_MAX_SIZE = 80; + private static final String HTML_START = ""; + private static final String HTML_END = ""; + public static final String NEW_LINE = "
"; + + public static String format(String tooltip) { + if(tooltip == null) return null; + List chunks = getChunks(tooltip); + StringBuilder sb = new StringBuilder(HTML_START); + for (int i = 0; i < chunks.size() - 1; i++) { + sb.append(chunks.get(i) + NEW_LINE); + } + sb.append(chunks.get(chunks.size() - 1)); + sb.append((HTML_END)); + return sb.toString(); + } + + private static List getChunks(String tooltip) { + List chunks = new ArrayList<>(); + if (tooltip.length() <= TOOLTIP_MAX_SIZE || tooltip.contains(NEW_LINE)) { + chunks.add(tooltip); + } else { + int splitIndex = tooltip.substring(0, TOOLTIP_MAX_SIZE + 1).lastIndexOf(" "); + chunks.add(tooltip.substring(0, splitIndex)); + chunks.addAll(getChunks(tooltip.substring(splitIndex + 1, tooltip.length()))); + } + return chunks; + + } +} diff --git a/src/eu/engys/util/Util.java b/src/eu/engys/util/Util.java new file mode 100644 index 0000000..c4d036b --- /dev/null +++ b/src/eu/engys/util/Util.java @@ -0,0 +1,595 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import static java.nio.file.LinkOption.NOFOLLOW_LINKS; +import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; +import static java.nio.file.StandardWatchEventKinds.OVERFLOW; + +import java.awt.Desktop; +import java.io.BufferedReader; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.FileSystem; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.WatchEvent; +import java.nio.file.WatchEvent.Kind; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.net.util.Base64; + +import com.jcraft.jsch.jce.Random; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.WinNT; + +public final class Util { + + public enum ScriptStyle { + WINDOWS, LINUX; + } + + private static ScriptStyle scriptStyle = ScriptStyle.LINUX; + + public static void initScriptStyle() { + scriptStyle = isWindows() ? ScriptStyle.WINDOWS : ScriptStyle.LINUX; + } + + public static boolean isWindowsScriptStyle() { + return scriptStyle == ScriptStyle.WINDOWS; + } + + public static boolean isUnixScriptStyle() { + return scriptStyle == ScriptStyle.LINUX; + } + + public static void setScriptStyle(ScriptStyle scriptStyle) { + Util.scriptStyle = scriptStyle; + } + + public static String getTrimmedSingleSpaceLine(String string) { + return string.trim().replaceAll("\\s+", " "); + } + + public static final String getStringFromList(List list, int itemsPerRow) { + StringBuilder sb = new StringBuilder(); + sb.append("[ "); + for (int i = 0; i < list.size(); i++) { + sb.append(list.get(i)); + if (i == list.size() - 1) { + sb.append("]"); + } else { + sb.append(", "); + if ((i + 1) % itemsPerRow == 0) { + sb.append("\n"); + } + } + + } + return sb.toString(); + } + + public static String replaceForbiddenCharacters(String name) { + char[] charArray = name.toCharArray(); + if (Character.isDigit(charArray[0])) + charArray[0] = '_'; + for (int i = 0; i < charArray.length; i++) { + if (Util.isForbidden(charArray[i])) { + charArray[i] = '_'; + } + } + return new String(charArray); + } + + public static String padWithSpaces(String string, int lenght) { + if (string.length() > lenght) { + return string; + } else { + StringBuilder sb = new StringBuilder(); + sb.append(string); + for (int i = 0; i < lenght - string.length(); i++) { + sb.append(" "); + } + return sb.toString(); + } + } + + public static String[] fromKeystoLabels(String[] keys) { + String[] labels = new String[keys.length]; + for (int i = 0; i < labels.length; i++) { + labels[i] = fromKeyToLabel(keys[i]); + } + return labels; + } + + private static String fromKeyToLabel(String key) { + StringBuilder sb = new StringBuilder(); + sb.append(Character.toUpperCase(key.charAt(0))); + for (int i = 1; i < key.length(); i++) { + char c = key.charAt(i); + if (Character.isUpperCase(c)) + sb.append(" "); + sb.append(c); + } + return sb.toString(); + } + + public static boolean isWindows() { + String os = System.getProperty("os.name").toLowerCase(); + // windows + return (os.indexOf("win") >= 0); + } + + public static boolean isMac() { + String os = System.getProperty("os.name").toLowerCase(); + // Mac + return (os.indexOf("mac") >= 0); + } + + public static boolean isUnix() { + String os = System.getProperty("os.name").toLowerCase(); + // linux or unix + return (os.indexOf("nix") >= 0 || os.indexOf("nux") >= 0); + } + + public static boolean isSolaris() { + String os = System.getProperty("os.name").toLowerCase(); + // Solaris + return (os.indexOf("sunos") >= 0); + } + + public static int[] getFactorsFor(int np) { + int cubeRoot = (int) Math.ceil(Math.cbrt(np)); + int firstFactor = 1; + int secondFactor = 1; + int thirdFactor = 1; + + for (int i = cubeRoot; i <= np; i++) { + if (np % i == 0) { + firstFactor = i; + break; + } + } + + int remainder = np / firstFactor; + int squareRoot = (int) Math.ceil(Math.sqrt(remainder)); + + for (int j = squareRoot; j <= remainder; j++) { + if (remainder % j == 0) { + secondFactor = j; + break; + } + } + + if (secondFactor > firstFactor) { + int tmp = secondFactor; + secondFactor = firstFactor; + firstFactor = tmp; + } + + thirdFactor = np / firstFactor / secondFactor; + return new int[] { firstFactor, secondFactor, thirdFactor }; + } + + public static int getLinuxProcessId(Process proc) throws Exception { + if (proc.getClass().getName().equals("java.lang.UNIXProcess")) { + Field f = proc.getClass().getDeclaredField("pid"); + f.setAccessible(true); + int pid = f.getInt(proc); + return pid; + } + return 0; + } + + public static int getWindowsProcessId(Process proc) throws Exception { + if (proc.getClass().getName().equals("java.lang.Win32Process") || proc.getClass().getName().equals("java.lang.ProcessImpl")) { + /* determine the pid on windows plattforms */ + Field f = proc.getClass().getDeclaredField("handle"); + f.setAccessible(true); + long handl = f.getLong(proc); + Kernel32 kernel = Kernel32.INSTANCE; + WinNT.HANDLE handle = new WinNT.HANDLE(); + handle.setPointer(Pointer.createConstant(handl)); + return kernel.GetProcessId(handle); + } + return 0; + } + + public static boolean isRunning(String program) { + if (isWindows()) { + String listOfProcesses = getCommandOutput("tasklist"); + if (listOfProcesses == null || listOfProcesses.isEmpty()) { + return false; + } else { + if (listOfProcesses.contains(program)) { + return true; + } else { + return false; + } + } + } else { + String listOfProcesses = getCommandOutput("ps -f"); + // System.err.println(listOfProcesses); + if (listOfProcesses == null || listOfProcesses.isEmpty()) { + return false; + } else { + if (listOfProcesses.contains(program)) { + return true; + } else { + return false; + } + } + } + } + + public static String getCommandOutput(String command) { + String output = null; // the string to return + + Process process = null; + BufferedReader reader = null; + InputStreamReader streamReader = null; + InputStream stream = null; + + try { + process = Runtime.getRuntime().exec(command); + + // Get stream of the console running the command + stream = process.getInputStream(); + streamReader = new InputStreamReader(stream); + reader = new BufferedReader(streamReader); + + String currentLine = null; // store current line of output from the + // cmd + StringBuilder commandOutput = new StringBuilder(); // build up the + // output from + // cmd + while ((currentLine = reader.readLine()) != null) { + commandOutput.append(currentLine + "\n"); + } + + int returnCode = process.waitFor(); + if (returnCode == 0) { + output = commandOutput.toString(); + } + System.err.println(output); + } catch (IOException e) { + System.err.println("Cannot retrieve output of command"); + System.err.println(e); + output = null; + } catch (InterruptedException e) { + System.err.println("Cannot retrieve output of command"); + System.err.println(e); + } finally { + // Close all inputs / readers + + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + System.err.println("Cannot close stream input! " + e); + } + } + if (streamReader != null) { + try { + streamReader.close(); + } catch (IOException e) { + System.err.println("Cannot close stream input reader! " + e); + } + } + if (reader != null) { + try { + streamReader.close(); + } catch (IOException e) { + System.err.println("Cannot close stream input reader! " + e); + } + } + } + // Return the output from the command - may be null if an error occured + return output; + } + + public static void deepCopy(double[] source, double[] target) { + if (source == null || target == null) + throw new IllegalArgumentException("Arrays should be not null"); + if (source.length != target.length) + throw new IllegalArgumentException("Arrays should have same length"); + + for (int i = 0; i < source.length; i++) { + target[i] = source[i]; + } + } + + public static void deepCopy(int[] source, int[] target) { + if (source == null || target == null) + throw new IllegalArgumentException("Arrays should be not null"); + if (source.length != target.length) + throw new IllegalArgumentException("Arrays should have same length"); + + for (int i = 0; i < source.length; i++) { + target[i] = source[i]; + } + + } + + @SuppressWarnings("unchecked") + public static boolean isVarArgsNotNull(O... objs) { + return isVarArgsNotNullAndOfSize(-1, objs); + } + + @SuppressWarnings("unchecked") + public static boolean isVarArgsNotNullAndOfSize(int length, O... objs) { + boolean notNull = objs != null; + if (!notNull) + return false; + boolean correctSize = length < 0 ? objs.length > 0 : objs.length == length; + if (!correctSize) + return false; + boolean elementsNotNull = true; + for (O object : objs) { + elementsNotNull &= (object != null); + } + return notNull && correctSize && elementsNotNull; + } + + public static Map invertMap(Map map) { + Map out = new HashMap<>(map.size()); + java.util.Map.Entry entry; + for (Iterator> it = map.entrySet().iterator(); it.hasNext(); out.put(entry.getValue(), entry.getKey())) + entry = it.next(); + + return out; + } + + public static Map sortMapByValues(Map passedMap, boolean descending, boolean useAbsoluteValues) { + List mapKeys = new ArrayList(passedMap.keySet()); + Collections.sort(mapKeys); + + List mapValues = new ArrayList(passedMap.values()); + if (useAbsoluteValues) { + Collections.sort(mapValues, new Comparator() { + @Override + public int compare(Double o1, Double o2) { + return Double.valueOf(Math.abs(o1)).compareTo(Double.valueOf(Math.abs(o2))); + } + }); + } else { + Collections.sort(mapValues); + } + if (descending) { + Collections.reverse(mapValues); + } + + Map sortedMap = new LinkedHashMap(); + + Iterator valueIt = mapValues.iterator(); + while (valueIt.hasNext()) { + Double val = valueIt.next(); + Iterator keyIt = mapKeys.iterator(); + + while (keyIt.hasNext()) { + String key = keyIt.next(); + String comp1 = String.valueOf(Math.abs(passedMap.get(key))); + String comp2 = String.valueOf(Math.abs(val)); + + if (comp1.equals(comp2)) { + passedMap.remove(key); + mapKeys.remove(key); + sortedMap.put(key, val); + break; + } + + } + + } + return sortedMap; + } + + public static boolean canWrite(File folder) { + if (!folder.canWrite()) { + return false; + } + try { + File testFile = Paths.get(folder.getAbsoluteFile().toURI()).resolve("testWrite").toFile(); + if (testFile.exists()) { + testFile.delete(); + } + boolean res = testFile.createNewFile(); + if (res) { + testFile.delete(); + } + return res; + } catch (Exception e) { + return false; + } + } + + public static void openWebpage(URL url) { + try { + openWebpage(url.toURI()); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } + + private static void openWebpage(URI uri) { + Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; + if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) { + try { + desktop.browse(uri); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public static String encrypt(String value) { + if (!value.isEmpty()) { + try { + return Base64.encodeBase64String(value.getBytes()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return value; + } + + public static String decrypt(String value) { + if (!value.isEmpty()) { + return new String(Base64.decodeBase64(value)); + } + return value; + } + + public static String[] getNumericSubFolders(File parentDir) { + String[] folders = parentDir.list(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + try { + Double.parseDouble(name); + return dir.isDirectory(); + } catch (NumberFormatException nfee) { + return false; + } + } + }); + if (folders != null) { + Arrays.sort(folders, new Comparator() { + public int compare(String s1, String s2) { + return Double.valueOf(s1).compareTo(Double.valueOf(s2)); + } + }); + return folders; + } else { + return new String[0]; + } + } + + public static void watchDirectoryPath(Path path) { + // Sanity check - Check if path is a folder + try { + Boolean isFolder = (Boolean) Files.getAttribute(path, "basic:isDirectory", NOFOLLOW_LINKS); + if (!isFolder) { + throw new IllegalArgumentException("Path: " + path + " is not a folder"); + } + } catch (IOException ioe) { + // Folder does not exists + ioe.printStackTrace(); + } + + // System.out.println("Watching path: " + path); + + // We obtain the file system of the Path + FileSystem fs = path.getFileSystem(); + + // We create the new WatchService using the new try() block + try (WatchService service = fs.newWatchService()) { + + // We register the path to the service + // We watch for creation events + path.register(service, ENTRY_CREATE); + + // Start the infinite polling loop + WatchKey key = null; + while (true) { + key = service.take(); + + // Dequeueing events + Kind kind = null; + for (WatchEvent watchEvent : key.pollEvents()) { + // Get the type of the event + kind = watchEvent.kind(); + if (OVERFLOW == kind) { + continue; // loop + } else if (ENTRY_CREATE == kind) { + // A new Path was created + // Path newPath = ((WatchEvent) + // watchEvent).context(); + // Output + // System.out.println("New path created: " + newPath); + } + } + + if (!key.reset()) { + break; // loop + } + } + + } catch (IOException ioe) { + ioe.printStackTrace(); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + + } + + public static String generateID() { + byte[] foo = new byte[4]; + Util.rnd.fill(foo, 0, foo.length); + String id = new String(Hex.encodeHex(foo)).toUpperCase(); + return id; + } + + public static String getMachineName() { + try { + return InetAddress.getLocalHost().getHostName(); + } catch (Exception e) { + return ""; + } + } + + public static final Random rnd = new Random(); + public static final int WINDOWS_MAX_FILENAME_LENGTH = 200; + + public static int boolToInt(boolean b) { + return b ? 1 : 0; + } + + public static boolean isForbidden(char ch) { + return !Character.isLetterOrDigit(ch) && " \"/\\*#$;".indexOf(ch) >= 0; + } + +} diff --git a/src/eu/engys/util/VTKSettings.java b/src/eu/engys/util/VTKSettings.java new file mode 100644 index 0000000..34744e3 --- /dev/null +++ b/src/eu/engys/util/VTKSettings.java @@ -0,0 +1,156 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkNativeLibrary; + +public class VTKSettings { + + private static final Logger logger = LoggerFactory.getLogger(VTKSettings.class); + + private static boolean librariesAreLoaded = false; + + public static void LoadAllNativeLibraries() { + librariesAreLoaded = true; + try { + if (!_LoadAllNativeLibraries()) { + for (vtkNativeLibrary lib : vtkNativeLibrary.values()) { + String libName = lib.GetLibraryName(); + if (lib.IsLoaded()) { + logger.info(libName + " loaded"); + } else { + librariesAreLoaded = false; + logger.error(libName + " NOT loaded"); + } + } + } else { + librariesAreLoaded = true; + logger.info("ALL VTK libraries loaded"); + } + } catch (Exception e) { + librariesAreLoaded = false; + logger.error("Error loading VTK libraries: " + e.getMessage()); + } + + if (librariesAreLoaded) { + vtkNativeLibrary.DisableOutputWindow(null); + } else { + librariesAreLoaded = false; + } + } + + private static boolean _LoadAllNativeLibraries() { + boolean isEveryThingLoaded = true; + for (vtkNativeLibrary lib : vtkNativeLibrary.values()) { + try { + if(lib.IsBuilt()) { + lib.LoadLibrary(); + } + } catch (UnsatisfiedLinkError e) { + isEveryThingLoaded = false; + //e.printStackTrace(); + } + } + + return isEveryThingLoaded; + } + + public static boolean librariesAreLoaded() { + return librariesAreLoaded; + } + +// private static final String COMMON = "vtkCommonJava"; +// private static final String FILTERING = "vtkFilteringJava"; +//// private static final String GEOVIS = "vtkGeovisJava"; +// private static final String GRAPHICS = "vtkGraphicsJava"; +// private static final String HYBRID = "vtkHybridJava"; +//// private static final String IMAGING = "vtkImagingJava"; +//// private static final String INFOVIS = "vtkInfovisJava"; +// private static final String IO = "vtkIOJava"; +// private static final String RENDERING = "vtkRenderingJava"; +// private static final String VIEWS = "vtkViewsJava"; +// private static final String VOLUME_RENDERING = "vtkVolumeRenderingJava"; +// private static final String WIDGETS = "vtkWidgetsJava"; +//// private static final String CHARTS = "vtkChartsJava"; +// private static final String PARALLEL = "vtkParallelJava"; +// +// private static boolean librariesAreLoaded = false; +// +// public static void LoadAllNativeLibraries() { +// librariesAreLoaded = true; +// +// loadLibrary(COMMON); +// loadLibrary(FILTERING); +// // loadLibrary(GEOVIS); +// loadLibrary(GRAPHICS); +// loadLibrary(PARALLEL); +// loadLibrary(HYBRID); +// // loadLibrary(IMAGING); +// // loadLibrary(INFOVIS); +// loadLibrary(IO); +// loadLibrary(RENDERING); +// loadLibrary(VIEWS); +// loadLibrary(VOLUME_RENDERING); +// loadLibrary(WIDGETS); +// // loadLibrary(CHARTS); +// +// if (librariesAreLoaded) { +// disableOutputWindow(null); +// } else { +// logger.warn("Make sure the search path is correct: "); +// logger.warn(System.getProperty("java.library.path")); +// librariesAreLoaded = false; +// return; +// } +// } +// +// private static void loadLibrary(String libName) { +// try { +// System.loadLibrary(libName); +// logger.info(libName + " loaded"); +// } catch (UnsatisfiedLinkError e) { +// logger.warn(libName + " NOT loaded: " + e.getMessage()); +// librariesAreLoaded = false; +// } +// } +// +// public static boolean librariesAreLoaded() { +// return librariesAreLoaded; +// } +// +// private static void disableOutputWindow(File logFile) { +// if (logFile == null) { +// logFile = new File("vtkError.txt"); +// } +// vtkFileOutputWindow outputError = new vtkFileOutputWindow(); +// outputError.SetFileName(logFile.getAbsolutePath()); +// outputError.SetInstance(outputError); +// } + +} diff --git a/src/eu/engys/util/VersionChecker.java b/src/eu/engys/util/VersionChecker.java new file mode 100644 index 0000000..587f68a --- /dev/null +++ b/src/eu/engys/util/VersionChecker.java @@ -0,0 +1,140 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.StringTokenizer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VersionChecker { + + private static final Logger logger = LoggerFactory.getLogger(VersionChecker.class); + + private static final String PATH = "http://engys.com/helyx-os/version.txt"; + + public enum VersionType { + + UPDATED, OLD, NOT_AVAILABLE; + + public boolean isUpdated(){ + return this == UPDATED; + } + + public boolean isOld(){ + return this == OLD; + } + + public boolean isNotAvailable(){ + return this == NOT_AVAILABLE; + } + + } + + public static VersionType isNewVersionAvailable() { + try { + String actual = getActualVersion(); + String online = getOnlineVersion(); + if (actual.isEmpty() || online.isEmpty()) { + return VersionType.NOT_AVAILABLE; + } + int[] actualNumber = extractVersionNumber(actual); + int[] onlineNumber = extractVersionNumber(online); + if (isEarlier(actualNumber, onlineNumber)) { + return VersionType.OLD; + } else { + return VersionType.UPDATED; + } + } catch (Exception e) { + return VersionType.NOT_AVAILABLE; + } + } + + public static int[] extractVersionNumber(String version) { + String versionNumber = version.replace("v", "").trim(); + final int[] vers = new int[3]; + final StringTokenizer token = new StringTokenizer(versionNumber, "."); + + for (int i = 0; i < 3; i++) { + if (token.hasMoreTokens()) { + try { + vers[i] = Integer.parseInt(token.nextToken()); + } catch (final Exception e) { + break; + } + } + } + + return vers; + } + + public static String getActualVersion() { + return ApplicationInfo.getVersion(); + } + + public static String getOnlineVersion() { + try { + URL url = new URL(PATH); + URLConnection uc = url.openConnection(); + + InputStreamReader input = new InputStreamReader(uc.getInputStream()); + BufferedReader in = new BufferedReader(input); + String inputLine; + StringBuffer sb = new StringBuffer(); + while ((inputLine = in.readLine()) != null) { + sb.append(inputLine); + } + in.close(); + return sb.toString(); + } catch (IOException e) { + logger.warn("Unable to find latest version online", e.getMessage()); + return ""; + } + } + + public static boolean isEarlier(int[] v1, int[] v2) { + boolean returnValue = false; + + if (!((v1 == null) || (v2 == null))) { + for (int i = 0; i < 3; i++) { + if (v1[i] < v2[i]) { + returnValue = true; + break; + } else if (v1[i] > v2[i]) { + break; + } + } + } + + return returnValue; + } + +} diff --git a/src/eu/engys/util/bean/AbstractBean.java b/src/eu/engys/util/bean/AbstractBean.java new file mode 100644 index 0000000..d8fbfef --- /dev/null +++ b/src/eu/engys/util/bean/AbstractBean.java @@ -0,0 +1,74 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.bean; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +import org.apache.commons.lang.ArrayUtils; + +public class AbstractBean { + + private transient PropertyChangeSupport support; + + public void addPropertyChangeListener(PropertyChangeListener listener) { + if (support == null) { + support = new PropertyChangeSupport(this); + } + support.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + if (support != null) { + support.removePropertyChangeListener(listener); + } + } + + public boolean isListenedBy(PropertyChangeListener listener) { + return ArrayUtils.contains(support.getPropertyChangeListeners(), listener); + } + + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + if (support == null) { + support = new PropertyChangeSupport(this); + } + support.firePropertyChange(propertyName, oldValue, newValue); + } + + protected void firePropertyChange(String propertyName, int oldValue, int newValue) { + if (support == null) { + support = new PropertyChangeSupport(this); + } + support.firePropertyChange(propertyName, oldValue, newValue); + } + + protected void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { + if (support == null) { + support = new PropertyChangeSupport(this); + } + support.firePropertyChange(propertyName, oldValue, newValue); + } +} diff --git a/src/eu/engys/util/bean/Bindings.java b/src/eu/engys/util/bean/Bindings.java new file mode 100644 index 0000000..244a3e4 --- /dev/null +++ b/src/eu/engys/util/bean/Bindings.java @@ -0,0 +1,64 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.bean; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.reflect.Method; + +import eu.engys.util.ui.textfields.DoubleField; + +public class Bindings { + + public static void bind(final DoubleField field, final Object bean, final String key) { + field.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + set(bean, key, field.getDoubleValue()); + } + } + }); + } + + private static void set(Object bean, String key, Object value) { + try { + Method method = bean.getClass().getMethod(toSetter(key), value.getClass()); + method.invoke(bean, value); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static String toSetter(String key) { + return "set" + key.substring(0, 1).toUpperCase() + key.substring(1); + } + + private static String toGetter(String key) { + return "get" + key.substring(0, 1).toUpperCase() + key.substring(1); + } + +} diff --git a/src/eu/engys/util/connection/QueueParameters.java b/src/eu/engys/util/connection/QueueParameters.java new file mode 100644 index 0000000..e3550a5 --- /dev/null +++ b/src/eu/engys/util/connection/QueueParameters.java @@ -0,0 +1,79 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.connection; + +public class QueueParameters { + + public static final String QUEUE_NODES = "numberOfNodes"; + public static final String QUEUE_CPUS = "cpuPerNode"; + public static final String QUEUE_TIMEOUT = "timeout"; + public static final String QUEUE_FEATURE = "feature"; + public static final String QUEUE_NAMES = "nodeNames"; + + private int numberOfNodes = 1; + private String nodeNames = ""; + private int cpuPerNode = 1; + private int timeout = 12; + private String feature = ""; + + public int getNumberOfNodes() { + return numberOfNodes; + } + public void setNumberOfNodes(int numberOfNodes) { + this.numberOfNodes = numberOfNodes; + } + public int getCpuPerNode() { + return cpuPerNode; + } + public void setCpuPerNode(int cpuPerNode) { + this.cpuPerNode = cpuPerNode; + } + public int getTimeout() { + return timeout; + } + public void setTimeout(int timeout) { + this.timeout = timeout; + } + public String getFeature() { + return feature; + } + public void setFeature(String feature) { + this.feature = feature; + } + public void setNodeNames(String nodeNames) { + this.nodeNames = nodeNames; + } + public String getNodeNames() { + return nodeNames; + } + + @Override + public String toString() { + return "Queue Parameters [ Number Of Nodes: " + numberOfNodes + " - Cpu Per Node: " + cpuPerNode + " - Feature: " + feature + " - Timeout: " + timeout + " ]"; + } + + +} diff --git a/src/eu/engys/util/connection/SshParameters.java b/src/eu/engys/util/connection/SshParameters.java new file mode 100644 index 0000000..c18cbfc --- /dev/null +++ b/src/eu/engys/util/connection/SshParameters.java @@ -0,0 +1,186 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.connection; + +import java.io.Serializable; + +public class SshParameters implements Serializable { + + public static final String USER = "user"; + public static final String SSH_PWD = "sshpwd"; + public static final String SSH_KEY = "sshkey"; + public static final String HOST = "host"; + public static final String PORT = "port"; + public static final String AUTHENTICATION = "sshauth"; + public static final String REMOTE_BASEDIR = "remoteBaseDir"; + public static final String REMOTE_BASEDIR_PARENT = "remoteBaseDirParent"; + public static final String APPLICATION_DIR = "applicationDir"; + public static final String OPENFOAM_DIR = "openFoamDir"; + public static final String PARAVIEW_DIR = "paraviewDir"; + + public enum AuthType { + SSH_KEY, SSH_PWD; + + public boolean isKey() { + return this == SSH_KEY; + } + } + + private int port = 22; + private String user = ""; + private String host = ""; + private String sshkey = ""; + private String sshpwd = ""; + + private String remoteBaseDir = ""; + private String remoteBaseDirParent = ""; + private String openFoamDir = ""; + private String paraviewDir = ""; + private String applicationDir = ""; + private AuthType sshauth = AuthType.SSH_PWD; + + public void copy(SshParameters sshParameters) { + setUser(sshParameters.getUser()); + setSshpwd(sshParameters.getSshpwd()); + setSshkey(sshParameters.getSshkey()); + setHost(sshParameters.getHost()); + setPort(sshParameters.getPort()); + setSshauth(sshParameters.getSshauth()); + setRemoteBaseDir(sshParameters.getRemoteBaseDir()); + setRemoteBaseDirParent(sshParameters.getRemoteBaseDirParent()); + setApplicationDir(sshParameters.getApplicationDir()); + setOpenFoamDir(sshParameters.getOpenFoamDir()); + setParaviewDir(sshParameters.getParaviewDir()); + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public AuthType getSshauth() { + return sshauth; + } + + public void setSshauth(AuthType sshauth) { + this.sshauth = sshauth; + } + + public String getSshkey() { + return sshkey; + } + + public void setSshkey(String sshkey) { + this.sshkey = sshkey; + } + + public String getSshpwd() { + return sshpwd; + } + + public void setSshpwd(String sshpwd) { + this.sshpwd = sshpwd; + } + + public String getRemoteBaseDir() { + return remoteBaseDir; + } + + public void setRemoteBaseDir(String remoteBaseDir) { + this.remoteBaseDir = remoteBaseDir; + } + + public String getRemoteBaseDirParent() { + return remoteBaseDirParent; + } + + public void setRemoteBaseDirParent(String remoteBaseDirParent) { + this.remoteBaseDirParent = remoteBaseDirParent; + } + + public String getOpenFoamDir() { + return openFoamDir; + } + + public void setOpenFoamDir(String openFoamDir) { + this.openFoamDir = openFoamDir; + } + + public void setParaviewDir(String paraviewDir) { + this.paraviewDir = paraviewDir; + } + + public String getParaviewDir() { + return paraviewDir; + } + + public String getApplicationDir() { + return applicationDir; + } + + public void setApplicationDir(String elementsDir) { + this.applicationDir = elementsDir; + } + + public boolean isValidForRemoteChooser() { + return (user != null) && (sshpwd != null) || (host != null); + } + + @Override + public String toString() { + return "SSHParameters: " + + "\nUSER [ " + getUser() + " ]" + + "\nHOST [ " + getHost() + " ]" + + "\nPORT [ " + getPort() + " ]" + + "\nAUTH [ " + getSshauth() + " ]" + + "\nPASS [ ******* ]" + + "\nKEY [ " + getSshkey() + " ]" + + "\nRDIR [ " + getRemoteBaseDir() + " ]" + + "\nCDIR [ " + getRemoteBaseDirParent() + " ]" + + "\nOFDIR [ " + getOpenFoamDir() + " ]" + + "\nPVDIR [ " + getParaviewDir() + " ]" + + "\nAPDIR [ " + getApplicationDir() + " ]"; + } +} diff --git a/src/eu/engys/util/connection/SshUtils.java b/src/eu/engys/util/connection/SshUtils.java new file mode 100644 index 0000000..a204b74 --- /dev/null +++ b/src/eu/engys/util/connection/SshUtils.java @@ -0,0 +1,618 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.connection; + +import java.awt.Container; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.URL; +import java.net.UnknownHostException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Vector; + +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.net.telnet.TelnetClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcraft.jsch.Channel; +import com.jcraft.jsch.ChannelExec; +import com.jcraft.jsch.ChannelSftp; +import com.jcraft.jsch.ChannelSftp.LsEntry; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import com.jcraft.jsch.SftpATTRS; +import com.jcraft.jsch.SftpException; +import com.jcraft.jsch.SftpProgressMonitor; +import com.jcraft.jsch.UIKeyboardInteractive; +import com.jcraft.jsch.UserInfo; + +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; + +public class SshUtils { + + public static final int TIMEOUT = 21000; + + private static final Logger logger = LoggerFactory.getLogger(SshUtils.class); + + private static final URL PLINK_URL = SshUtils.class.getClassLoader().getResource("eu/engys/gui/vtk/depot/ssh/plink.exe"); + + public enum Terminal { + XTERM, GNOMETERMINAL, KONSOLE + } + + public static boolean testTelnetConnection(String machine, int port) { + TelnetClient c = new TelnetClient(); + try { + c.connect(machine, port); + c.disconnect(); + return true; + } catch (IOException e) { + logger.error("TELNET: {}", e.getMessage()); + return false; + } + } + + public static boolean testPingConnection(String machine) { + try { + InetAddress address = InetAddress.getByName(machine); + address.isReachable(3000); + return true; + } catch (IOException e) { + logger.error(e.getMessage()); + return false; + } + } + + private static void checkParameters(SshParameters parameters) throws JSchException { + if (parameters.getUser() == null || parameters.getUser().isEmpty()) + throw new JSchException("Username not set"); + if (parameters.getHost() == null || parameters.getHost().isEmpty()) + throw new JSchException("Hostname not set"); + } + + public static Session createSession(SshParameters parameters) throws JSchException { + checkParameters(parameters); + + String user = parameters.getUser(); + String host = parameters.getHost(); + int port = parameters.getPort(); + String passwd = parameters.getSshpwd(); + boolean authWithKey = parameters.getSshauth().isKey(); + + if (authWithKey) { + Path key = Paths.get(parameters.getSshkey()); + return createSession(user, host, key, port); + } else { + return createSession(user, host, passwd, port); + } + } + + private static Session createSession(String user, String host, String password, int port) throws JSchException { + Session session = new JSch().getSession(user, host, port); + session.setPassword(password); + UserInfo ui = new MyUserInfo(); + session.setUserInfo(ui); + session.setConfig("compression.s2c", "zlib@openssh.com,zlib,none"); + session.setConfig("compression.c2s", "zlib@openssh.com,zlib,none"); + session.setConfig("compression_level", "9"); + logger.info("CREATE SESSION: CONNECT"); + session.connect(TIMEOUT); + logger.info("CREATE SESSION: CONNECTED"); + return session; + } + + private static Session createSession(String user, String host, Path privateKey, int port) throws JSchException { + JSch jsch = new JSch(); + jsch.addIdentity(privateKey.toString()); + Session session = jsch.getSession(user, host, port); + UserInfo ui = new MyUserInfo(); + session.setUserInfo(ui); + session.setConfig("compression.s2c", "zlib@openssh.com,zlib,none"); + session.setConfig("compression.c2s", "zlib@openssh.com,zlib,none"); + session.setConfig("compression_level", "9"); + session.connect(20000); + return session; + } + + public static ChannelExec createEXEChannel(Session session) throws JSchException { + Channel channel = session.openChannel("exec"); + logger.info("EXE CHANNEL: CREATED"); + return (ChannelExec) channel; + } + + public static ChannelSftp createSFTPChannel(Session session) throws JSchException { + Channel channel = session.openChannel("sftp"); + logger.info("SFTP CHANNEL: OPENED"); + channel.connect(); + logger.info("SFTP CHANNEL: CONNECTED"); + return (ChannelSftp) channel; + } + + public static void uploadFileOrFolder(Path localFile, String remoteDestination, ChannelSftp channel, ProgressMonitor monitor) throws SftpException, JSchException, IOException { + channel.cd(remoteDestination.toString()); + String remoteFile = remoteDestination + getFilePathSeparator(remoteDestination) + localFile.getFileName(); + if (remoteFileAlreadyExists(remoteFile, channel)) { + int res = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "File " + remoteFile + " already exists. Override?"); + if (res == JOptionPane.OK_OPTION) { + if (localFile.toFile().isDirectory()) { + // channel.rmdir gives an error + execSSHCommand("rm -rf " + remoteFile.toString(), channel.getSession()); + } else { + channel.rm(localFile.getFileName().toString()); + } + createFileOrFolder(localFile, remoteDestination, channel, monitor); + } + } else { + createFileOrFolder(localFile, remoteDestination, channel, monitor); + } + } + + public static void uploadFileOrFolderForced(Path localFile, String remoteDestination, ChannelSftp channel, ProgressMonitor monitor) throws SftpException, JSchException, IOException { + channel.cd(remoteDestination.toString()); + createFileOrFolder(localFile, remoteDestination, channel, monitor); + } + + public static void createFileOrFolder(Path localFile, String remoteDestination, ChannelSftp channel, ProgressMonitor monitor) throws SftpException, JSchException, IOException { + if (localFile.toFile().isDirectory()) { + channel.mkdir(localFile.getFileName().toString()); + if (monitor != null) { + monitor.info("New folder: " + localFile.getFileName().toString()); + } + for (File file : localFile.toFile().listFiles()) { + uploadFileOrFolder(Paths.get(file.toURI()), remoteDestination + getFilePathSeparator(remoteDestination) + localFile.getFileName(), channel, monitor); + } + } else { + if (monitor != null) { + monitor.info("Uploading: " + localFile.toString()); + } + channel.put(new FileInputStream(localFile.toFile()), localFile.getFileName().toString(), monitor != null ? new UploadProgressMonitor(monitor, (int) Files.size(localFile)) : null); + } + } + + public static void removeFileOrFolder(Path localFile, String remoteFile, ChannelSftp channel, ProgressMonitor monitor) throws JSchException, IOException, SftpException { + if (localFile.toFile().isDirectory()) { + execSSHCommand("rm -rf " + remoteFile.toString(), channel.getSession()); + } else { + channel.rm(localFile.getFileName().toString()); + } + } + + public static void removeFile(String remoteFolder, String fileName, ChannelSftp channel) throws SftpException { + channel.cd(remoteFolder); + channel.rm(fileName); + } + + public static boolean remoteFileAlreadyExists(String file, ChannelSftp channel) throws SftpException { + try { + SftpATTRS attrs = channel.stat(file); + return attrs != null; + } catch (SftpException e) { + return false; + } + } + + @SuppressWarnings("unchecked") + public static void downloadFolder(String remoteFolder, Path localDestination, ChannelSftp channel, ProgressMonitor monitor) throws SftpException { + Path localFolder = localDestination.resolve(new File(remoteFolder).getName()); + if (!localFolder.toFile().exists()) { + localFolder.toFile().mkdirs(); + } + Vector list = channel.ls(remoteFolder.toString()); + for (ChannelSftp.LsEntry file : list) { + if (!isCurrentOrParentDir(file)) { + if (file.getAttrs().isDir()) { + downloadFolder(remoteFolder + getFilePathSeparator(remoteFolder) + file.getFilename(), localFolder, channel, monitor); + } else { + downloadFile(remoteFolder + getFilePathSeparator(remoteFolder) + file.getFilename(), localFolder, channel, monitor); + } + } + + } + } + + public static class UploadProgressMonitor implements SftpProgressMonitor { + + private ProgressMonitor monitor; + private int total; + + public UploadProgressMonitor(ProgressMonitor monitor, int total) { + this.monitor = monitor; + this.total = total; + } + + @Override + public void init(int op, String src, String dest, long max) { + monitor.setTotal(total); + monitor.setCurrent(null, 0); + } + + @Override + public boolean count(long l) { + monitor.setCurrent(null, monitor.getCurrent() + (int) l); + return true; + } + + @Override + public void end() { + } + } + + public static class DownloadProgressMonitor implements SftpProgressMonitor { + + private ProgressMonitor monitor; + + public DownloadProgressMonitor(ProgressMonitor monitor) { + this.monitor = monitor; + } + + @Override + public void init(int op, String src, String dest, long max) { + monitor.setTotal((int) max); + monitor.setCurrent(null, 1); + monitor.infoN(src + " -> " + dest); + } + + @Override + public boolean count(long l) { + monitor.setCurrent(null, monitor.getCurrent() + (int) l); + return true; + } + + @Override + public void end() { + monitor.info(" DONE"); + } + } + + public static void downloadFile(String remoteFile, Path localDestination, ChannelSftp channel, ProgressMonitor monitor) throws SftpException { + channel.get(remoteFile, localDestination.toString(), new DownloadProgressMonitor(monitor)); + } + + public static void downloadFile(String remoteFile, Path localDestination, ChannelSftp channel) throws SftpException { + channel.get(remoteFile, localDestination.toString()); + } + + public static void exexRemoteScriptInLocalShell(String user, String host, String privateKeyPath, String scriptFile) throws IOException, InterruptedException { + String nameOS = System.getProperty("os.name"); + String command = null; + if (nameOS.startsWith("Windows")) { + String openTerminalcommand = "cmd /C start cmd.exe /K"; + String plinkPath = PLINK_URL.getFile().substring(1); + String sshCommand = "-ssh " + host + " -l " + user + " -i " + privateKeyPath + " -m"; + File scriptLauncher = createScriptLauncher(scriptFile); + String scriptLauncherPath = scriptLauncher.getAbsolutePath(); + command = openTerminalcommand + " " + plinkPath + " " + sshCommand + " " + scriptLauncherPath; + } else if (nameOS.startsWith("Linux")) { + Terminal terminal = getConsoleType(); + String openTerminalcommand = null; + switch (terminal) { + case GNOMETERMINAL: + openTerminalcommand = "gnome-terminal -x"; + break; + case KONSOLE: + openTerminalcommand = "konsole -e"; + break; + case XTERM: + openTerminalcommand = "xterm -x"; + break; + default: + break; + } + + String sshCommand = "ssh " + user + "@" + host + " -i " + privateKeyPath.toString() + " " + scriptFile; + command = openTerminalcommand + " " + sshCommand; + + } else { + System.out.println("OS NOT SUPPORTED!"); + } + Process p = Runtime.getRuntime().exec(command); + p.waitFor(); + } + + public static void execSSHCommand(String command, Session session) throws JSchException, IOException { + execSSHCommand(command, session, null); + } + + public static void execSSHCommand(String command, Session session, Map env) throws JSchException, IOException { + ChannelExec channel = (ChannelExec) session.openChannel("exec"); + channel.setCommand(addEnvToCommand(command, env)); + channel.setInputStream(null); + // InputStream stdout = channel.getInputStream(); + InputStream stderr = channel.getErrStream(); + + channel.connect(); + + waitForChannelClosed(channel); + + String ERR = IOUtils.toString(stderr); + // String OUT = IOUtils.toString(stdout); + + // System.out.println("SSHUtils.execSSHCommand() OUT: "+OUT); + + try { + if (channel.getExitStatus() > 0) { + throw new JSchException(ERR); + } + } finally { + channel.disconnect(); + } + } + + public static String addEnvToCommand(String command, Map env) { + StringBuilder sb = new StringBuilder(); + if (env != null) { + for (String key : env.keySet()) { + sb.append("export " + key + "=" + env.get(key)); + sb.append(" && "); + } + } + sb.append(command); + return sb.toString(); + } + + public static String addProfileLoaderToCommand(String command) { + StringBuilder sb = new StringBuilder(); + sb.append("[[ -e ~/.profile ]] && source ~/.profile; "); + sb.append("[[ -e ~/.bash_profile ]] && source ~/.bash_profile; "); + sb.append(command); + return sb.toString(); + } + + private static void waitForChannelClosed(ChannelExec channel) { + while (channel.getExitStatus() == -1 && !channel.isClosed()) { + try { + Thread.sleep(1000); + } catch (Exception e) { + } + } + } + + public static void makeExecutable(String filePath, Session session) { + try { + execSSHCommand("chmod +x " + filePath, session); + } catch (JSchException | IOException e) { + e.printStackTrace(); + } + } + + private static Terminal getConsoleType() throws IOException, InterruptedException { + Process p = Runtime.getRuntime().exec("which gnome-terminal"); + p.waitFor(); + if (p.exitValue() == 0) { + return Terminal.GNOMETERMINAL; + } + Process p1 = Runtime.getRuntime().exec("which konsole"); + p1.waitFor(); + if (p1.exitValue() == 0) { + return Terminal.KONSOLE; + } + return Terminal.XTERM; + } + + private static File createScriptLauncher(String string) throws IOException { + File file = File.createTempFile("xxx", null); + FileWriter fstream = new FileWriter(file); + BufferedWriter out = new BufferedWriter(fstream); + out.write(string); + out.close(); + return file; + } + + public static boolean testConnection(SshParameters sshParameters) { + return testConnection(sshParameters, null, false, false); + } + + public static boolean testConnection(SshParameters sshParameters, Path localDestination, boolean testUpload, boolean testDownload) { + logger.info("TEST SSH CONNECTION"); + try { + Session session = createSession(sshParameters); + + // TEST FTP CONNECTION + logger.info("TEST SFTP CONNECTION"); + ChannelSftp channel = SshUtils.createSFTPChannel(session); + + File tmpFile = File.createTempFile("xxx", null); + + String remoteDestination = sshParameters.getRemoteBaseDirParent(); + + // TEST UPLOAD FILE + if (testUpload) { + logger.info("TEST SFTP CONNECTION: UPLOAD"); + uploadFileOrFolder(Paths.get(tmpFile.toURI()), remoteDestination, channel, null); + execSSHCommand("rm " + remoteDestination + getFilePathSeparator(remoteDestination) + tmpFile.getName(), session); + } + + // TEST DOWNLOAD FILE + if (testDownload) { + logger.info("TEST SFTP CONNECTION: DOWNLOAD"); + downloadFile(remoteDestination + getFilePathSeparator(remoteDestination) + tmpFile.getName(), localDestination, channel); + new File(localDestination + File.separator + tmpFile.getName()).delete(); + } + + tmpFile.delete(); + channel.disconnect(); + session.disconnect(); + + logger.info("TEST SSH CONNECTION: SUCCESS"); + + return true; + } catch (Exception e) { + showErrorDialog(e); + logger.error("TEST SSH CONNECTION: ERROR {} PARAMETERS ARE {}", e.getMessage(), sshParameters); + return false; + } + } + + public static void showErrorDialog(Exception e) { + showError(decodeErrorMessage(e)); + } + + public static String decodeErrorMessage(Exception e) { + String message = ""; + if (e instanceof SftpException) { + message = "Remote path does not exists!"; + } else if (e instanceof JSchException) { + JSchException ex = ((JSchException) e); + if (ex.getCause() != null && ex.getCause() instanceof UnknownHostException) { + message = "Unknown host!"; + } else { + message = "Wrong username or password/key!"; + } + } else { + message = "Unknown exception: " + e.getMessage(); + + } + return message; + } + + private static void showError(final String message) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Connection failed!\n" + message, "SSH connection status", JOptionPane.ERROR_MESSAGE); + } + }); + } + + private static boolean isCurrentOrParentDir(LsEntry file) { + return file.getFilename().equals("..") || file.getFilename().equals("."); + } + + public static String getFilePathSeparator(String path) { + return path.indexOf("/") == -1 ? "\\" : "/"; + } + + private static class MyUserInfo implements UserInfo, UIKeyboardInteractive { + private String passphrase; + private JTextField passphraseField = null; + + public MyUserInfo() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + passphraseField = (JTextField) new JPasswordField(20); + } + }); + } + + public String getPassword() { + return null; + } + + public boolean promptYesNo(String str) { + return true; + } + + public String getPassphrase() { + return passphrase; + } + + public boolean promptPassphrase(String message) { + Object[] ob = { passphraseField }; + int result = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), ob, message, JOptionPane.OK_CANCEL_OPTION); + if (result == JOptionPane.OK_OPTION) { + passphrase = passphraseField.getText(); + return true; + } else { + return false; + } + } + + public boolean promptPassword(String message) { + return true; + } + + public void showMessage(String message) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), message, "SSH Info", JOptionPane.INFORMATION_MESSAGE); + } + + final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); + private Container panel; + + public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { + panel = new JPanel(); + panel.setLayout(new GridBagLayout()); + + gbc.weightx = 1.0; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.gridx = 0; + panel.add(new JLabel(instruction), gbc); + gbc.gridy++; + + gbc.gridwidth = GridBagConstraints.RELATIVE; + + JTextField[] texts = new JTextField[prompt.length]; + for (int i = 0; i < prompt.length; i++) { + gbc.fill = GridBagConstraints.NONE; + gbc.gridx = 0; + gbc.weightx = 1; + panel.add(new JLabel(prompt[i]), gbc); + + gbc.gridx = 1; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.weighty = 1; + if (echo[i]) { + texts[i] = new JTextField(20); + } else { + texts[i] = new JPasswordField(20); + } + panel.add(texts[i], gbc); + gbc.gridy++; + } + + if (JOptionPane.showConfirmDialog(panel, "SSH Info", destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { + String[] response = new String[prompt.length]; + for (int i = 0; i < prompt.length; i++) { + response[i] = texts[i].getText(); + } + return response; + } else { + return null; // cancel + } + } + } +} diff --git a/src/eu/engys/util/filechooser/AbstractFileChooser.java b/src/eu/engys/util/filechooser/AbstractFileChooser.java new file mode 100644 index 0000000..71cfa87 --- /dev/null +++ b/src/eu/engys/util/filechooser/AbstractFileChooser.java @@ -0,0 +1,174 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser; + +import java.awt.Dimension; +import java.awt.HeadlessException; +import java.awt.Window; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; + +import javax.swing.JDialog; + +import eu.engys.util.filechooser.gui.FileChooserPanel; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.UiUtil; + +public class AbstractFileChooser { + + public enum ReturnValue { + Approve, Cancelled; + + public boolean isApprove() { + return equals(Approve); + } + + public boolean isCancelled() { + return equals(Cancelled); + } + } + + protected FileChooserPanel panel; + private ReturnValue returnValue = ReturnValue.Cancelled; + protected String initialPath; + private JDialog dialog; + private SelectionMode selectionMode = SelectionMode.DIRS_AND_FILES; + private boolean multiSelectionEnabled; + private String title; + private Window parent; + private File fileToSelect; + + public AbstractFileChooser() { + this(null); + } + + public AbstractFileChooser(String initialPath) { + this.initialPath = initialPath; + } + + protected ReturnValue initializeAndShow(Dimension d) { + this.panel.layoutComponents(); + this.panel.setSelectionMode(selectionMode); + this.panel.setSelectedFile(ensureValidFileToSelect(fileToSelect)); + this.panel.setMultiSelectionEnabled(multiSelectionEnabled); + this.panel.initialize(ensureValidInitialPath(initialPath)); + return showDialog(d); + } + + protected String ensureValidInitialPath(String pathToCheck) { + return pathToCheck; + } + + protected File ensureValidFileToSelect(File fileToCheck) { + return fileToCheck; + } + + private ReturnValue showDialog(Dimension d) throws HeadlessException { + dialog = new JDialog(parent != null ? parent : UiUtil.getActiveWindow()); + dialog.setName("helyx.chooser.dialog"); + dialog.setTitle(title != null ? title : createTitle()); + dialog.getContentPane().add(panel); + dialog.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + returnValue = ReturnValue.Cancelled; + } + }); + dialog.setSize(d); + dialog.setLocationRelativeTo(null); + dialog.setModal(true); + dialog.setVisible(true); + dialog.getRootPane().setDefaultButton(panel.getOkButton()); + return returnValue; + } + + private String createTitle() { + switch (selectionMode) { + case DIRS_ONLY: + return "Select Folder"; + case FILES_ONLY: + return "Select File"; + case DIRS_AND_FILES: + return "Select File or Folder"; + default: + return "Select File or Folder"; + } + } + + public HelyxFileFilter getSelectedFileFilter(){ + return panel.getSelectedFilter(); + } + + public void setMultiSelectionEnabled(boolean multiSelectionEnabled) { + this.multiSelectionEnabled = multiSelectionEnabled; + } + + public void setSelectionMode(SelectionMode selectionMode) { + this.selectionMode = selectionMode; + } + + public void selectFile(File fileToSelect) { + this.fileToSelect = fileToSelect; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setReturnValue(ReturnValue returnValue) { + this.returnValue = returnValue; + } + + public void disposeDialog() { + if (dialog != null) {// FOR TESTS + dialog.setVisible(false); + dialog.dispose(); + } + } + + public void setParent(Window parent) { + this.parent = parent; + } + + /* + * For test purpose only + */ + public void setPanel(FileChooserPanel panel) { + this.panel = panel; + } + + public FileChooserPanel getPanel() { + return panel; + } + + private static final int WIDTH = 750; + private static final int HELIGHT = 500; + + protected Dimension getDimension(Dimension d) { + return d != null ? d : new Dimension(WIDTH, HELIGHT); + } +} diff --git a/src/eu/engys/util/filechooser/FileChooserEventListener.java b/src/eu/engys/util/filechooser/FileChooserEventListener.java new file mode 100644 index 0000000..ffc4165 --- /dev/null +++ b/src/eu/engys/util/filechooser/FileChooserEventListener.java @@ -0,0 +1,32 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser; + +public interface FileChooserEventListener { + + public void urlSelected(); + +} diff --git a/src/eu/engys/util/filechooser/HelyxFileChooser.java b/src/eu/engys/util/filechooser/HelyxFileChooser.java new file mode 100644 index 0000000..04a687e --- /dev/null +++ b/src/eu/engys/util/filechooser/HelyxFileChooser.java @@ -0,0 +1,163 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser; + +import java.awt.Dimension; +import java.io.File; + +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileObject; + +import eu.engys.util.filechooser.gui.Accessory; +import eu.engys.util.filechooser.gui.BrowserFactory; +import eu.engys.util.filechooser.gui.Options; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.filechooser.util.VFSUtils; + +public class HelyxFileChooser extends AbstractFileChooser { + + public HelyxFileChooser() { + super(); + } + + public HelyxFileChooser(String initialPath) { + super(initialPath); + } + + public ReturnValue showOpenDialog() { + this.panel = BrowserFactory.createOpenBrowser(this); + return initializeAndShow(getDimension(null)); + } + + public ReturnValue showOpenDialog(Dimension d) { + this.panel = BrowserFactory.createOpenBrowser(this); + return initializeAndShow(getDimension(d)); + } + + public ReturnValue showOpenDialog(HelyxFileFilter... filters) { + this.panel = BrowserFactory.createOpenBrowser(this, filters); + return initializeAndShow(getDimension(null)); + } + + public ReturnValue showOpenDialog(Accessory accessory) { + this.panel = BrowserFactory.createOpenBrowser(this, accessory); + return initializeAndShow(getDimension(null)); + } + + public ReturnValue showOpenDialog(Options options) { + this.panel = BrowserFactory.createOpenBrowser(this, options); + return initializeAndShow(getDimension(null)); + } + + public ReturnValue showOpenDialog(Accessory accessory, Dimension d, HelyxFileFilter... filters) { + this.panel = BrowserFactory.createOpenBrowser(this, accessory, filters); + return initializeAndShow(getDimension(d)); + } + + public ReturnValue showSaveAsDialog() { + this.panel = BrowserFactory.createSaveAsBrowser(this); + return initializeAndShow(getDimension(null)); + } + + public ReturnValue showSaveAsDialog(HelyxFileFilter... filters) { + this.panel = BrowserFactory.createSaveAsBrowser(this, filters); + return initializeAndShow(getDimension(null)); + } + + public File getSelectedFile() { + File[] files = getSelectedFiles(); + if (files != null && files.length > 0) { + return files[0]; + } + return null; + } + + public File[] getSelectedFiles() { + FileObject[] selectedFileObjects = panel.getFileObjects(); + if (selectedFileObjects == null) { + return null; + } else { + File[] selectedFiles = new File[selectedFileObjects.length]; + for (int i = 0; i < selectedFileObjects.length; i++) { + FileName name = selectedFileObjects[i].getName(); + selectedFiles[i] = new File(VFSUtils.decode(name.getURI(), null)); + } + return selectedFiles; + } + } + + @Override + protected String ensureValidInitialPath(String pathToCheck) { + if (pathToCheck == null || new File(pathToCheck).exists()) { + return pathToCheck; + } else { + File parentFile = new File(pathToCheck).getParentFile(); + if (parentFile == null) { + return null; + } else if (parentFile.exists()) { + return parentFile.getAbsolutePath(); + } else { + return ensureValidInitialPath(parentFile.getAbsolutePath()); + } + } + } + + @Override + protected File ensureValidFileToSelect(File fileToCheck) { + if (fileToCheck == null) + return null; + String path = ensureValidInitialPath(fileToCheck.getAbsolutePath()); + return path != null ? new File(path) : null; + } + + // public static void main(String[] args) { + // JFrame f = UiUtil.defaultTestFrame("a", new JButton(new AbstractAction("open") { + // @Override + // public void actionPerformed(ActionEvent e) { + // HelyxFileChooser fileChooser = new HelyxFileChooser("C:\\"); + // fileChooser.showOpenDialog(); + // } + // })); + // f.setSize(200, 200); + // f.setVisible(true); + // } +} diff --git a/src/eu/engys/util/filechooser/LinkFileObject.java b/src/eu/engys/util/filechooser/LinkFileObject.java new file mode 100644 index 0000000..0bb94d2 --- /dev/null +++ b/src/eu/engys/util/filechooser/LinkFileObject.java @@ -0,0 +1,60 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileType; + +import eu.engys.util.filechooser.util.FileObjectWrapper; + +public class LinkFileObject extends FileObjectWrapper { + + public LinkFileObject(FileObject parent) { + super(parent); + } + + @Override + public FileType getType() throws FileSystemException { + return FileType.IMAGINARY; + } +} diff --git a/src/eu/engys/util/filechooser/ParentFileObject.java b/src/eu/engys/util/filechooser/ParentFileObject.java new file mode 100644 index 0000000..f294759 --- /dev/null +++ b/src/eu/engys/util/filechooser/ParentFileObject.java @@ -0,0 +1,69 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser; + +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileObject; + +import eu.engys.util.filechooser.util.FileNameWrapper; +import eu.engys.util.filechooser.util.FileObjectWrapper; + +public class ParentFileObject extends FileObjectWrapper { + + public static final String PARENT_NAME = "[..]"; + private FileName fileName; + + public ParentFileObject(FileObject parent) { + super(parent); + fileName = new FileNameWrapper(parent.getName()) { + @Override + public String getBaseName() { + return PARENT_NAME; + } + }; + } + + @Override + public FileName getName() { + return fileName; + } +} diff --git a/src/eu/engys/util/filechooser/RemoteFileChooser.java b/src/eu/engys/util/filechooser/RemoteFileChooser.java new file mode 100644 index 0000000..68c70ab --- /dev/null +++ b/src/eu/engys/util/filechooser/RemoteFileChooser.java @@ -0,0 +1,111 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.connection.SshParameters; +import eu.engys.util.filechooser.gui.BrowserFactory; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.UiUtil; + +public class RemoteFileChooser extends AbstractFileChooser { + + private static final Logger LOGGER = LoggerFactory.getLogger(RemoteFileChooser.class); + + private SshParameters sshParameters; + + public RemoteFileChooser(SshParameters sshParameters) { + super(); + this.sshParameters = sshParameters; + } + + public RemoteFileChooser(SshParameters sshParameters, String initialPath) { + this.initialPath = encodePath(initialPath); + } + + public ReturnValue showOpenRemoteDialogConnectionTested(final ProgressMonitor progressMonitor) { + this.panel = BrowserFactory.createOpenRemoteBrowser(this, sshParameters); + return initializeAndShow(getDimension(null)); + } + + public ReturnValue showOpenRemoteDialog(final ProgressMonitor progressMonitor) { + Boolean retVal = UiUtil.testConnection(sshParameters, progressMonitor); + if (!retVal) { + return ReturnValue.Cancelled; + } + this.panel = BrowserFactory.createOpenRemoteBrowser(this, sshParameters); + return initializeAndShow(getDimension(null)); + } + + public FileObject getSelectedFileObject() { + FileObject[] files = getSelectedFileObjects(); + if (files != null && files.length > 0) { + return files[0]; + } + return null; + } + + public FileObject[] getSelectedFileObjects() { + return panel.getFileObjects(); + } + + private String encodePath(String filePath) { + try { + String encodePath = VFSUtils.encode(filePath, sshParameters); + FileObject fileObject = VFSUtils.resolveFileObject(encodePath, sshParameters); + if (fileObject != null) { + return fileObject.getName().getPath(); + } else { + return ""; + } + } catch (FileSystemException e1) { + LOGGER.error("Cannot resolve: " + filePath + ". " + e1.getMessage()); + return ""; + } + } + +} diff --git a/src/eu/engys/util/filechooser/actions/DeleteFileAction.java b/src/eu/engys/util/filechooser/actions/DeleteFileAction.java new file mode 100644 index 0000000..8f8d0ba --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/DeleteFileAction.java @@ -0,0 +1,82 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.actions; + +import java.awt.event.ActionEvent; +import java.io.File; + +import javax.swing.AbstractAction; +import javax.swing.Icon; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ResourcesUtil; + +public final class DeleteFileAction extends AbstractAction { + + private static final Logger logger = LoggerFactory.getLogger(DeleteFileAction.class); + private FileChooserController controller; + + public DeleteFileAction(FileChooserController controller) { + super("Delete"); + this.controller = controller; + putValue(SMALL_ICON, DELETE_FOLDER_ICON); + putValue(SHORT_DESCRIPTION, DELETE_FOLDER_TEXT); + setEnabled(!controller.isRemote()); + } + + @Override + public void actionPerformed(ActionEvent e) { + FileObject[] fileObjects = controller.getFileSystemPanel().getSelectedFileObjects(); + for (FileObject fo : fileObjects) { + File file = new File(VFSUtils.decode(fo.getName().getURI(), controller.getSshParameters())); + FileUtils.deleteQuietly(file); + } + refresh(controller.getUriPanel().getFileObject()); + } + + private void refresh(FileObject fileObject) { + try { + fileObject.refresh(); + controller.goToURL(fileObject); + } catch (FileSystemException e) { + logger.error("Can't refresh location", e.getMessage()); + } + } + + /** + * Resources + */ + private static final String DELETE_FOLDER_TEXT = ResourcesUtil.getString("delete.file.label"); + private static final Icon DELETE_FOLDER_ICON = ResourcesUtil.getIcon("delete.file.icon"); + +} diff --git a/src/eu/engys/util/filechooser/actions/ExtractArchiveAction.java b/src/eu/engys/util/filechooser/actions/ExtractArchiveAction.java new file mode 100644 index 0000000..0353943 --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/ExtractArchiveAction.java @@ -0,0 +1,122 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.actions; + +import java.awt.event.ActionEvent; +import java.io.File; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.ArchiveUtils; +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ResourcesUtil; + +public final class ExtractArchiveAction extends AbstractAction { + + private static final Logger logger = LoggerFactory.getLogger(ExtractArchiveAction.class); + private FileChooserController controller; + + public ExtractArchiveAction(FileChooserController controller) { + super("Extract"); + this.controller = controller; + putValue(SMALL_ICON, EXTRACT_ARCHIVE_ICON); + putValue(SHORT_DESCRIPTION, EXTRACT_ARCHIVE_TEXT); + setEnabled(!controller.isRemote()); + } + + @Override + public void actionPerformed(ActionEvent e) { + controller.showLoading(); + new Thread(new Runnable() { + + @Override + public void run() { + extractArchives(); + controller.showTable(); + } + }).start(); + + } + + private void extractArchives() { + FileObject[] fileObjects = controller.getFileSystemPanel().getSelectedFileObjects(); + for (FileObject fileObject : fileObjects) { + extractFileObject(fileObject); + } + } + + private void extractFileObject(FileObject archivedFileObject) { + try { + final File selectedFile = new File(VFSUtils.decode(archivedFileObject.getName().getURI(), controller.getSshParameters())); + if (ArchiveUtils.isArchive(selectedFile)) { + File parentFile = new File(VFSUtils.decode(archivedFileObject.getParent().getName().getURI(), controller.getSshParameters())); + ArchiveUtils.unarchive(selectedFile, parentFile); + + controller.resetFileFilter(); + refresh(archivedFileObject.getParent()); + + controller.getFileSystemPanel().selectFileByName(removeExtension(selectedFile.getAbsolutePath())); + } else { + JOptionPane.showMessageDialog(SwingUtilities.getRoot(controller.getFileSystemPanel()), "The selected file is not a known archive file", "Archive Error", JOptionPane.ERROR_MESSAGE); + } + + } catch (Exception e) { + logger.error("Can't extract file", e); + } + } + + public String removeExtension(String fileName) { + String noFirstExtension = FilenameUtils.getBaseName(fileName); + String noEventualSecondExtension = FilenameUtils.getBaseName(noFirstExtension); + return noEventualSecondExtension; + } + + private void refresh(FileObject fileObject) { + try { + fileObject.refresh(); + controller.goToURL(fileObject); + } catch (FileSystemException e) { + logger.error("Can't refresh location", e); + } + } + + /** + * Resources + */ + private static final String EXTRACT_ARCHIVE_TEXT = ResourcesUtil.getString("extract.archive.label"); + private static final Icon EXTRACT_ARCHIVE_ICON = ResourcesUtil.getIcon("extract.archive.icon"); + +} diff --git a/src/eu/engys/util/filechooser/actions/NewFolderAction.java b/src/eu/engys/util/filechooser/actions/NewFolderAction.java new file mode 100644 index 0000000..7adbfe5 --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/NewFolderAction.java @@ -0,0 +1,112 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.actions; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.io.File; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.textfields.PromptTextField; + +public final class NewFolderAction extends AbstractAction { + + private static final String FOLDER_ALREADY_EXISTS = "Folder already exists"; + private static final String EMPTY_NAME_MESSAGE = "Cannot create folder with emptyName!"; + private static final String NEW_FOLDER_NAME = "New Folder Name"; + private static final Logger logger = LoggerFactory.getLogger(NewFolderAction.class); + private FileChooserController controller; + + public NewFolderAction(FileChooserController controller) { + super("New"); + this.controller = controller; + putValue(SMALL_ICON, NEW_FOLDER_ICON); + putValue(SHORT_DESCRIPTION, NEW_FOLDER_TEXT); + setEnabled(!controller.isRemote()); + } + + @Override + public void actionPerformed(ActionEvent e) { + FileObject fileObject = controller.getUriPanel().getFileObject(); + String newFolderName = askNewFolderName(); + if (newFolderName == null) { + return; + } else if (newFolderName.isEmpty()) { + JOptionPane.showMessageDialog(SwingUtilities.getRoot(controller.getUriPanel()), EMPTY_NAME_MESSAGE, NEW_FOLDER_NAME, JOptionPane.ERROR_MESSAGE); + } else { + String parentFile = VFSUtils.decode(fileObject.getName().getURI(), controller.getSshParameters()); + File newFile = new File(parentFile, newFolderName); + if (newFile.exists()) { + JOptionPane.showMessageDialog(SwingUtilities.getRoot(controller.getUriPanel()), FOLDER_ALREADY_EXISTS, NEW_FOLDER_NAME, JOptionPane.ERROR_MESSAGE); + } else { + newFile.mkdirs(); + refresh(fileObject); + } + } + } + + private void refresh(FileObject fileObject) { + try { + fileObject.refresh(); + controller.goToURL(fileObject); + } catch (FileSystemException e) { + logger.error("Can't refresh location", e.getMessage()); + } + } + + private String askNewFolderName() { + final PromptTextField textFieldName = new PromptTextField(); + textFieldName.setName("newFolder.name"); + textFieldName.setPrompt("newFolder"); + + Object[] options = { "Create", "Cancel" }; + Component parent = SwingUtilities.getRoot(controller.getUriPanel()); + int response = JOptionPane.showOptionDialog(parent, textFieldName, NEW_FOLDER_NAME, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); + if (response == JOptionPane.YES_OPTION) { + return textFieldName.getText(); + } + return null; + } + + /** + * Resources + */ + private static final String NEW_FOLDER_TEXT = ResourcesUtil.getString("new.folder.label"); + private static final Icon NEW_FOLDER_ICON = ResourcesUtil.getIcon("new.folder.icon"); + +} diff --git a/src/eu/engys/util/filechooser/actions/favorite/AddFavorite.java b/src/eu/engys/util/filechooser/actions/favorite/AddFavorite.java new file mode 100644 index 0000000..17af0d1 --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/favorite/AddFavorite.java @@ -0,0 +1,91 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.actions.favorite; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; + +import eu.engys.util.filechooser.favorites.Favorite; +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ResourcesUtil; + +/** + */ +public class AddFavorite extends AbstractAction { + + private FileChooserController controller; + + public AddFavorite(FileChooserController controller) { + this.controller = controller; + putValue(NAME, NAV_ADDTOFAVORITES); + putValue(SHORT_DESCRIPTION, NAV_ADDTOFAVORITES); + putValue(SMALL_ICON, STAR_PLUS); + + } + + @Override + public void actionPerformed(ActionEvent e) { + FileObject currentLocation = controller.getUriPanel().getFileObject(); + if (currentLocation != null) { + try { + String url = currentLocation.getURL().toString(); + String name = VFSUtils.decode(url, controller.getSshParameters()); + Favorite favorite = new Favorite(name, url, Favorite.Type.USER); + controller.addFavorite(favorite); + } catch (FileSystemException e1) { + e1.printStackTrace(); + } + } + } + + /** + * Resources + */ + private static final String NAV_ADDTOFAVORITES = ResourcesUtil.getString("nav.AddToFavorites"); + private static final Icon STAR_PLUS = ResourcesUtil.getIcon("starPlus"); +} diff --git a/src/eu/engys/util/filechooser/actions/favorite/EditFavorite.java b/src/eu/engys/util/filechooser/actions/favorite/EditFavorite.java new file mode 100644 index 0000000..223b0d4 --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/favorite/EditFavorite.java @@ -0,0 +1,167 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.actions.favorite; + +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; + +import eu.engys.util.filechooser.favorites.Favorite; +import eu.engys.util.filechooser.favorites.list.MutableListModel; +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ResourcesUtil; + +/** + */ +public class EditFavorite extends AbstractAction { + + private JList favoriteList; + private MutableListModel listModel; + private FileChooserController controller; + + public EditFavorite(FileChooserController controller, JList favoriteList, MutableListModel listModel) { + super(EDITFAVORITES_ACTIONNAME, EDITSIGNATURE); + super.putValue(SHORT_DESCRIPTION, EDITFAVORITES_TOOLTIP); + this.controller = controller; + this.favoriteList = favoriteList; + this.listModel = listModel; + } + + @Override + public void actionPerformed(ActionEvent actionEvent) { + if (favoriteList.getSelectedValue() != null) { + Favorite favorite = favoriteList.getSelectedValue(); + JPanel panel = new JPanel(new GridLayout(4, 1)); + + JTextField nameField = new JTextField(favorite.getName()); + addNameListeners(nameField); + nameField.setName("favorite.name"); + panel.add(new JLabel(EDITFAVORITES_NAME)); + panel.add(nameField); + + JTextField urlField = new JTextField(decodedURL(favorite), 20); + urlField.setName("favorite.url"); + panel.add(new JLabel(EDITFAVORITES_URL)); + panel.add(urlField); + + int response = JOptionPane.showConfirmDialog(SwingUtilities.getRoot(favoriteList), panel, EDITFAVORITES_TITLE, JOptionPane.YES_NO_OPTION); + if (response == JOptionPane.YES_OPTION) { + favorite.setName(nameField.getText()); + favorite.setUrl(encodedURL(urlField)); + listModel.change(favoriteList.getSelectedIndex(), favorite); + } + } + } + + private String encodedURL(JTextField urlField) { + return VFSUtils.encode(urlField.getText(), controller.getSshParameters()); + } + + private String decodedURL(Favorite favorite) { + return VFSUtils.decode(favorite.getUrl(), controller.getSshParameters()); + } + + private void addNameListeners(final JTextField text) { + text.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent evt) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + text.selectAll(); + } + }); + } + + @Override + public void focusLost(FocusEvent e) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + text.select(0, 0); + } + }); + } + }); + text.addAncestorListener(new AncestorListener() { + + @Override + public void ancestorRemoved(AncestorEvent event) { + } + + @Override + public void ancestorMoved(AncestorEvent event) { + } + + @Override + public void ancestorAdded(AncestorEvent event) { + // doesn't work because the "yes" button grabs the focus + text.requestFocusInWindow(); + } + }); + text.setFocusable(true); + } + + /** + * Resources + */ + + private static final String EDITFAVORITES_ACTIONNAME = ResourcesUtil.getString("favorites.action"); + private static final String EDITFAVORITES_TOOLTIP = ResourcesUtil.getString("favorites.tooltip"); + private static final String EDITFAVORITES_NAME = ResourcesUtil.getString("favorites.name"); + private static final String EDITFAVORITES_URL = ResourcesUtil.getString("favorites.url"); + private static final String EDITFAVORITES_TITLE = ResourcesUtil.getString("favorites.title"); + + private static final Icon EDITSIGNATURE = ResourcesUtil.getIcon("favorites.edit"); +} diff --git a/src/eu/engys/util/filechooser/actions/favorite/OpenFavorite.java b/src/eu/engys/util/filechooser/actions/favorite/OpenFavorite.java new file mode 100644 index 0000000..6ba2812 --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/favorite/OpenFavorite.java @@ -0,0 +1,87 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.actions.favorite; + +import javax.swing.Icon; +import javax.swing.JList; + +import eu.engys.util.filechooser.actions.pathnavigation.BaseNavigateAction; +import eu.engys.util.filechooser.favorites.Favorite; +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.ui.ResourcesUtil; + +/** + */ +public class OpenFavorite extends BaseNavigateAction { + + private JList favoriteList; + + public OpenFavorite(FileChooserController controller, JList favoriteList) { + super(controller, "Open", FOLDEROPEN); + this.favoriteList = favoriteList; + } + + @Override + protected void performLongOperation(CheckBeforeActionResult checkBeforeActionResult) { + if (favoriteList.getSelectedValue() != null) { + Favorite favorite = favoriteList.getSelectedValue(); + controller.goToURL(favorite.getUrl(), true); + controller.updateOkButton(); + } + } + + @Override + protected boolean canGoUrl() { + return favoriteList.getSelectedValue() != null; + } + + @Override + protected boolean canExecuteDefaultAction() { + return true; + } + + /** + * Resources + */ + + private static final Icon FOLDEROPEN = ResourcesUtil.getIcon("folderOpen"); +} diff --git a/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateAction.java b/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateAction.java new file mode 100644 index 0000000..8c11956 --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateAction.java @@ -0,0 +1,175 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.actions.pathnavigation; + +import java.awt.Component; +import java.awt.KeyboardFocusManager; +import java.awt.event.ActionEvent; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JOptionPane; +import javax.swing.SwingWorker; + +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.ui.UiUtil; + +public abstract class BaseNavigateAction extends AbstractAction { + + private static final int SWITCH_TO_LOADING_TIME = 120; + + public FileChooserController controller; + private static Executor executor = Executors.newSingleThreadExecutor(); + private volatile SwingWorker showLoadingAfterDelayWorker; + private Component focusOwner; + + public BaseNavigateAction(FileChooserController controller) { + super(); + this.controller = controller; + } + + public BaseNavigateAction(FileChooserController controller, String name) { + this(controller); + putValue(NAME, name); + } + + public BaseNavigateAction(FileChooserController controller, String name, Icon icon) { + this(controller, name); + putValue(SMALL_ICON, icon); + } + + protected abstract void performLongOperation(CheckBeforeActionResult checkBeforeActionResult); + + @Override + public final void actionPerformed(ActionEvent e) { + final CheckBeforeActionResult checkBeforeActionResult = doInUiThreadBefore(); + if (CheckBeforeActionResult.CANT_GO.equals(checkBeforeActionResult)) { + return; + } + + SwingWorker worker = new SwingWorker() { + + @Override + protected void done() { + doInUiThreadAfter(); + } + + @Override + protected Void doInBackground() throws Exception { + try { + performLongOperation(checkBeforeActionResult); + } catch (Exception e) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), e.getMessage(), "File Chooser Error", JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + } + return null; + } + }; + executor.execute(worker); + + } + + protected final void doInUiThreadAfter() { + if (showLoadingAfterDelayWorker != null) { + showLoadingAfterDelayWorker.cancel(false); + } + updateGuiAfter(); + controller.showTable(); + if (focusOwner != null) { + focusOwner.requestFocus(); + } + } + + protected void updateGuiAfter() { + } + + protected final CheckBeforeActionResult doInUiThreadBefore() { + CheckBeforeActionResult result = CheckBeforeActionResult.CAN_GO; + if (!canGoUrl()) { + if (canExecuteDefaultAction()) { + result = CheckBeforeActionResult.CANT_GO_USE_DEFAULT_ACTION; + } else { + result = CheckBeforeActionResult.CANT_GO; + } + } else { + if (canExecuteDefaultAction()) { + result = CheckBeforeActionResult.CAN_GO_OR_USE_DEFAULT_ACTION; + } else { + result = CheckBeforeActionResult.CAN_GO; + } + } + + focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + showLoadingAfterDelayWorker = new SwingWorker() { + + @Override + protected void done() { + boolean cancelled = isCancelled(); + if (!cancelled) { + controller.showLoading(); + } + } + + @Override + protected Void doInBackground() throws Exception { + Thread.sleep(SWITCH_TO_LOADING_TIME); + return null; + } + }; + executor.execute(showLoadingAfterDelayWorker); + return result; + } + + protected abstract boolean canExecuteDefaultAction(); + + protected abstract boolean canGoUrl(); + + protected void updateGuiBefore() { + + } + + public enum CheckBeforeActionResult { + CAN_GO_OR_USE_DEFAULT_ACTION, CANT_GO, CANT_GO_USE_DEFAULT_ACTION, CAN_GO; + } +} diff --git a/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateActionGoUp.java b/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateActionGoUp.java new file mode 100644 index 0000000..20f22d7 --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateActionGoUp.java @@ -0,0 +1,82 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.actions.pathnavigation; + +import javax.swing.Icon; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ResourcesUtil; + +public final class BaseNavigateActionGoUp extends BaseNavigateAction { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseNavigateActionGoUp.class); + + public BaseNavigateActionGoUp(FileChooserController controller) { + super(controller); + putValue(SMALL_ICON, ARROWTURN90); + putValue(SHORT_DESCRIPTION, NAV_GOFOLDERUP); + } + + @Override + public void performLongOperation(CheckBeforeActionResult actionResult) { + LOGGER.debug("Executing going up"); + try { + FileObject parent = controller.getUriPanel().getFileObject().getParent(); + controller.goToURL(parent); + } catch (FileSystemException e) { + LOGGER.error("Error go UP", e); + } + } + + @Override + protected boolean canGoUrl() { + try { + FileObject parent = controller.getUriPanel().getFileObject().getParent(); + return parent != null && VFSUtils.canGoUrl(parent); + } catch (FileSystemException e) { + LOGGER.error("Can't get parent of current location", e); + } + return false; + } + + @Override + protected boolean canExecuteDefaultAction() { + return false; + } + + /** + * Resources + */ + + private static final String NAV_GOFOLDERUP = ResourcesUtil.getString("nav.goFolderUp"); + private static final Icon ARROWTURN90 = ResourcesUtil.getIcon("arrowTurn90"); +} diff --git a/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateActionOpen.java b/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateActionOpen.java new file mode 100644 index 0000000..77b1414 --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateActionOpen.java @@ -0,0 +1,89 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.actions.pathnavigation; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.filechooser.util.VFSUtils; + +public final class BaseNavigateActionOpen extends BaseNavigateAction { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseNavigateActionOpen.class); + private final FileChooserController controller; + + public BaseNavigateActionOpen(FileChooserController controller) { + super(controller); + this.controller = controller; + } + + @Override + public void performLongOperation(CheckBeforeActionResult checkBeforeActionResult) { + // When double click a file on the table + FileObject fileObject = controller.getSelectedFileObject(); + if (canExecuteDefaultAction()) { + controller.closeAndReturn(ReturnValue.Approve); + } else { + controller.goToURL(fileObject); + } + } + + @Override + protected boolean canGoUrl() { + FileObject fileObject = controller.getSelectedFileObject(); + if (fileObject != null) { + try { + return VFSUtils.canGoUrl(fileObject); + } catch (FileSystemException e) { + LOGGER.error("Can't open location", e.getMessage()); + } + } + return false; + } + + @Override + protected boolean canExecuteDefaultAction() { + SelectionMode selectionMode = controller.getSelectionMode(); + if (selectionMode.isFilesOnly() || selectionMode.isDirsAndFiles()) { + FileObject fileObject = controller.getSelectedFileObject(); + if (fileObject != null) { + try { + return FileType.FILE.equals(fileObject.getType()) || FileType.FILE_OR_FOLDER.equals(fileObject.getType()); + } catch (FileSystemException e) { + LOGGER.warn("Cant' get file type", e); + } + } + } + return false; + } + +} diff --git a/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateActionRefresh.java b/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateActionRefresh.java new file mode 100644 index 0000000..2843edb --- /dev/null +++ b/src/eu/engys/util/filechooser/actions/pathnavigation/BaseNavigateActionRefresh.java @@ -0,0 +1,76 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.actions.pathnavigation; + +import javax.swing.Icon; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.filechooser.gui.FileChooserController; +import eu.engys.util.ui.ResourcesUtil; + +public final class BaseNavigateActionRefresh extends BaseNavigateAction { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseNavigateActionRefresh.class); + + public BaseNavigateActionRefresh(FileChooserController controller) { + super(controller); + putValue(SMALL_ICON, ARROWCIRCLEDOUBLE); + putValue(SHORT_DESCRIPTION, NAV_REFRESHACTIONLABELTEXT); + } + + @Override + public void performLongOperation(CheckBeforeActionResult checkBeforeActionResult) { + try { + FileObject fileObject = controller.getUriPanel().getFileObject(); + fileObject.refresh(); + controller.goToURL(fileObject); + } catch (FileSystemException e) { + LOGGER.error("Can't refresh location", e.getMessage()); + } + } + + @Override + protected boolean canGoUrl() { + return true; + } + + @Override + protected boolean canExecuteDefaultAction() { + return false; + } + + /** + * Resources + */ + + private static final String NAV_REFRESHACTIONLABELTEXT = ResourcesUtil.getString("nav.refreshActionLabelText"); + private static final Icon ARROWCIRCLEDOUBLE = ResourcesUtil.getIcon("arrowCircleDouble"); + +} diff --git a/src/eu/engys/util/filechooser/authentication/AuthStore.java b/src/eu/engys/util/filechooser/authentication/AuthStore.java new file mode 100644 index 0000000..45b5d09 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/AuthStore.java @@ -0,0 +1,59 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +import java.util.Collection; + +public interface AuthStore { + public void add(UserAuthenticationInfo auInfo, UserAuthenticationDataWrapper authenticationData); + + public UserAuthenticationDataWrapper getUserAuthenticationData(UserAuthenticationInfo auInfo); + + public Collection getUserAuthenticationDatas(String protocol, String host); + + public void remove(UserAuthenticationInfo authenticationInfo); + + public Collection getAll(); + + public void clear(); + +} diff --git a/src/eu/engys/util/filechooser/authentication/AuthStoreUtils.java b/src/eu/engys/util/filechooser/authentication/AuthStoreUtils.java new file mode 100644 index 0000000..5dde411 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/AuthStoreUtils.java @@ -0,0 +1,306 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Collection; +import java.util.Map; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.vfs2.UserAuthenticationData; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.helpers.XMLReaderFactory; + +public class AuthStoreUtils { + + private static final java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger(AuthStoreUtils.class.getName()); + + public static final String USER = "user"; + public static final String HOST = "host"; + public static final String PROTOCOL = "protocol"; + public static final String ENTRY = "Entry"; + public static final String USER_AUTHENTICATION_DATA = "UserAuthenticationData"; + public static final String TYPE = "Type"; + public static final String DATA = "Data"; + public static final String ALGORITHM_BLOW_FISH = "Blowfish"; + public static final int SALT_LENGTH = 64; + private char[] password = null; + + private PasswordProvider passwordProvider; + + public AuthStoreUtils(PasswordProvider passwordProvider) { + this.passwordProvider = passwordProvider; + } + + public void save(AuthStore authStore, OutputStream out) throws IOException { + Collection all = authStore.getAll(); + for (UserAuthenticationInfo userAuthenticationInfo : all) { + UserAuthenticationData userAuthenticationData = authStore.getUserAuthenticationData(userAuthenticationInfo); + } + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = null; + try { + documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document document = documentBuilder.newDocument(); + Element root = document.createElement("root"); + + document.appendChild(root); + for (UserAuthenticationInfo userAuthenticationInfo : all) { + UserAuthenticationDataWrapper userAuthenticationData = authStore.getUserAuthenticationData(userAuthenticationInfo); + Element entry = document.createElement(ENTRY); + entry.setAttribute(PROTOCOL, userAuthenticationInfo.getProtocol()); + entry.setAttribute(HOST, userAuthenticationInfo.getHost()); + entry.setAttribute(USER, userAuthenticationInfo.getUser()); + Map addedTypes = userAuthenticationData.getAddedTypes(); + + for (UserAuthenticationData.Type type : addedTypes.keySet()) { + Element elementUserAuthenticationData = document.createElement(USER_AUTHENTICATION_DATA); + char[] data = userAuthenticationData.getData(type); + String value; + // if (UserAuthenticationData.PASSWORD.equals(type)) { + // if (password == null){ + // password = + // passwordProvider.getPassword("Enter password for password store"); + // } + // if (password == null || password.length==0){ + // throw new + // IOException("Password for password store not entered"); + // } + // value = saltAndEncrypt(data); + // } else { + // value = new String(data); + // } + value = new String(data); + Element elementType = document.createElement(TYPE); + elementType.setTextContent(type.toString()); + Element elementData = document.createElement(DATA); + elementData.setTextContent(value); + elementUserAuthenticationData.appendChild(elementType); + elementUserAuthenticationData.appendChild(elementData); + entry.appendChild(elementUserAuthenticationData); + } + root.appendChild(entry); + } + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(out); + transformer.transform(source, result); + } catch (Exception e) { + throw new IOException(e); + } + + } + + private String saltAndEncrypt(char[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { + String value; + Hex hex = new Hex(); + char[] saltedData = addSalt(data); + + byte[] encode = encrypt(saltedData, password); + value = new String(hex.encode(encode)); + return value; + } + + protected char[] addSalt(char[] data) { + char[] saltedData = new char[SALT_LENGTH + data.length]; + for (int i = 0; i < SALT_LENGTH; i++) { + saltedData[i] = 'a';// (char) random.nextInt(); + } + for (int i = 0; i < data.length; i++) { + saltedData[i + SALT_LENGTH] = data[i]; + } + return saltedData; + } + + protected char[] removeSalt(char[] data) { + char[] deSalted = new char[data.length - SALT_LENGTH]; + System.arraycopy(data, SALT_LENGTH, deSalted, 0, deSalted.length); + return deSalted; + } + + public void load(AuthStore authStore, InputStream in) throws IOException { + try { + XMLReader xmlReader = XMLReaderFactory.createXMLReader(); + xmlReader.setContentHandler(new AuthStoreHandler(authStore)); + xmlReader.parse(new InputSource(in)); + } catch (SAXException e) { + throw new IOException(e); + } + } + + private class AuthStoreHandler extends DefaultHandler { + + private UserAuthenticationDataWrapper userAuthenticationData; + private UserAuthenticationInfo info; + private StringBuilder sb = new StringBuilder(); + private String data; + private String type; + + private AuthStore authStore; + + private AuthStoreHandler(AuthStore authStore) { + this.authStore = authStore; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { + + if (ENTRY.equals(localName)) { + userAuthenticationData = new UserAuthenticationDataWrapper(); + info = new UserAuthenticationInfo(atts.getValue(PROTOCOL), atts.getValue(HOST), atts.getValue(USER)); + + } + sb.setLength(0); + + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + if (ENTRY.equals(localName)) { + authStore.add(info, userAuthenticationData); + } else if (USER_AUTHENTICATION_DATA.equals(localName)) { + // if (UserAuthenticationData.PASSWORD.equals(new + // UserAuthenticationData.Type(type))) { + // if (password == null){ + // password = + // passwordProvider.getPassword("Enter password for password store"); + // } + // if (password == null || password.length==0){ + // throw new + // SAXException("Password for password store not entered"); + // } + // Hex hex = new Hex(); + // try { + // byte[] decode = (byte[]) hex.decode(data.trim()); + // byte[] decrypted = decrypt(decode, password); + // char[] passwordWithSalt = bytesToChars(decrypted); + // char[] password = removeSalt(passwordWithSalt); + // data = new String(password); + // } catch (Exception e) { + // password=null; + // throw new SAXException("Can't decrypt password", e); + // } + // } + userAuthenticationData.setData(new UserAuthenticationData.Type(type), data.toCharArray()); + } else if (DATA.equals(localName)) { + data = sb.toString(); + } else if (TYPE.equals(localName)) { + type = sb.toString(); + } + + sb.setLength(0); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + sb.append(ch, start, length); + } + } + + protected byte[] encrypt(char[] bytes, char[] password) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { + byte[] passBytes = charsToBytes(password); + SecretKeySpec secretKeySpec = new SecretKeySpec(passBytes, ALGORITHM_BLOW_FISH); + + Cipher cipher = Cipher.getInstance(ALGORITHM_BLOW_FISH); + + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); + byte[] encrypted = cipher.doFinal(new String(bytes).getBytes("UTF-8")); + return encrypted; + } + + protected byte[] decrypt(byte[] bytes, char[] password) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { + byte[] passBytes = charsToBytes(password); + SecretKeySpec secretKeySpec = new SecretKeySpec(passBytes, ALGORITHM_BLOW_FISH); + Cipher cipher = Cipher.getInstance(ALGORITHM_BLOW_FISH); + cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); + byte[] decrypted = cipher.doFinal(bytes); + return decrypted; + } + + protected byte[] charsToBytes(char[] chars) throws UnsupportedEncodingException { + return new String(chars).getBytes("UTF-8"); + } + + protected char[] bytesToChars(byte[] bytes) { + return new String(bytes, Charset.forName("UTF-8")).toCharArray(); + } + + public PasswordProvider getPasswordProvider() { + return passwordProvider; + } + + public void setPasswordProvider(PasswordProvider passwordProvider) { + this.passwordProvider = passwordProvider; + } + +} diff --git a/src/eu/engys/util/filechooser/authentication/AuthorisationCancelledException.java b/src/eu/engys/util/filechooser/authentication/AuthorisationCancelledException.java new file mode 100644 index 0000000..34e022d --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/AuthorisationCancelledException.java @@ -0,0 +1,59 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +public class AuthorisationCancelledException extends RuntimeException { + + public AuthorisationCancelledException() { + super(); + } + + public AuthorisationCancelledException(String message) { + super(message); + } + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/src/eu/engys/util/filechooser/authentication/CompositeAuthStore.java b/src/eu/engys/util/filechooser/authentication/CompositeAuthStore.java new file mode 100644 index 0000000..1db3e11 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/CompositeAuthStore.java @@ -0,0 +1,110 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +public class CompositeAuthStore implements AuthStore { + + public AuthStore[] authStores; + + public CompositeAuthStore(AuthStore... authStores) { + super(); + this.authStores = authStores; + } + + @Override + public void add(UserAuthenticationInfo auInfo, UserAuthenticationDataWrapper authenticationData) { + for (AuthStore authStore : authStores) { + authStore.add(auInfo, authenticationData); + } + + } + + @Override + public UserAuthenticationDataWrapper getUserAuthenticationData(UserAuthenticationInfo auInfo) { + for (AuthStore authStore : authStores) { + UserAuthenticationDataWrapper userAuthenticationData = authStore.getUserAuthenticationData(auInfo); + if (userAuthenticationData != null) { + return userAuthenticationData; + } + } + return null; + } + + @Override + public Collection getUserAuthenticationDatas(String protocol, String host) { + HashSet set = new HashSet(); + for (AuthStore authStore : authStores) { + set.addAll(authStore.getUserAuthenticationDatas(protocol, host)); + } + return set; + } + + @Override + public void remove(UserAuthenticationInfo authenticationInfo) { + for (AuthStore authStore : authStores) { + authStore.remove(authenticationInfo); + } + + } + + @Override + public Collection getAll() { + List l = new ArrayList(); + for (AuthStore authStore : authStores) { + l.addAll(authStore.getAll()); + } + return l; + } + + @Override + public void clear() { + for (AuthStore authStore : authStores) { + authStore.clear(); + } + } + +} diff --git a/src/eu/engys/util/filechooser/authentication/DialogPasswordProvider.java b/src/eu/engys/util/filechooser/authentication/DialogPasswordProvider.java new file mode 100644 index 0000000..44909a6 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/DialogPasswordProvider.java @@ -0,0 +1,67 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +import java.awt.GridLayout; + +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPasswordField; + +import eu.engys.util.ui.UiUtil; + +public class DialogPasswordProvider implements PasswordProvider { + @Override + public char[] getPassword(String message) { + JPanel jPanel = new JPanel(new GridLayout(2, 1)); + jPanel.add(new JLabel(message)); + JPasswordField comp = new JPasswordField(20); + jPanel.add(comp); + int i = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), jPanel, "Podaj haslo", JOptionPane.YES_NO_OPTION); + if (i == JOptionPane.OK_OPTION) { + return comp.getPassword(); + } + return null; + } + +} diff --git a/src/eu/engys/util/filechooser/authentication/MemoryAuthStore.java b/src/eu/engys/util/filechooser/authentication/MemoryAuthStore.java new file mode 100644 index 0000000..2410c95 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/MemoryAuthStore.java @@ -0,0 +1,101 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MemoryAuthStore implements AuthStore { + + private static final Logger LOGGER = LoggerFactory.getLogger(MemoryAuthStore.class); + + private Map map; + + public MemoryAuthStore() { + map = new HashMap(); + } + + @Override + public UserAuthenticationDataWrapper getUserAuthenticationData(UserAuthenticationInfo info) { + return map.get(info); + } + + @Override + public Collection getUserAuthenticationDatas(String protocol, String host) { + List list = new ArrayList(); + for (UserAuthenticationInfo key : map.keySet()) { + if (StringUtils.equalsIgnoreCase(key.getProtocol(), protocol) && StringUtils.equalsIgnoreCase(key.getHost(), host)) { + list.add(map.get(key)); + } + } + return list; + } + + @Override + public void add(UserAuthenticationInfo aInfo, UserAuthenticationDataWrapper authenticationData) { + LOGGER.debug("Adding auth info {}://{}@{}", new Object[] { aInfo.getProtocol(), aInfo.getUser(), aInfo.getHost() }); + map.put(aInfo, authenticationData); + } + + @Override + public void remove(UserAuthenticationInfo authenticationInfo) { + map.remove(authenticationInfo); + } + + @Override + public Collection getAll() { + return new ArrayList(map.keySet()); + } + + @Override + public void clear() { + map.clear(); + } + +} diff --git a/src/eu/engys/util/filechooser/authentication/PasswordProvider.java b/src/eu/engys/util/filechooser/authentication/PasswordProvider.java new file mode 100644 index 0000000..0abae91 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/PasswordProvider.java @@ -0,0 +1,47 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +public interface PasswordProvider { + + public char[] getPassword(String message); +} diff --git a/src/eu/engys/util/filechooser/authentication/StaticPasswordProvider.java b/src/eu/engys/util/filechooser/authentication/StaticPasswordProvider.java new file mode 100644 index 0000000..f856d75 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/StaticPasswordProvider.java @@ -0,0 +1,56 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +public class StaticPasswordProvider implements PasswordProvider { + + private char[] password; + + public StaticPasswordProvider(char[] password) { + this.password = password; + } + + @Override + public char[] getPassword(String message) { + return password; + } +} diff --git a/src/eu/engys/util/filechooser/authentication/UserAuthenticationDataWrapper.java b/src/eu/engys/util/filechooser/authentication/UserAuthenticationDataWrapper.java new file mode 100644 index 0000000..e3add8b --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/UserAuthenticationDataWrapper.java @@ -0,0 +1,102 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.vfs2.UserAuthenticationData; + +public class UserAuthenticationDataWrapper extends UserAuthenticationData { + + /** + * The password. + */ + public static final Type SSH_KEY = new Type("sshKey"); + + private HashMap map; + + public UserAuthenticationDataWrapper() { + super(); + map = new HashMap(); + } + + @Override + public void setData(Type type, char[] data) { + super.setData(type, data.clone()); + map.put(type, data); + } + + public Map getAddedTypes() { + return map; + } + + public UserAuthenticationDataWrapper copy() { + UserAuthenticationDataWrapper cp = new UserAuthenticationDataWrapper(); + for (Type type : map.keySet()) { + cp.setData(type, map.get(type)); + } + return cp; + } + + @Override + public void cleanup() { + } + + public void cleanWrapper() { + super.cleanup(); + for (char[] chars : map.values()) { + for (int i = 0; i < chars.length; i++) { + chars[i] = '0'; + } + } + } + + public void remove(Type type) { + super.cleanup(); + map.remove(type); + for (Type type1 : map.keySet()) { + super.setData(type1, map.get(type1)); + } + } + +} diff --git a/src/eu/engys/util/filechooser/authentication/UserAuthenticationInfo.java b/src/eu/engys/util/filechooser/authentication/UserAuthenticationInfo.java new file mode 100644 index 0000000..aa6607a --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/UserAuthenticationInfo.java @@ -0,0 +1,109 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +public class UserAuthenticationInfo { + public final String protocol; + public final String host; + public final String user; + + public UserAuthenticationInfo(String protocol, String host, String user) { + this.protocol = protocol; + this.host = host; + this.user = user; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((host == null) ? 0 : host.hashCode()); + result = prime * result + ((protocol == null) ? 0 : protocol.hashCode()); + result = prime * result + ((user == null) ? 0 : user.hashCode()); + return result; + } + + public String getProtocol() { + return protocol; + } + + public String getHost() { + return host; + } + + public String getUser() { + return user; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + UserAuthenticationInfo other = (UserAuthenticationInfo) obj; + if (host == null) { + if (other.host != null) + return false; + } else if (!host.equals(other.host)) + return false; + if (protocol == null) { + if (other.protocol != null) + return false; + } else if (!protocol.equals(other.protocol)) + return false; + if (user == null) { + if (other.user != null) + return false; + } else if (!user.equals(other.user)) + return false; + return true; + } + + @Override + public String toString() { + return "UserAuthenticationInfo [ user: " +user + " - host: " + host + " - protocol: " + protocol + " ]" ; + } + +} diff --git a/src/eu/engys/util/filechooser/authentication/UserAuthenticatorFactory.java b/src/eu/engys/util/filechooser/authentication/UserAuthenticatorFactory.java new file mode 100644 index 0000000..5133a72 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/UserAuthenticatorFactory.java @@ -0,0 +1,66 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication; + +import org.apache.commons.vfs2.FileSystemOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.filechooser.authentication.authenticator.AbstractUiUserAuthenticator; +import eu.engys.util.filechooser.authentication.authenticator.OtrosUserAuthenticator; +import eu.engys.util.filechooser.authentication.authenticator.UseCentralsFromSessionUserAuthenticator; + +public class UserAuthenticatorFactory { + private static final Logger LOGGER = LoggerFactory.getLogger(UserAuthenticatorFactory.class); + + public OtrosUserAuthenticator getUiUserAuthenticator(AuthStore sessionAuthStore, String url, FileSystemOptions fileSystemOptions) { + LOGGER.info("Getting authenticator for {}", url); + AbstractUiUserAuthenticator authenticator = null; +// if (url.startsWith("sftp://")) { +// authenticator = new SftpUserAuthenticator(url, fileSystemOptions); +// } + UseCentralsFromSessionUserAuthenticator fromSessionUserAuthenticator = new UseCentralsFromSessionUserAuthenticator(sessionAuthStore, url, fileSystemOptions, authenticator); + return fromSessionUserAuthenticator; + + } + +} diff --git a/src/eu/engys/util/filechooser/authentication/authenticator/AbstractUiUserAuthenticator.java b/src/eu/engys/util/filechooser/authentication/authenticator/AbstractUiUserAuthenticator.java new file mode 100644 index 0000000..be68ba6 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/authenticator/AbstractUiUserAuthenticator.java @@ -0,0 +1,131 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication.authenticator; + +import java.awt.BorderLayout; +import java.text.MessageFormat; + +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import org.apache.commons.vfs2.FileSystemOptions; +import org.apache.commons.vfs2.UserAuthenticationData; +import org.apache.commons.vfs2.UserAuthenticationData.Type; + +import eu.engys.util.filechooser.authentication.UserAuthenticationDataWrapper; +import eu.engys.util.filechooser.uri.VFSURIParser; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; + +public abstract class AbstractUiUserAuthenticator implements OtrosUserAuthenticator { + + private String url; + private VFSURIParser vfsUriParser; + private final FileSystemOptions fileSystemOptions; + protected UserAuthenticationDataWrapper data; + private final String title; + + public AbstractUiUserAuthenticator(String url, FileSystemOptions fileSystemOptions) { + this.url = url; + this.title = MessageFormat.format(AUTHENTICATOR_ENTERCREDENTIALSFORURL, url); + this.fileSystemOptions = fileSystemOptions; + this.vfsUriParser = new VFSURIParser(url); + } + + @Override + public UserAuthenticationData requestAuthentication(Type[] types) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + JPanel authOptionPanel = getOptionsPanelBuilder().getPanel(); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(authOptionPanel); + + String[] options = { "OK", "Cancel" }; + int showConfirmDialog = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), panel, title, JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]); + if (showConfirmDialog != JOptionPane.OK_OPTION) { + return; + } + data = new UserAuthenticationDataWrapper(); + updateAuthenticationData(data); + } + }); + return data; + } + + @Override + public UserAuthenticationDataWrapper getLastUserAuthenticationData() { + return data; + } + + // @Override + // public boolean isPasswordSave() { + // return saveCredentialsCheckBox.isSelected(); + // } + + protected abstract void updateAuthenticationData(UserAuthenticationData authenticationData); + + protected abstract PanelBuilder getOptionsPanelBuilder(); + + protected String getUrl() { + return url; + } + + protected VFSURIParser getVfsUriParser() { + return vfsUriParser; + } + + protected FileSystemOptions getFileSystemOptions() { + return fileSystemOptions; + } + + /** + * Resources + */ + + private static final String AUTHENTICATOR_SAVEPASSWORD = ResourcesUtil.getString("authenticator.savePassword"); + private static final String AUTHENTICATOR_ENTERCREDENTIALSFORURL = ResourcesUtil.getString("authenticator.enterCredentialsForUrl"); + +} diff --git a/src/eu/engys/util/filechooser/authentication/authenticator/OtrosStaticUserAuthenticator.java b/src/eu/engys/util/filechooser/authentication/authenticator/OtrosStaticUserAuthenticator.java new file mode 100644 index 0000000..75ba395 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/authenticator/OtrosStaticUserAuthenticator.java @@ -0,0 +1,83 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication.authenticator; + +import org.apache.commons.vfs2.UserAuthenticationData; +import org.apache.commons.vfs2.UserAuthenticationData.Type; +import org.slf4j.Logger; + +import eu.engys.util.filechooser.authentication.UserAuthenticationDataWrapper; + +public class OtrosStaticUserAuthenticator implements OtrosUserAuthenticator { + + private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(OtrosStaticUserAuthenticator.class); + + private final UserAuthenticationDataWrapper userAuthenticationDataWrapper; + private final UserAuthenticationData userAuthenticationData; + + public OtrosStaticUserAuthenticator(UserAuthenticationData userAuthenticationData) { + this.userAuthenticationData = userAuthenticationData; + userAuthenticationDataWrapper = new UserAuthenticationDataWrapper(); + } + + @Override + public UserAuthenticationData requestAuthentication(Type[] arg0) { + LOGGER.info("Received request for authentication"); + UserAuthenticationDataWrapper data = new UserAuthenticationDataWrapper(); + for (Type type : arg0) { + data.setData(type, userAuthenticationData.getData(type)); + userAuthenticationDataWrapper.setData(type, userAuthenticationData.getData(type)); + } + return data; + } + + @Override + public UserAuthenticationDataWrapper getLastUserAuthenticationData() { + return userAuthenticationDataWrapper; + } +// +// @Override +// public boolean isPasswordSave() { +// return false; +// } + +} diff --git a/src/eu/engys/util/filechooser/authentication/authenticator/OtrosUserAuthenticator.java b/src/eu/engys/util/filechooser/authentication/authenticator/OtrosUserAuthenticator.java new file mode 100644 index 0000000..ebf26ec --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/authenticator/OtrosUserAuthenticator.java @@ -0,0 +1,53 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.authentication.authenticator; + +import org.apache.commons.vfs2.UserAuthenticator; + +import eu.engys.util.filechooser.authentication.UserAuthenticationDataWrapper; + +public interface OtrosUserAuthenticator extends UserAuthenticator { + public UserAuthenticationDataWrapper getLastUserAuthenticationData(); + +// public boolean isPasswordSave(); + +} diff --git a/src/eu/engys/util/filechooser/authentication/authenticator/UseCentralsFromSessionUserAuthenticator.java b/src/eu/engys/util/filechooser/authentication/authenticator/UseCentralsFromSessionUserAuthenticator.java new file mode 100644 index 0000000..7789ec5 --- /dev/null +++ b/src/eu/engys/util/filechooser/authentication/authenticator/UseCentralsFromSessionUserAuthenticator.java @@ -0,0 +1,101 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright (c) 2012. Krzysztof Otrebski + * All right reserved + */ + +package eu.engys.util.filechooser.authentication.authenticator; + +import java.util.Collection; + +import org.apache.commons.vfs2.FileSystemOptions; +import org.apache.commons.vfs2.UserAuthenticationData; +import org.slf4j.Logger; + +import eu.engys.util.filechooser.authentication.AuthStore; +import eu.engys.util.filechooser.authentication.UserAuthenticationDataWrapper; +import eu.engys.util.filechooser.uri.VFSURIParser; +import eu.engys.util.ui.builder.PanelBuilder; + +public class UseCentralsFromSessionUserAuthenticator extends AbstractUiUserAuthenticator { + + private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(UseCentralsFromSessionUserAuthenticator.class); + + private final AuthStore sessionAuthStore; + private final AbstractUiUserAuthenticator otrosUserAuthenticator; + + public UseCentralsFromSessionUserAuthenticator(AuthStore sessionAuthStore, String url, FileSystemOptions fileSystemOptions, AbstractUiUserAuthenticator otrosUserAuthenticator) { + super(url, fileSystemOptions); + this.sessionAuthStore = sessionAuthStore; + this.otrosUserAuthenticator = otrosUserAuthenticator; + } + + @Override + public UserAuthenticationDataWrapper getLastUserAuthenticationData() { + if (otrosUserAuthenticator != null) { + return otrosUserAuthenticator.getLastUserAuthenticationData(); + } + return null; + + } + + @Override + protected void updateAuthenticationData(UserAuthenticationData authenticationData) { + otrosUserAuthenticator.updateAuthenticationData(authenticationData); + } + + @Override + protected PanelBuilder getOptionsPanelBuilder() { + return otrosUserAuthenticator.getOptionsPanelBuilder(); + } + + @Override + public UserAuthenticationData requestAuthentication(UserAuthenticationData.Type[] types) { + UserAuthenticationData userAuthenticationData = getStaticWorkingUserAuthForSmb(sessionAuthStore, getUrl()); + if (userAuthenticationData == null) { + userAuthenticationData = otrosUserAuthenticator.requestAuthentication(types); + } + return userAuthenticationData; + } + + protected UserAuthenticationData getStaticWorkingUserAuthForSmb(AuthStore authStore, String url) { + LOGGER.debug("Checking if have credentials for {}", url); + VFSURIParser parser = new VFSURIParser(url); + if (parser.getHostname() != null) { + Collection userAuthenticationDatas = authStore.getUserAuthenticationDatas(parser.getProtocol().toString(), parser.getHostname()); + LOGGER.debug("Credentials count: {}", userAuthenticationDatas.size()); + if (userAuthenticationDatas.size() > 0) { + UserAuthenticationData authenticationDataFromStore = userAuthenticationDatas.iterator().next(); + LOGGER.debug("Returning static authenticator for {}", url); + return authenticationDataFromStore; + } + } + LOGGER.debug("Do not have credentials for {}", url); + return null; + } + +} diff --git a/src/eu/engys/util/filechooser/depot/FTPUserAuthenticator.java b/src/eu/engys/util/filechooser/depot/FTPUserAuthenticator.java new file mode 100644 index 0000000..0b0ab6b --- /dev/null +++ b/src/eu/engys/util/filechooser/depot/FTPUserAuthenticator.java @@ -0,0 +1,169 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.depot; +///* +// * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package eu.engys.util.otrosfilechooser.authentication.authenticator; +// +//import java.awt.event.ActionEvent; +//import java.awt.event.ActionListener; +//import java.util.Collection; +// +//import javax.swing.JComboBox; +//import javax.swing.JPasswordField; +//import javax.swing.event.AncestorEvent; +//import javax.swing.event.AncestorListener; +// +//import org.apache.commons.lang.StringUtils; +//import org.apache.commons.vfs2.FileSystemOptions; +//import org.apache.commons.vfs2.UserAuthenticationData; +// +//import eu.engys.util.otrosfilechooser.authentication.AuthStore; +//import eu.engys.util.otrosfilechooser.authentication.UserAuthenticationDataWrapper; +//import eu.engys.util.otrosfilechooser.authentication.UserAuthenticationInfo; +//import eu.engys.util.ui.ResourcesUtil; +//import eu.engys.util.ui.builder.PanelBuilder; +// +//public class FTPUserAuthenticator extends AbstractUiUserAuthenticator { +// +// protected JComboBox nameTextField; +// protected JPasswordField passTextField; +// +// public FTPUserAuthenticator(String url, FileSystemOptions fileSystemOptions) { +// super(url, fileSystemOptions); +// } +// +// @Override +// protected void updateAuthenticationData(UserAuthenticationData authenticationData) { +// authenticationData.setData(UserAuthenticationData.USERNAME, nameTextField.getSelectedItem().toString().toCharArray()); +// authenticationData.setData(UserAuthenticationData.PASSWORD, passTextField.getPassword()); +// +// } +// +// @SuppressWarnings({ "rawtypes", "unchecked" }) +// @Override +// protected PanelBuilder getOptionsPanelBuilder() { +// +// Collection userAuthenticationDatas = getAuthStore().getUserAuthenticationDatas(getVfsUriParser().getProtocol().getName(), getVfsUriParser().getHostname()); +// String[] names = new String[userAuthenticationDatas.size()]; +// int i = 0; +// for (UserAuthenticationData userAuthenticationData : userAuthenticationDatas) { +// names[i] = new String(userAuthenticationData.getData(UserAuthenticationData.USERNAME)); +// i++; +// } +// +// nameTextField = new JComboBox(names); +// nameTextField.setEditable(true); +// nameTextField.addActionListener(new ActionListener() { +// +// @Override +// public void actionPerformed(ActionEvent e) { +// userSelected(nameTextField.getSelectedItem().toString()); +// } +// }); +// +// nameTextField.addAncestorListener(new AncestorListener() { +// +// @Override +// public void ancestorRemoved(AncestorEvent event) { +// +// } +// +// @Override +// public void ancestorMoved(AncestorEvent event) { +// +// } +// +// @Override +// public void ancestorAdded(AncestorEvent event) { +// event.getComponent().requestFocusInWindow(); +// } +// }); +// +// passTextField = new JPasswordField(15); +// passTextField.setText(getVfsUriParser().getPassword()); +// +// if (StringUtils.isNotBlank(getVfsUriParser().getUsername())) { +// nameTextField.setSelectedItem(getVfsUriParser().getUsername()); +// } +// if (names.length > 0) { +// nameTextField.setSelectedIndex(0); +// } +// +// PanelBuilder pb = new PanelBuilder(); +// pb.addComponent(AUTHENTICATOR_USERNAME, nameTextField); +// pb.addComponent(AUTHENTICATOR_PASSWORD, passTextField); +// +// return pb; +// } +// +// private void userSelected(String user) { +// UserAuthenticationData userAuthenticationData = getAuthStore().getUserAuthenticationData(new UserAuthenticationInfo(getVfsUriParser().getProtocol().getName(), getVfsUriParser().getHostname(), user)); +// char[] passChars = new char[0]; +// +// if (userAuthenticationData != null && userAuthenticationData.getData(UserAuthenticationData.PASSWORD) != null) { +// passChars = userAuthenticationData.getData(UserAuthenticationData.PASSWORD); +// } +// passTextField.setText(new String(passChars)); +// +// userSelectedHook(userAuthenticationData); +// } +// +// protected void userSelectedHook(UserAuthenticationData userAuthenticationData) { +// +// } +// +// /** +// * Override this method to be notified when user from authstore is selected +// * +// * @param authenticationData +// */ +// protected void updateUserAuthenticationData(UserAuthenticationData authenticationData) { +// +// } +// +// /** +// * Resources +// */ +// +// private static final String AUTHENTICATOR_USERNAME = ResourcesUtil.getString("authenticator.username"); +// private static final String AUTHENTICATOR_PASSWORD = ResourcesUtil.getString("authenticator.password"); +// +//} diff --git a/src/eu/engys/util/filechooser/depot/OriginalVfsBrowser.java b/src/eu/engys/util/filechooser/depot/OriginalVfsBrowser.java new file mode 100644 index 0000000..1dbaeb0 --- /dev/null +++ b/src/eu/engys/util/filechooser/depot/OriginalVfsBrowser.java @@ -0,0 +1,519 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.depot; +///* +// * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package eu.engys.util.otrosfilechooser.panels; +// +//import java.awt.BorderLayout; +//import java.awt.CardLayout; +//import java.awt.Color; +//import java.awt.FlowLayout; +//import java.text.MessageFormat; +//import java.util.List; +// +//import javax.swing.Action; +//import javax.swing.BorderFactory; +//import javax.swing.Icon; +//import javax.swing.JButton; +//import javax.swing.JLabel; +//import javax.swing.JOptionPane; +//import javax.swing.JPanel; +//import javax.swing.JProgressBar; +//import javax.swing.JScrollPane; +//import javax.swing.JSplitPane; +//import javax.swing.JTable; +//import javax.swing.JTextField; +//import javax.swing.ListSelectionModel; +//import javax.swing.SwingWorker; +//import javax.swing.event.ListSelectionEvent; +//import javax.swing.event.ListSelectionListener; +// +//import org.apache.commons.vfs2.FileObject; +//import org.apache.commons.vfs2.FileSystemException; +//import org.apache.commons.vfs2.FileType; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +// +//import eu.engys.util.otrosfilechooser.FileChooserSelectionChangedListener; +//import eu.engys.util.otrosfilechooser.ParentFileObject; +//import eu.engys.util.otrosfilechooser.favorites.Favorite; +//import eu.engys.util.otrosfilechooser.preview.PreviewListener; +//import eu.engys.util.otrosfilechooser.util.SelectionMode; +//import eu.engys.util.otrosfilechooser.util.SwingUtils; +//import eu.engys.util.otrosfilechooser.util.TaskContext; +//import eu.engys.util.otrosfilechooser.util.VFSUtils; +//import eu.engys.util.ui.ResourcesUtil; +// +//public class OriginalVfsBrowser extends JPanel { +// +// private static final Logger LOGGER = LoggerFactory.getLogger(OriginalVfsBrowser.class); +// public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY = "MultiSelectionEnabledChangedProperty"; +// public static final String MULTI_SELECTION_MODE_CHANGED_PROPERTY = "SelectionModeChangedProperty"; +// +// private static final String TABLE_KEY = "TABLE"; +// private static final String LOADING_KEY = "LOADING"; +// +// protected JPanel centralPanel; +// +// private JLabel statusLabel; +// +// private FileObject currentLocation; +// private CardLayout cardLayout; +// +// private SelectionMode selectionMode = SelectionMode.DIRS_AND_FILES; +// private Action actionApproveDelegate; +// private Action actionCancelDelegate; +// +// private boolean multiSelectionEnabled = false; +// private JButton actionApproveButton; +// private JButton actionCancelButton; +// private TaskContext taskContext; +// private URIPanel uriPanel; +// private FileSystemPanel fileSystemPanel; +// +// private FavoritesPanel favoritesPanel; +// +// private LoadingPanel loadingPanel; +// +// public OriginalVfsBrowser() { +// this(System.getProperty("user.home")); +// } +// +// public OriginalVfsBrowser(String initialPath) { +// this(initialPath, null); +// } +// +// public OriginalVfsBrowser(String initialPath, JPanel rightPanel) { +// this(initialPath, rightPanel, false); +// } +// +// public OriginalVfsBrowser(String initialPath, JPanel rightPanel, boolean remote) { +// this(initialPath, rightPanel, new String[0], remote); +// } +// +// public OriginalVfsBrowser(String initialPath, JPanel rightPanel, String[] filter, boolean remote) { +// this(initialPath, rightPanel, new String[0], remote, false, ""); +// } +// +// public OriginalVfsBrowser(String initialPath, JPanel rightPanel, String[] filter, boolean remote, boolean saveas, String currentProjectName) { +// super(new BorderLayout()); +// layoutComponents(initialPath, rightPanel, filter, remote, saveas, currentProjectName); +// VFSUtils.loadAuthStore(); +// } +// +// private void layoutComponents(final String initialPath, final JPanel rightPanel, String[] filter, boolean remote, boolean saveAs, String currentProjectName) { +// fileSystemPanel = new FileSystemPanel(this, filter); +// +// favoritesPanel = new FavoritesPanel(this); +// +// JSplitPane fileSystemAndPreviewPane = null; +// if (rightPanel != null) { +// if (rightPanel instanceof PreviewPanel) { +// fileSystemPanel.getTable().getSelectionModel().addListSelectionListener(new PreviewListener(this, (PreviewPanel) rightPanel)); +// } else if (rightPanel instanceof FileChooserSelectionChangedListener) { +// fileSystemPanel.getTable().getSelectionModel().addListSelectionListener(new ListSelectionListener() { +// +// @Override +// public void valueChanged(ListSelectionEvent e) { +// ((FileChooserSelectionChangedListener) rightPanel).onSelectionChanged(); +// } +// }); +// } +// fileSystemAndPreviewPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, fileSystemPanel, rightPanel); +// fileSystemAndPreviewPane.setOneTouchExpandable(false); +// fileSystemAndPreviewPane.setDividerLocation(350); +// +// } +// +// loadingPanel = new LoadingPanel(taskContext); +// +// centralPanel = new JPanel(cardLayout = new CardLayout()); +// centralPanel.add(loadingPanel, LOADING_KEY); +// if (fileSystemAndPreviewPane != null) { +// centralPanel.add(fileSystemAndPreviewPane, TABLE_KEY); +// } else { +// centralPanel.add(fileSystemPanel, TABLE_KEY); +// } +// +// showTable(); +// +// uriPanel = new URIPanel(this, remote); +// +// JSplitPane centralSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(favoritesPanel), centralPanel); +// centralSplitPane.setOneTouchExpandable(false); +// centralSplitPane.setDividerLocation(180); +// +// JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); +// mainPanel.add(uriPanel, BorderLayout.NORTH); +// mainPanel.add(centralSplitPane, BorderLayout.CENTER); +// mainPanel.add(createSouthPanel(saveAs, currentProjectName), BorderLayout.SOUTH); +// +// mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); +// +// this.add(mainPanel, BorderLayout.CENTER); +// +// postLayout(initialPath); +// } +// +// private void postLayout(final String initialPath) { +// try { +// selectionChanged(); +// } catch (FileSystemException e) { +// LOGGER.error("Can't initialize default selection mode", e); +// } +// try { +// if (initialPath == null) { +// goToUrl(VFSUtils.getUserHome()); +// } else { +// goToUrl(initialPath); +// } +// } catch (FileSystemException e1) { +// LOGGER.error("Can't initialize default location", e1); +// } +// } +// +// private JPanel createSouthPanel(boolean saveas, String currentProjectName) { +// JPanel southPanel = new JPanel(new BorderLayout()); +// +// JPanel leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); +// JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); +// +// actionApproveButton = new JButton(actionApproveDelegate); +// actionCancelButton = new JButton(actionCancelDelegate); +// +// leftPanel.add(statusLabel = new JLabel()); +// if (saveas) { +// rightPanel.add(new JLabel("Name:")); +// newFileNameField = new JTextField(15); +// newFileNameField.setText(currentProjectName + "_copy"); +// rightPanel.add(newFileNameField); +// } +// rightPanel.add(actionApproveButton); +// rightPanel.add(actionCancelButton); +// +// southPanel.add(leftPanel, BorderLayout.WEST); +// southPanel.add(rightPanel, BorderLayout.CENTER); +// +// return southPanel; +// } +// +// public String getNewFileName() { +// if (newFileNameField != null) { +// return newFileNameField.getText(); +// } +// return null; +// } +// +// public void selectionChanged() throws FileSystemException { +// LOGGER.debug("Updating selection"); +// boolean acceptEnabled = false; +// if (getSelectedFilesOnTable().length == 0) { +// acceptEnabled = false; +// } else if (isMultiSelectionEnabled()) { +// boolean filesSelected = false; +// boolean folderSelected = false; +// +// for (FileObject fo : getSelectedFilesOnTable()) { +// FileType fileType = fo.getType(); +// if (fileType == FileType.FILE) { +// filesSelected = true; +// } else if (fileType == FileType.FOLDER) { +// folderSelected = true; +// } +// } +// if (selectionMode == SelectionMode.FILES_ONLY && filesSelected && !folderSelected) { +// acceptEnabled = true; +// } else if (selectionMode == SelectionMode.DIRS_ONLY && !filesSelected && folderSelected) { +// acceptEnabled = true; +// } else if (selectionMode == SelectionMode.DIRS_AND_FILES) { +// acceptEnabled = true; +// } +// } else { +// FileObject selectedFileObject = fileSystemPanel.getSelectedFileObject(); +// FileType type = selectedFileObject.getType(); +// if (selectionMode == SelectionMode.FILES_ONLY && type == FileType.FILE || selectionMode == SelectionMode.DIRS_ONLY && type == FileType.FOLDER) { +// acceptEnabled = true; +// } else if (SelectionMode.DIRS_AND_FILES == selectionMode) { +// acceptEnabled = true; +// } +// } +// +// if (actionApproveDelegate != null) { +// actionApproveDelegate.setEnabled(acceptEnabled); +// } +// actionApproveButton.setEnabled(acceptEnabled); +// } +// +// public FileSystemPanel getFileSystemPanel() { +// return fileSystemPanel; +// } +// +// public JTable getFileSystemTable() { +// return fileSystemPanel.getTable(); +// } +// +// public void fixSelection() { +// fileSystemPanel.fixSelection(); +// } +// +// public void goToUrl(String url) { +// // System.out.println("VfsBrowser.goToUrl(): " + url); +// LOGGER.info("Going to URL: " + url); +// try { +// FileObject resolveFile = VFSUtils.resolveFileObject(url); +// String type = "?"; +// if (resolveFile != null) { +// type = resolveFile.getType().toString(); +// } +// LOGGER.info("URL: " + url + " is resolved " + type); +// goToUrl(resolveFile); +// } catch (FileSystemException e) { +// LOGGER.error("Can't go to URL " + url, e); +// final String message = getRootCause(e).getClass().getName() + ": " + getRootCause(e).getLocalizedMessage(); +// +// Runnable runnable = new Runnable() { +// public void run() { +// JOptionPane.showMessageDialog(OriginalVfsBrowser.this, "Can't open location: " + message); +// } +// }; +// SwingUtils.runInEdt(runnable); +// } +// } +// +// public void goToUrl(final FileObject fileObject) { +// if (taskContext != null) { +// taskContext.setStop(true); +// } +// // +// final FileObject[] files = VFSUtils.getFiles(fileObject); +// LOGGER.info("Have {} files in {}", files.length, fileObject.getName().getFriendlyURI()); +// this.currentLocation = fileObject; +// // +// taskContext = new TaskContext(BROWSER_CHECKINGSFTPLINKSTASK, files.length); +// taskContext.setIndeterminate(false); +// SwingWorker refreshWorker = new SwingWorker() { +// int icon = 0; +// Icon[] icons = new Icon[] { NETWORKSTATUSONLINE, NETWORKSTATUSAWAY, NETWORKSTATUSOFFLINE }; +// +// @Override +// protected void process(List chunks) { +// JProgressBar loadingProgressBar = loadingPanel.getLoadingProgressBar(); +// loadingProgressBar.setIndeterminate(taskContext.isIndeterminate()); +// loadingProgressBar.setMaximum(taskContext.getMax()); +// loadingProgressBar.setValue(taskContext.getCurrentProgress()); +// loadingProgressBar.setString(String.format("%s [%d of %d]", taskContext.getName(), taskContext.getCurrentProgress(), taskContext.getMax())); +// loadingPanel.getLoadingIconLabel().setIcon(icons[++icon % icons.length]); +// } +// +// @Override +// protected Void doInBackground() throws Exception { +// try { +// while (!taskContext.isStop()) { +// publish(); +// Thread.sleep(300); +// } +// } catch (InterruptedException ignore) { +// // ignore +// } +// return null; +// } +// }; +// new Thread(refreshWorker).start(); +// +// if (!loadingPanel.getSkipCheckingLinksButton().isSelected()) { +// VFSUtils.checkForSftpLinks(files, taskContext); +// } +// taskContext.setStop(true); +// final FileObject[] fileObjectsWithParent = addParentToFiles(files); +// Runnable r = new Runnable() { +// +// @Override +// public void run() { +// fileSystemPanel.setContent(fileObjectsWithParent); +// uriPanel.setFileObject(fileObject); +// int filesCount = files.length; +// statusLabel.setText(MessageFormat.format(BROWSER_FOLDERCONTAINSXELEMENTS, filesCount)); +// JTable table = fileSystemPanel.getTable(); +// if (table.getRowCount() > 0) { +// table.getSelectionModel().setSelectionInterval(0, 0); +// } +// } +// }; +// SwingUtils.runInEdt(r); +// } +// +// public static Throwable getRootCause(Throwable t) { +// while (t.getCause() != null) { +// t = t.getCause(); +// } +// return t; +// } +// +// private FileObject[] addParentToFiles(FileObject[] files) { +// FileObject[] newFiles = new FileObject[files.length + 1]; +// try { +// FileObject parent = currentLocation.getParent(); +// if (parent != null) { +// newFiles[0] = new ParentFileObject(parent); +// System.arraycopy(files, 0, newFiles, 1, files.length); +// } else { +// newFiles = files; +// } +// } catch (FileSystemException e) { +// LOGGER.warn("Can't add parent", e); +// newFiles = files; +// } +// return newFiles; +// } +// +// public FileObject getCurrentLocation() { +// return currentLocation; +// } +// +// public void addFavorite(Favorite favorite) { +// favoritesPanel.getFavoritesUserListModel().add(favorite); +// } +// +// public void showLoading() { +// System.out.println("VfsBrowser.showLoading()----------------------"); +// LOGGER.trace("Showing loading panel"); +// JProgressBar loadingProgressBar = loadingPanel.getLoadingProgressBar(); +// loadingProgressBar.setIndeterminate(true); +// loadingProgressBar.setString(BROWSER_LOADING); +// loadingPanel.getSkipCheckingLinksButton().setSelected(false); +// loadingPanel.setBorder(BorderFactory.createLineBorder(Color.RED)); +// cardLayout.show(centralPanel, LOADING_KEY); +// } +// +// public void showTable() { +// LOGGER.trace("Showing result table"); +// fileSystemPanel.resetScroll(); +// cardLayout.show(centralPanel, TABLE_KEY); +// } +// +// public boolean isMultiSelectionEnabled() { +// return multiSelectionEnabled; +// } +// +// public void setMultiSelectionEnabled(boolean b) { +// int selectionMode = b ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : ListSelectionModel.SINGLE_SELECTION; +// fileSystemPanel.getTable().getSelectionModel().setSelectionMode(selectionMode); +// if (multiSelectionEnabled == b) { +// return; +// } +// boolean oldValue = multiSelectionEnabled; +// multiSelectionEnabled = b; +// firePropertyChange(MULTI_SELECTION_ENABLED_CHANGED_PROPERTY, oldValue, multiSelectionEnabled); +// try { +// selectionChanged(); +// } catch (FileSystemException e) { +// LOGGER.error("Error during update state", e); +// } +// } +// +// public SelectionMode getSelectionMode() { +// return selectionMode; +// } +// +// public void setSelectionMode(SelectionMode mode) { +// if (selectionMode == mode) { +// return; +// } +// SelectionMode oldValue = selectionMode; +// this.selectionMode = mode; +// firePropertyChange(MULTI_SELECTION_MODE_CHANGED_PROPERTY, oldValue, selectionMode); +// try { +// selectionChanged(); +// } catch (FileSystemException e) { +// LOGGER.error("Error during update state", e); +// } +// } +// +// public JButton getActionApproveButton() { +// return actionApproveButton; +// } +// +// public Action getActionApproveDelegate() { +// return actionApproveDelegate; +// } +// +// public void setApproveAction(Action action) { +// actionApproveDelegate = action; +// actionApproveButton.setAction(actionApproveDelegate); +// if (action != null) { +// actionApproveButton.setText((String) actionApproveDelegate.getValue(Action.NAME)); +// } +// try { +// selectionChanged(); +// } catch (FileSystemException e) { +// LOGGER.warn("Problem with checking selection conditions", e); +// } +// } +// +// public void setCancelAction(Action cancelAction) { +// actionCancelDelegate = cancelAction; +// actionCancelButton.setAction(actionCancelDelegate); +// try { +// selectionChanged(); +// } catch (FileSystemException e) { +// LOGGER.warn("Problem with checking selection conditions", e); +// } +// +// } +// +// public FileObject[] getSelectedFilesOnTable() { +// return fileSystemPanel.getSelectedFileObjects(); +// } +// +// /** +// * Resources +// */ +// +// private static final String BROWSER_CHECKINGSFTPLINKSTASK = ResourcesUtil.getString("browser.checkingSFtpLinksTask"); +// private static final String BROWSER_FOLDERCONTAINSXELEMENTS = ResourcesUtil.getString("browser.folderContainsXElements"); +// private static final String BROWSER_LOADING = ResourcesUtil.getString("browser.loading..."); +// +// private static final Icon NETWORKSTATUSAWAY = ResourcesUtil.getIcon("networkStatusAway"); +// private static final Icon NETWORKSTATUSONLINE = ResourcesUtil.getIcon("networkStatusOnline"); +// private static final Icon NETWORKSTATUSOFFLINE = ResourcesUtil.getIcon("networkStatusOffline"); +// private JTextField newFileNameField; +// +//} diff --git a/src/eu/engys/util/filechooser/depot/SftpUserAuthenticator.java b/src/eu/engys/util/filechooser/depot/SftpUserAuthenticator.java new file mode 100644 index 0000000..f81f133 --- /dev/null +++ b/src/eu/engys/util/filechooser/depot/SftpUserAuthenticator.java @@ -0,0 +1,140 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.depot; +///* +// * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package eu.engys.util.otrosfilechooser.authentication.authenticator; +// +//import java.awt.event.ActionEvent; +//import java.awt.event.ActionListener; +//import java.io.File; +// +//import javax.swing.JButton; +//import javax.swing.JFileChooser; +//import javax.swing.JLabel; +//import javax.swing.JTextField; +// +//import net.java.dev.designgridlayout.Componentizer; +// +//import org.apache.commons.lang.StringUtils; +//import org.apache.commons.vfs2.FileSystemException; +//import org.apache.commons.vfs2.FileSystemOptions; +//import org.apache.commons.vfs2.UserAuthenticationData; +//import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder; +// +//import eu.engys.util.otrosfilechooser.authentication.UserAuthenticationDataWrapper; +//import eu.engys.util.ui.ResourcesUtil; +//import eu.engys.util.ui.builder.PanelBuilder; +// +//public class SftpUserAuthenticator extends FTPUserAuthenticator { +// +// private JTextField sshKeyFileField; +// private static JFileChooser chooser; +// +// public SftpUserAuthenticator(String url, FileSystemOptions fileSystemOptions) { +// super(url, fileSystemOptions); +// } +// +// @Override +// protected void updateAuthenticationData(UserAuthenticationData authenticationData) { +// super.updateAuthenticationData(authenticationData); +// authenticationData.setData(UserAuthenticationDataWrapper.SSH_KEY, sshKeyFileField.getText().trim().toCharArray()); +// +// if (StringUtils.isNotBlank(sshKeyFileField.getText())) { +// try { +// SftpFileSystemConfigBuilder.getInstance().setIdentities(getFileSystemOptions(), new File[] { new File(sshKeyFileField.getText()) }); +// // TODO set user auth data file path +// } catch (FileSystemException e) { +// e.printStackTrace(); +// } +// } +// +// } +// +// @Override +// protected PanelBuilder getOptionsPanelBuilder() { +// if (sshKeyFileField == null) { +// sshKeyFileField = new JTextField(15); +// } +// if (chooser == null) { +// chooser = new JFileChooser(); +// } +// PanelBuilder builder = super.getOptionsPanelBuilder(); +// +// JButton browseButton = new JButton("..."); +// browseButton.addActionListener(new ActionListener() { +// +// @Override +// public void actionPerformed(ActionEvent e) { +// chooser.setMultiSelectionEnabled(false); +// chooser.setDialogTitle(AUTHENTICATOR_SELECTSSHKEY); +// int showOpenDialog = chooser.showOpenDialog(null); +// if (showOpenDialog == JFileChooser.APPROVE_OPTION) { +// sshKeyFileField.setText(chooser.getSelectedFile().getAbsolutePath()); +// } +// } +// }); +// builder.addComponent(AUTHENTICATOR_SSHKEYFILE, Componentizer.create().prefAndMore(sshKeyFileField).minToPref(browseButton).component()); +// builder.addComponent(new JLabel(AUTHENTICATOR_SSHKEYFILEDESCRIPTION)); +// +// return builder; +// } +// +// @Override +// protected void userSelectedHook(UserAuthenticationData userAuthenticationData) { +// if (userAuthenticationData != null) { +// char[] sshKeyPath = userAuthenticationData.getData(UserAuthenticationDataWrapper.SSH_KEY); +// String path = ""; +// if (sshKeyPath != null && sshKeyPath.length > 0) { +// path = new String(sshKeyPath); +// } +// sshKeyFileField.setText(path); +// } +// } +// +// /** +// * Resources +// */ +// +// private static final String AUTHENTICATOR_SSHKEYFILE = ResourcesUtil.getString("authenticator.sshKeyFile"); +// private static final String AUTHENTICATOR_SELECTSSHKEY = ResourcesUtil.getString("authenticator.selectSshKey"); +// private static final String AUTHENTICATOR_SSHKEYFILEDESCRIPTION = ResourcesUtil.getString("authenticator.sshKeyFileDescription"); +// +//} diff --git a/src/eu/engys/util/filechooser/depot/SmbUserAuthenticator.java b/src/eu/engys/util/filechooser/depot/SmbUserAuthenticator.java new file mode 100644 index 0000000..9f8bfdf --- /dev/null +++ b/src/eu/engys/util/filechooser/depot/SmbUserAuthenticator.java @@ -0,0 +1,111 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.depot; +///* +// * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package eu.engys.util.otrosfilechooser.depot; +// +//import javax.swing.JLabel; +//import javax.swing.JPanel; +//import javax.swing.JTextField; +// +//import org.apache.commons.vfs2.FileSystemOptions; +//import org.apache.commons.vfs2.UserAuthenticationData; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +// +//import eu.engys.util.otrosfilechooser.authentication.AuthStore; +//import eu.engys.util.ui.ResourcesUtil; +//import eu.engys.util.ui.builder.PanelBuilder; +// +//public class SmbUserAuthenticator extends FTPUserAuthenticator { +// +// private static final Logger LOGGER = LoggerFactory.getLogger(SmbUserAuthenticator.class); +// +// private JTextField fieldTextField; +// +// public SmbUserAuthenticator(AuthStore authStore, String url, FileSystemOptions fileSystemOptions) { +// super(authStore, url, fileSystemOptions); +// } +// +// @Override +// public UserAuthenticationData requestAuthentication(UserAuthenticationData.Type[] types) { +// LOGGER.debug("Requested for authentication"); +// for (UserAuthenticationData.Type type : types) { +// LOGGER.debug("Requested for authentication: %s", type); +// } +// if (data == null) { +// return super.requestAuthentication(types); +// } else { +// return data; +// } +// } +// +// @Override +// protected void updateAuthenticationData(UserAuthenticationData authenticationData) { +// super.updateAuthenticationData(authenticationData); +// authenticationData.setData(UserAuthenticationData.DOMAIN, fieldTextField.getText().toCharArray()); +// } +// +// @Override +// protected void userSelectedHook(UserAuthenticationData userAuthenticationData) { +// char[] domain = new char[0]; +// if (userAuthenticationData != null) { +// domain = userAuthenticationData.getData(UserAuthenticationData.DOMAIN); +// } +// fieldTextField.setText(new String(domain)); +// +// } +// +// @Override +// protected PanelBuilder getOptionsPanelBuilder() { +// PanelBuilder panel = super.getOptionsPanelBuilder(); +// fieldTextField = new JTextField(15); +// panel.addComponent(AUTHENTICATOR_DOMAIN, fieldTextField); +// return panel; +// } +// +// /** +// * Resources +// */ +// +// private static final String AUTHENTICATOR_DOMAIN = ResourcesUtil.getString("authenticator.domain"); +// +//} diff --git a/src/eu/engys/util/filechooser/favorites/Favorite.java b/src/eu/engys/util/filechooser/favorites/Favorite.java new file mode 100644 index 0000000..4d208af --- /dev/null +++ b/src/eu/engys/util/filechooser/favorites/Favorite.java @@ -0,0 +1,100 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.favorites; + +public class Favorite { + + public enum Type { + USER, SYSTEM, JVFSFILECHOOSER; + + public boolean isSystem() { + return equals(SYSTEM); + } + + public boolean isUser() { + return equals(USER); + } + } + + private String name; + + private Type type = Type.USER; + + private String url; + + public Favorite(String name, String url, Type type) { + this.name = name; + this.type = type; + this.url = url; + + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + @Override + public String toString() { + return name + " [" + url + "]"; + } + +} diff --git a/src/eu/engys/util/filechooser/favorites/FavoritesUtils.java b/src/eu/engys/util/filechooser/favorites/FavoritesUtils.java new file mode 100644 index 0000000..ff15206 --- /dev/null +++ b/src/eu/engys/util/filechooser/favorites/FavoritesUtils.java @@ -0,0 +1,135 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.favorites; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.filechooser.FileSystemView; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; +import eu.engys.util.filechooser.favorites.Favorite.Type; + +public class FavoritesUtils { + + private static final Logger logger = LoggerFactory.getLogger(FavoritesUtils.class); + + public static final String HOME = "Home"; + public static final String DESKTOP = "Desktop"; + public static final String DOCUMENTS = "Documents"; + private static final String FAVORITES_PREFERENCE_DELIMITER = "@@@"; + private static final String FAVORITE_NAME_URL_DELIMITER = "##"; + + public static final File HOME_DIRECTORY = new File(System.getProperty("user.home")); + + public static final File VFS_JFC_CONFIG_DIRECTORY = new File(HOME_DIRECTORY, ".vfsjfilechooser"); + public static final File VFS_JFC_BOOKMARKS_FILE = new File(VFS_JFC_CONFIG_DIRECTORY, "favorites.xml"); + + public List loadFavorite() { + return new ArrayList(); + } + + public static List loadFavorites() { + List list = new ArrayList(); + String favoritesString = PrefUtil.getString(PrefUtil.FAVORITES_KEY); + if (!favoritesString.isEmpty()) { + String[] favorites = favoritesString.split(FAVORITES_PREFERENCE_DELIMITER); + for (int i = 0; i < favorites.length; i++) { + String fav = favorites[i]; + if (!fav.isEmpty()) { + String[] nameAndURL = fav.split(FAVORITE_NAME_URL_DELIMITER); + if (nameAndURL.length == 2) { + String name = nameAndURL[0]; + String url = nameAndURL[1]; + list.add(new Favorite(name, url, Type.USER)); + } + } + } + } + return list; + } + + public static void saveFavorites(List favoriteList) { + StringBuffer favoritesString = new StringBuffer(); + for (Favorite favorite : favoriteList) { + if (favorite.getType().equals(Type.USER)) { + favoritesString.append(favorite.getName()); + favoritesString.append(FAVORITE_NAME_URL_DELIMITER); + favoritesString.append(favorite.getUrl()); + favoritesString.append(FAVORITES_PREFERENCE_DELIMITER); + } + } + PrefUtil.putString(PrefUtil.FAVORITES_KEY, favoritesString.toString()); + } + + public static List loadSystemLocations() { + List list = new ArrayList(); + File[] listRoots = File.listRoots(); + for (File file : listRoots) { + list.add(new Favorite(file.getAbsolutePath(), file.getAbsolutePath(), Favorite.Type.SYSTEM)); + } + File userHome = new File(System.getProperty("user.home")); + File desktop = null; + File documents = null; + if (Util.isWindows()) { + desktop = FileSystemView.getFileSystemView().getHomeDirectory(); + documents = FileSystemView.getFileSystemView().getDefaultDirectory(); + } else { + desktop = new File(userHome, "Desktop"); + documents = new File(userHome, "Documents"); + } + + list.add(new Favorite(HOME, userHome.getAbsolutePath(), Favorite.Type.SYSTEM)); + if (desktop.exists()) { + list.add(new Favorite(DESKTOP, desktop.getAbsolutePath(), Favorite.Type.SYSTEM)); + } + if (documents.exists()) { + list.add(new Favorite(DOCUMENTS, documents.getAbsolutePath(), Favorite.Type.SYSTEM)); + } + return list; + } +} diff --git a/src/eu/engys/util/filechooser/favorites/PopupListener.java b/src/eu/engys/util/filechooser/favorites/PopupListener.java new file mode 100644 index 0000000..945a4e8 --- /dev/null +++ b/src/eu/engys/util/filechooser/favorites/PopupListener.java @@ -0,0 +1,116 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.favorites; + +import java.awt.Component; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JList; +import javax.swing.JPopupMenu; +import javax.swing.JTable; + +public class PopupListener extends MouseAdapter implements KeyListener { + + private JPopupMenu popupMenu; + + public PopupListener(JPopupMenu popupMenu) { + super(); + this.popupMenu = popupMenu; + } + + public void mousePressed(MouseEvent e) { + checkPopup(e); + } + + public void mouseClicked(MouseEvent e) { + checkPopup(e); + } + + public void mouseReleased(MouseEvent e) { + checkPopup(e); + } + + private void checkPopup(MouseEvent e) { + if (e.isPopupTrigger()) { + show((Component) e.getSource(), e.getX(), e.getY()); + } + } + + public void show(Component invoker, int x, int y) { + popupMenu.show(invoker, x, y); + } + + @Override + public void keyTyped(KeyEvent e) { + + } + + @Override + public void keyPressed(KeyEvent e) { + Point p = new Point(e.getComponent().getLocation()); + + if (e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU) { + if (e.getComponent() instanceof JTable) { + JTable table = (JTable) e.getComponent(); + int selectedRow = table.getSelectedRow(); + Rectangle cellRect = table.getCellRect(selectedRow, 0, true); + p.setLocation(cellRect.getCenterX(), cellRect.getCenterY()); + } else if (e.getComponent() instanceof JList) { + JList list = (JList) e.getComponent(); + int selectedIndex = list.getSelectedIndex(); + Rectangle cellRect = list.getCellBounds(selectedIndex, selectedIndex); + p.setLocation(cellRect.getCenterX(), cellRect.getCenterY()); + } + show(e.getComponent(), (int) p.getX(), (int) p.getY()); + } + } + + @Override + public void keyReleased(KeyEvent e) { + + } +} diff --git a/src/eu/engys/util/filechooser/favorites/list/MutableListDragListener.java b/src/eu/engys/util/filechooser/favorites/list/MutableListDragListener.java new file mode 100644 index 0000000..6ee854d --- /dev/null +++ b/src/eu/engys/util/filechooser/favorites/list/MutableListDragListener.java @@ -0,0 +1,87 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.favorites.list; + +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; + +import javax.swing.JList; + +public class MutableListDragListener implements DragSourceListener, DragGestureListener { + private JList list; + + private DragSource ds = new DragSource(); + + public MutableListDragListener(final JList list) { + this.list = list; + ds.createDefaultDragGestureRecognizer(list, DnDConstants.ACTION_MOVE, this); + + } + + public void dragGestureRecognized(final DragGestureEvent dge) { + final StringSelection transferable = new StringSelection(Integer.toString(list.getSelectedIndex())); + ds.startDrag(dge, DragSource.DefaultCopyDrop, transferable, this); + } + + public void dragEnter(final DragSourceDragEvent dsde) { + } + + public void dragExit(final DragSourceEvent dse) { + } + + public void dragOver(final DragSourceDragEvent dsde) { + } + + public void dragDropEnd(final DragSourceDropEvent dsde) { + + } + + public void dropActionChanged(final DragSourceDragEvent dsde) { + } +} diff --git a/src/eu/engys/util/filechooser/favorites/list/MutableListDropHandler.java b/src/eu/engys/util/filechooser/favorites/list/MutableListDropHandler.java new file mode 100644 index 0000000..da82ed3 --- /dev/null +++ b/src/eu/engys/util/filechooser/favorites/list/MutableListDropHandler.java @@ -0,0 +1,95 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.favorites.list; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; + +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.TransferHandler; + +import eu.engys.util.ui.UiUtil; + +public class MutableListDropHandler extends TransferHandler { + private JList list; + + public MutableListDropHandler(final JList list) { + this.list = list; + } + + public boolean canImport(final TransferHandler.TransferSupport support) { + if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) { + return false; + } + final JList.DropLocation dl = (JList.DropLocation) support.getDropLocation(); + if (dl.getIndex() == -1) { + return false; + } else { + return true; + } + } + + public boolean importData(final TransferHandler.TransferSupport support) { + if (!canImport(support)) { + return false; + } + + final Transferable transferable = support.getTransferable(); + String indexString; + try { + indexString = (String) transferable.getTransferData(DataFlavor.stringFlavor); + } catch (final Exception e) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), e.getMessage(), "File Chooser Error", JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + return false; + } + + int index = Integer.parseInt(indexString); + final JList.DropLocation dl = (JList.DropLocation) support.getDropLocation(); + final int dropTargetIndex = dl.getIndex(); + + final MutableListModel model = (MutableListModel) list.getModel(); + model.move(index, dropTargetIndex); + return true; + } +} diff --git a/src/eu/engys/util/filechooser/favorites/list/MutableListModel.java b/src/eu/engys/util/filechooser/favorites/list/MutableListModel.java new file mode 100644 index 0000000..6887c21 --- /dev/null +++ b/src/eu/engys/util/filechooser/favorites/list/MutableListModel.java @@ -0,0 +1,98 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.favorites.list; + +import java.util.ArrayList; +import java.util.List; + +import javax.swing.AbstractListModel; + +/** + */ +public class MutableListModel extends AbstractListModel { + + private ArrayList list; + + public MutableListModel() { + list = new ArrayList(); + } + + @Override + public int getSize() { + return list.size(); + } + + @Override + public T getElementAt(int index) { + return list.get(index); + } + + public void add(T favorite) { + list.add(favorite); + fireIntervalAdded(this, list.size() - 1, list.size() - 1); + } + + public void remove(int index) { + list.remove(index); + fireIntervalRemoved(this, index, index); + } + + public void change(int index, T favorite) { + list.set(index, favorite); + fireContentsChanged(this, index, index); + } + + public void move(int from, int to) { + list.add(to, list.get(from)); + if (to < from) { + from++; + } + list.remove(from); + fireContentsChanged(this, Math.min(from, to), Math.max(from, to)); + + } + + public List getList() { + return new ArrayList(list); + } + +} diff --git a/src/eu/engys/util/filechooser/favorites/list/SelectFirstElementFocusAdapter.java b/src/eu/engys/util/filechooser/favorites/list/SelectFirstElementFocusAdapter.java new file mode 100644 index 0000000..a61ecdb --- /dev/null +++ b/src/eu/engys/util/filechooser/favorites/list/SelectFirstElementFocusAdapter.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.favorites.list; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; + +import javax.swing.JList; + +/** + * When component gained focus is list without selection, first element is + * selected. + */ +public class SelectFirstElementFocusAdapter extends FocusAdapter { + @Override + public void focusGained(FocusEvent e) { + if (e.getSource() instanceof JList) { + JList list = (JList) e.getSource(); + if (list.getSelectedIndex() < 0 && list.getModel().getSize() > 0) { + list.setSelectedIndex(0); + } + } + } +} diff --git a/src/eu/engys/util/filechooser/favorites/renderer/FavoriteListCellRenderer.java b/src/eu/engys/util/filechooser/favorites/renderer/FavoriteListCellRenderer.java new file mode 100644 index 0000000..76d1074 --- /dev/null +++ b/src/eu/engys/util/filechooser/favorites/renderer/FavoriteListCellRenderer.java @@ -0,0 +1,93 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.favorites.renderer; + +import java.awt.Component; + +import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.JLabel; +import javax.swing.JList; + +import eu.engys.util.filechooser.favorites.Favorite; +import eu.engys.util.filechooser.favorites.FavoritesUtils; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ResourcesUtil; + + +/** + */ +public class FavoriteListCellRenderer extends DefaultListCellRenderer { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + Component component = super.getListCellRendererComponent(list, value, index, isSelected & cellHasFocus, cellHasFocus); + if (component instanceof JLabel) { + JLabel label = (JLabel) component; + Favorite f = (Favorite) value; + label.setText(f.getName()); + label.setToolTipText(VFSUtils.getFriendlyName(f.getUrl())); + + if(f.getType().isSystem()){ + if(FavoritesUtils.HOME.equals(f.getName())){ + label.setIcon(HOME_ICON); + } else if(FavoritesUtils.DESKTOP.equals(f.getName())){ + label.setIcon(DESKTOP_ICON); + } else if(FavoritesUtils.DOCUMENTS.equals(f.getName())){ + label.setIcon(DOCUMENTS_ICON); + } else { + label.setIcon(VFSUtils.getIconForFileSystem(f.getUrl())); + } + } else { + label.setIcon(VFSUtils.getIconForFileSystem(f.getUrl())); + } + } + + return component; + } + + /* + * RESOURCES + */ + private static final Icon HOME_ICON = ResourcesUtil.getIcon("home"); + private static final Icon DESKTOP_ICON = ResourcesUtil.getIcon("desktop"); + private static final Icon DOCUMENTS_ICON = ResourcesUtil.getIcon("documents"); +} diff --git a/src/eu/engys/util/filechooser/gui/Accessory.java b/src/eu/engys/util/filechooser/gui/Accessory.java new file mode 100644 index 0000000..976bb31 --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/Accessory.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import javax.swing.JPanel; + +public interface Accessory { + + void onSelectionChanged(); + + JPanel getPanel(); + +} diff --git a/src/eu/engys/util/filechooser/gui/BreadCrumbsPanel.java b/src/eu/engys/util/filechooser/gui/BreadCrumbsPanel.java new file mode 100644 index 0000000..1416717 --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/BreadCrumbsPanel.java @@ -0,0 +1,159 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; + +public class BreadCrumbsPanel extends JPanel { + + public static final String NAME = "chooser.breadcrumbspanel"; + + private FileChooserController controller; + private JPanel mainPanel; + private JScrollPane scrollPanel; + private MoveToTheEndListener listener; + private JScrollBar horizontalScrollBar; + + private List buttons = new ArrayList<>(); + + public BreadCrumbsPanel(FileChooserController controller) { + super(new BorderLayout()); + this.controller = controller; + setName(NAME); + layoutComponents(); + } + + private void layoutComponents() { + this.mainPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + this.mainPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); + this.scrollPanel = createScrollPanel(); + this.horizontalScrollBar = scrollPanel.getHorizontalScrollBar(); + scrollPanel.getHorizontalScrollBar().setPreferredSize(new Dimension(0, 8)); + this.listener = new MoveToTheEndListener(); + add(scrollPanel, BorderLayout.CENTER); + } + + private JScrollPane createScrollPanel() { + JScrollPane scrollPanel = new JScrollPane(mainPanel); + scrollPanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + scrollPanel.setBorder(BorderFactory.createEmptyBorder()); + return scrollPanel; + } + + public void updatePanel(FileObject fileObject) { + horizontalScrollBar.addAdjustmentListener(listener); + + buttons.clear(); + mainPanel.removeAll(); + addButtons(fileObject); + + revalidate(); + repaint(); + } + + private void addButtons(FileObject fileObject) { + try { + addButtonFor(fileObject); + } catch (FileSystemException e) { + e.printStackTrace(); + } + } + + private void addButtonFor(final FileObject fo) throws FileSystemException { + if (fo != null) { + FileObject parent = fo.getParent(); + if (parent != null) { + addButtonFor(parent); + } + if (isRoot(fo)) { + _add(fo, "/"); + } else { + String baseName = fo.getName().getBaseName(); + if (!baseName.isEmpty()) { + _add(fo, baseName); + } + } + } + } + + private void _add(final FileObject fo, String name) { + JButton button = new JButton(new AbstractAction(name) { + @Override + public void actionPerformed(ActionEvent arg0) { + controller.goToURL(fo); + } + }); + button.setName(name); + mainPanel.add(button); + buttons.add(button); + } + + private boolean isRoot(FileObject fo) throws FileSystemException { + return fo.getName().getBaseName().isEmpty() && fo.getParent() == null; + } + + public List getButtons() { + return buttons; + } + + public List getPath() { + List path = new ArrayList<>(); + for (JButton b : buttons) { + path.add((String) b.getAction().getValue(Action.NAME)); + } + return path; + } + + private class MoveToTheEndListener implements AdjustmentListener { + + @Override + public void adjustmentValueChanged(AdjustmentEvent e) { + if (!e.getValueIsAdjusting()) { + horizontalScrollBar.setValue(horizontalScrollBar.getMaximum()); + horizontalScrollBar.removeAdjustmentListener(this); + } + } + } + +} diff --git a/src/eu/engys/util/filechooser/gui/BrowserFactory.java b/src/eu/engys/util/filechooser/gui/BrowserFactory.java new file mode 100644 index 0000000..16a21d0 --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/BrowserFactory.java @@ -0,0 +1,65 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import eu.engys.util.connection.SshParameters; +import eu.engys.util.filechooser.AbstractFileChooser; +import eu.engys.util.filechooser.util.HelyxFileFilter; + +public class BrowserFactory { + + public static FileChooserPanel createOpenBrowser(AbstractFileChooser chooser) { + return new FileChooserPanel(chooser, null, null, null, false); + } + + public static FileChooserPanel createOpenBrowser(AbstractFileChooser chooser, HelyxFileFilter... filters) { + return new FileChooserPanel(chooser, null, null, null, false, filters); + } + + public static FileChooserPanel createOpenBrowser(AbstractFileChooser chooser, Accessory accessory) { + return new FileChooserPanel(chooser, accessory, null, null, false); + } + + public static FileChooserPanel createOpenBrowser(AbstractFileChooser chooser, Options options) { + return new FileChooserPanel(chooser, null, options, null, false); + } + + public static FileChooserPanel createOpenBrowser(AbstractFileChooser chooser, Accessory accessory, HelyxFileFilter... filters) { + return new FileChooserPanel(chooser, accessory, null, null, false, filters); + } + + public static FileChooserPanel createSaveAsBrowser(AbstractFileChooser chooser) { + return new FileChooserPanel(chooser, null, null, null, true); + } + + public static FileChooserPanel createSaveAsBrowser(AbstractFileChooser chooser, HelyxFileFilter... filters) { + return new FileChooserPanel(chooser, null, null, null, true, filters); + } + + public static FileChooserPanel createOpenRemoteBrowser(AbstractFileChooser chooser, SshParameters sshParameters) { + return new FileChooserPanel(chooser, null, null, sshParameters, false); + } +} diff --git a/src/eu/engys/util/filechooser/gui/ButtonsPanel.java b/src/eu/engys/util/filechooser/gui/ButtonsPanel.java new file mode 100644 index 0000000..a4e93de --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/ButtonsPanel.java @@ -0,0 +1,208 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +import net.java.dev.designgridlayout.Componentizer; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileType; + +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.builder.PanelBuilder; + +public class ButtonsPanel extends JPanel { + + public static final String NAME = "chooser.buttonspanel"; + public static final String FILTER_COMBO = "filter.combo"; + + private FileChooserController controller; + private HelyxFileFilter[] filters; + private JComboBox filterCombo; + private JButton okButton; + + public ButtonsPanel(FileChooserController controller, HelyxFileFilter[] filters) { + super(new BorderLayout()); + this.filters = filters; + setName(NAME); + this.controller = controller; + layoutComponents(); + } + + private void layoutComponents() { + PanelBuilder pb = new PanelBuilder(); + okButton = new JButton(new OkAction()); + okButton.setName("OK"); + okButton.setEnabled(false); + JButton cancelButton = new JButton(new CancelAction()); + cancelButton.setName("Cancel"); + if (filters != null) { + filterCombo = createFilterCombo(); + pb.addComponent("Type", Componentizer.create().prefAndMore(filterCombo).minToPref(okButton, cancelButton).component()); + } else { + pb.addComponent(Componentizer.create().prefAndMore(new JLabel()).minToPref(okButton, cancelButton).component()); + } + add(pb.getPanel(), BorderLayout.CENTER); + } + + public void updateOkButton() { + ExecUtil.invokeAndWait(new Runnable() { + + @Override + public void run() { + _updateOkButton_OnEDT(); + } + }); + } + + private void _updateOkButton_OnEDT() { + FileObject fileSystemPanelFileObject = controller.getFileSystemPanel().getSelectedFileObject(); + FileObject uriPanelFileObject = controller.getUriPanel().getFileObject(); + + if (controller.isSaveAs()) { + String uriPanelNewFileName = controller.getUriPanel().getNewFileName(); + okButton.setEnabled(uriPanelFileObject != null && !uriPanelNewFileName.isEmpty()); + } else { + if (fileSystemPanelFileObject == null) { + if (controller.getSelectionMode().isDirsOnly() || controller.getSelectionMode().isDirsAndArchives()) { + okButton.setEnabled(uriPanelFileObject != null); + } else { + okButton.setEnabled(false); + } + } else { + okButton.setEnabled(checkTypeAndExtension(fileSystemPanelFileObject)); + } + } + } + + private boolean checkTypeAndExtension(FileObject selectedFileObject) { + try { + boolean rightType1 = (selectedFileObject.getType() == FileType.FILE) && controller.getSelectionMode().isFilesOnly(); + boolean rightType2 = (selectedFileObject.getType() == FileType.FOLDER) && controller.getSelectionMode().isDirsOnly(); + boolean rightType3 = (selectedFileObject.getType() == FileType.FOLDER) && controller.getSelectionMode().isDirsAndArchives(); + boolean rightType4 = controller.getSelectionMode().isDirsAndFiles(); + boolean rightType = rightType1 || rightType2 || rightType3 || rightType4; + + boolean rightExtension = true; + HelyxFileFilter filter = getSelectedFilter(); + if (filter != null && !filter.isAllFilesFilter()) { + String fileName = selectedFileObject.getName().getBaseName(); + String fileExtension = selectedFileObject.getName().getExtension(); + rightExtension = fileExtension.isEmpty() ? filter.isValidExtension(fileName) : filter.isValidExtension(fileExtension); + } + return rightExtension && (rightType); + } catch (FileSystemException e) { + return false; + } + } + + private JComboBox createFilterCombo() { + JComboBox filterCombo = new JComboBox(); + filterCombo.setName(FILTER_COMBO); + filterCombo.addItem(HelyxFileFilter.getAllFilesFilter()); + for (HelyxFileFilter filter : filters) { + filterCombo.addItem(filter); + } + filterCombo.setSelectedIndex(filterCombo.getItemCount() > 1 ? 1 : 0); + final ListCellRenderer renderer = filterCombo.getRenderer(); + filterCombo.setRenderer(new ListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, HelyxFileFilter value, int index, boolean isSelected, boolean cellHasFocus) { + Component c = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (c instanceof JLabel && value instanceof HelyxFileFilter) { + HelyxFileFilter model = (HelyxFileFilter) value; + ((JLabel) c).setText(model.getDescription()); + } + return c; + } + }); + filterCombo.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getSource() instanceof JComboBox && e.getStateChange() == ItemEvent.SELECTED) { + controller.applyFilter(); + } + } + }); + return filterCombo; + } + + public void resetFileFilter() { + filterCombo.setSelectedItem(HelyxFileFilter.getAllFilesFilter()); + controller.applyFilter(); + } + + public HelyxFileFilter getSelectedFilter() { + if (filterCombo != null) { + return (HelyxFileFilter) filterCombo.getSelectedItem(); + } + return null; + } + + public JButton getOkButton() { + return okButton; + } + + private class OkAction extends AbstractAction { + public OkAction() { + super(controller.isSaveAs() ? "Save" : filters != null ? "Open" : "Select"); + } + + @Override + public void actionPerformed(ActionEvent e) { + controller.closeAndReturn(ReturnValue.Approve); + } + } + + private class CancelAction extends AbstractAction { + public CancelAction() { + super("Cancel"); + } + + @Override + public void actionPerformed(ActionEvent e) { + controller.closeAndReturn(ReturnValue.Cancelled); + } + } + +} diff --git a/src/eu/engys/util/filechooser/gui/FavoritesPanel.java b/src/eu/engys/util/filechooser/gui/FavoritesPanel.java new file mode 100644 index 0000000..ff8eeee --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/FavoritesPanel.java @@ -0,0 +1,294 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.KeyStroke; +import javax.swing.SwingConstants; +import javax.swing.border.Border; +import javax.swing.border.CompoundBorder; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; + +import eu.engys.util.filechooser.actions.favorite.EditFavorite; +import eu.engys.util.filechooser.actions.favorite.OpenFavorite; +import eu.engys.util.filechooser.favorites.Favorite; +import eu.engys.util.filechooser.favorites.FavoritesUtils; +import eu.engys.util.filechooser.favorites.PopupListener; +import eu.engys.util.filechooser.favorites.list.MutableListDragListener; +import eu.engys.util.filechooser.favorites.list.MutableListDropHandler; +import eu.engys.util.filechooser.favorites.list.MutableListModel; +import eu.engys.util.filechooser.favorites.list.SelectFirstElementFocusAdapter; +import eu.engys.util.filechooser.favorites.renderer.FavoriteListCellRenderer; +import eu.engys.util.filechooser.util.VFSUtils.LocationType; +import eu.engys.util.ui.FileChooserUtils; +import eu.engys.util.ui.ResourcesUtil; + +public class FavoritesPanel extends JPanel { + + public static final String NAME = "chooser.favoritespanel"; + public static final String FAVORITES_PANEL = "favoritesPanel"; + public static final String SYSTEM_PANEL = "systemPanel"; + public static final String FAVORITES_USER_LIST = "favoritesUserList"; + public static final String FAVORITES_SYSTEM_LIST = "favoriteSystemList"; + + private static final Color BG_COLOR = new Color(250, 250, 250); + + private static final String ACTION_OPEN = "OPEN"; + private static final String ACTION_DELETE = "DELETE"; + private static final String ACTION_EDIT = "EDIT"; + + private final FileChooserController controller; + + private List userFavorites; + + private MutableListModel systemListModel; + private MutableListModel userListModel; + + public FavoritesPanel(FileChooserController controller) { + super(new GridLayout(controller.isRemote() ? 1 : 2, 1, 0, 10)); + setName(NAME); + this.controller = controller; + + layoutComponents(); + load(); + } + + + private void layoutComponents() { + addSystemLocationPanel(); + addUserFavoritesPanel(); + } + + private void load() { + loadSystemLocations(); + loadFavorites(); + } + + @SuppressWarnings("unchecked") + private void addSystemLocationPanel() { + systemListModel = new MutableListModel(); + + JList favoriteSystemList = new JList(systemListModel); + favoriteSystemList.setName(FAVORITES_SYSTEM_LIST); + favoriteSystemList.setCellRenderer(new FavoriteListCellRenderer()); + favoriteSystemList.addFocusListener(new SelectFirstElementFocusAdapter()); + + addOpenActionToList(favoriteSystemList); + addPopupMenu(favoriteSystemList, ACTION_OPEN); + + JLabel systemLocationLabel = createLabelWithIcon(FAVORITES_SYSTEMLOCATIONS, COMPUTER_ICON); + + if (!controller.isRemote()) { + JPanel systemPanel = new JPanel(new BorderLayout()); + systemPanel.setName(SYSTEM_PANEL); + systemPanel.add(systemLocationLabel, BorderLayout.NORTH); + systemPanel.add(favoriteSystemList, BorderLayout.CENTER); + JScrollPane comp = new JScrollPane(systemPanel); + add(comp); + } + } + + private void addUserFavoritesPanel() { + userListModel = createListModel(); + + JList favoritesUserList = createList(); + favoritesUserList.setName(FAVORITES_USER_LIST); + favoritesUserList.setCellRenderer(new FavoriteListCellRenderer()); + favoritesUserList.addFocusListener(new SelectFirstElementFocusAdapter()); + + addOpenActionToList(favoritesUserList); + addEditActionToList(favoritesUserList, userListModel); + addPopupMenu(favoritesUserList, ACTION_OPEN, ACTION_EDIT, ACTION_DELETE); + + JLabel userFavouritesLabel = createLabelWithIcon(FAVORITES_FAVORITES, STAR); + + JPanel favoritesPanel = new JPanel(new BorderLayout()); + favoritesPanel.setName(FAVORITES_PANEL); + favoritesPanel.add(userFavouritesLabel, BorderLayout.NORTH); + favoritesPanel.add(favoritesUserList, BorderLayout.CENTER); + + add(new JScrollPane(favoritesPanel)); + } + + private void loadSystemLocations() { + List systemLocations = FavoritesUtils.loadSystemLocations(); + for (Favorite favorite : systemLocations) { + systemListModel.add(favorite); + } + } + + private void loadFavorites() { + this.userFavorites = FavoritesUtils.loadFavorites(); + for (Favorite favorite : userFavorites) { + if (isValidFavorite(favorite.getUrl(), controller)) { + userListModel.add(favorite); + } + } + } + + private boolean isValidFavorite(String url, FileChooserController controller) { + if (controller.isRemote()) { + String host = controller.getSshParameters().getHost(); + String port = String.valueOf(controller.getSshParameters().getPort()); + String typePrefix = LocationType.sftp.toString(); + if(port.equals(FileChooserUtils.DEFAULT_SSH_PORT)){ + return url.startsWith(typePrefix + host); + } else { + return url.startsWith(typePrefix + host + ":" + port); + } + } else { + return url.startsWith(LocationType.file.toString()); + } + } + + public void addFavorite(Favorite favorite) { + userFavorites.add(favorite); + userListModel.add(favorite); + } + + @SuppressWarnings("unchecked") + private JList createList() { + final JList favoritesUserList = new JList(userListModel); + favoritesUserList.setTransferHandler(new MutableListDropHandler(favoritesUserList)); + new MutableListDragListener(favoritesUserList); + favoritesUserList.getActionMap().put(ACTION_DELETE, new AbstractAction("Delete", MINUSBUTTON) { + + @Override + public void actionPerformed(ActionEvent e) { + Favorite favorite = userListModel.getElementAt(favoritesUserList.getSelectedIndex()); + if (!Favorite.Type.USER.equals(favorite.getType())) { + return; + } + userFavorites.remove(favoritesUserList.getSelectedValue()); + userListModel.remove(favoritesUserList.getSelectedIndex()); + } + }); + InputMap favoritesListInputMap = favoritesUserList.getInputMap(JComponent.WHEN_FOCUSED); + favoritesListInputMap.put(KeyStroke.getKeyStroke("DELETE"), ACTION_DELETE); + return favoritesUserList; + } + + private MutableListModel createListModel() { + final MutableListModel favoritesUserListModel = new MutableListModel(); + favoritesUserListModel.addListDataListener(new ListDataListener() { + @Override + public void intervalAdded(ListDataEvent e) { + saveFavorites(); + } + + @Override + public void intervalRemoved(ListDataEvent e) { + saveFavorites(); + } + + @Override + public void contentsChanged(ListDataEvent e) { + saveFavorites(); + } + + protected void saveFavorites() { + FavoritesUtils.saveFavorites(userFavorites); + } + }); + return favoritesUserListModel; + } + + private JPopupMenu addPopupMenu(JList list, String... actions) { + JPopupMenu favoritesPopupMenu = new JPopupMenu(); + for (String action : actions) { + JMenuItem item = favoritesPopupMenu.add(list.getActionMap().get(action)); + item.setName(action); + } + list.addKeyListener(new PopupListener(favoritesPopupMenu)); + list.addMouseListener(new PopupListener(favoritesPopupMenu)); + return favoritesPopupMenu; + } + + private JLabel createLabelWithIcon(String text, Icon icon) { + JLabel label = new JLabel(text, icon, SwingConstants.CENTER); + Font font = label.getFont(); + label.setFont(font.deriveFont(Font.BOLD)); + Border lineBorder = BorderFactory.createMatteBorder(0, 0, 1, 0, BG_COLOR.darker()); + Border emptyBorder = BorderFactory.createEmptyBorder(2, 0, 2, 0); + CompoundBorder compoundBorder = BorderFactory.createCompoundBorder(lineBorder, emptyBorder); + + label.setBorder(compoundBorder); + return label; + } + + private void addOpenActionToList(final JList favoritesList) { + favoritesList.getActionMap().put(ACTION_OPEN, new OpenFavorite(controller, favoritesList)); + favoritesList.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + boolean isLeftButton = e.getButton() == MouseEvent.BUTTON1; + boolean isSingleClick = e.getClickCount() == 1; + if (isSingleClick && isLeftButton) { + favoritesList.getActionMap().get(ACTION_OPEN).actionPerformed(null); + } + } + }); + InputMap favoritesListInputMap = favoritesList.getInputMap(JComponent.WHEN_FOCUSED); + favoritesListInputMap.put(KeyStroke.getKeyStroke("ENTER"), ACTION_OPEN); + } + + private void addEditActionToList(JList favoritesList, MutableListModel listModel) { + favoritesList.getActionMap().put(ACTION_EDIT, new EditFavorite(controller, favoritesList, listModel)); + + InputMap favoritesListInputMap = favoritesList.getInputMap(JComponent.WHEN_FOCUSED); + favoritesListInputMap.put(KeyStroke.getKeyStroke("F2"), ACTION_EDIT); + } + + /** + * Resources + */ + + private static final String FAVORITES_SYSTEMLOCATIONS = ResourcesUtil.getString("favorites.systemLocations"); + private static final String FAVORITES_FAVORITES = ResourcesUtil.getString("favorites.favorites"); + + private static final Icon COMPUTER_ICON = ResourcesUtil.getIcon("computer"); + private static final Icon STAR = ResourcesUtil.getIcon("star"); + private static final Icon MINUSBUTTON = ResourcesUtil.getIcon("minusButton"); +} diff --git a/src/eu/engys/util/filechooser/gui/FileChooserController.java b/src/eu/engys/util/filechooser/gui/FileChooserController.java new file mode 100644 index 0000000..1dc5158 --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/FileChooserController.java @@ -0,0 +1,234 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.connection.SshParameters; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.favorites.Favorite; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.filechooser.util.TaskContext; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.ResourcesUtil; + +public class FileChooserController { + + private static final Logger logger = LoggerFactory.getLogger(FileChooserController.class); + public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY = "MultiSelectionEnabledChangedProperty"; + public static final String MULTI_SELECTION_MODE_CHANGED_PROPERTY = "SelectionModeChangedProperty"; + + private URIPanel uriPanel; + private FavoritesPanel favoritesPanel; + private FileSystemPanel fileSystemPanel; + + private TaskContext taskContext; + + private FileChooserPanel chooserPanel; + private SelectionMode selectionMode = SelectionMode.DIRS_AND_FILES; + private SshParameters sshParameters; + private boolean saveAs; + private ButtonsPanel buttonsPanel; + + public FileChooserController(SshParameters sshParameters) { + this.sshParameters = sshParameters; + } + + public void setBrowser(FileChooserPanel vfsBrowser) { + this.chooserPanel = vfsBrowser; + this.uriPanel = chooserPanel.getUriPanel(); + this.favoritesPanel = chooserPanel.getFavoritesPanel(); + this.fileSystemPanel = chooserPanel.getFileSystemPanel(); + this.buttonsPanel = chooserPanel.getButtonsPanel(); + // this.breadCrumbsPanel = chooserPanel.getBreadCrumbsPanel(); + } + + public void goToURL(final String url, boolean encoded) { + String encodedURL = encoded ? url : VFSUtils.encode(url, sshParameters); + try { + FileObject resolveFileObject = VFSUtils.resolveFileObject(encodedURL, sshParameters); + goToURL(resolveFileObject); + } catch (FileSystemException e) { + VFSUtils.showErrorMessage(chooserPanel, encodedURL, e); + } + } + + public void goToURL(final FileObject fileObject) { + try { + fileObject.refresh(); + } catch (FileSystemException e) { + logger.error("Could not refresh " + fileObject.getName().getFriendlyURI()); + } + if (taskContext != null) { + taskContext.setStop(true); + } + final FileObject[] files = VFSUtils.getFiles(chooserPanel, fileObject); + taskContext = new TaskContext(BROWSER_CHECKINGSFTPLINKSTASK, files.length); + taskContext.setIndeterminate(false); + VFSUtils.checkForSftpLinks(files, taskContext); + taskContext.setStop(true); + + ExecUtil.invokeLater(new Runnable() { + + @Override + public void run() { + FileObject[] fileObjectsWithParent = files; + if (fileSystemPanel != null) { + fileSystemPanel.setContent(fileObjectsWithParent); + } + if (uriPanel != null) { + uriPanel.setFileObject(fileObject); + } + if (fileSystemPanel != null) { + fileSystemPanel.resetFilter(); + } + } + }); + updateOkButton(); + } + + public void addFavorite(Favorite favorite) { + favoritesPanel.addFavorite(favorite); + } + + public FileObject getSelectedFileObject() { + FileObject[] fos = getSelectedFileObjects(); + if (fos != null && fos.length > 0) { + return fos[0]; + } else { + return null; + } + } + + public FileObject[] getSelectedFileObjects() { + return chooserPanel.getSelectedFileObjects(); + } + + public FileSystemPanel getFileSystemPanel() { + return fileSystemPanel; + } + + public void resetFileFilter() { + buttonsPanel.resetFileFilter(); + } + + public URIPanel getUriPanel() { + return uriPanel; + } + + public static Throwable getRootCause(Throwable t) { + while (t.getCause() != null) { + t = t.getCause(); + } + return t; + } + + public void applyFilter() { + HelyxFileFilter filter = buttonsPanel.getSelectedFilter(); + if (filter != null) { + fileSystemPanel.applyFilter(filter); + } + } + + public SelectionMode getSelectionMode() { + return selectionMode; + } + + public void setSelectionMode(SelectionMode mode) { + this.selectionMode = mode; + } + + public void showTable() { + if (chooserPanel != null) { + chooserPanel.showTable(); + } + } + + public void showLoading() { + if (chooserPanel != null) { + chooserPanel.showLoading(); + } + } + + public void updateNewFileName() { + uriPanel.updateFileName(); + } + + public void updateOkButton() { + buttonsPanel.updateOkButton(); + } + + public void closeAndReturn(ReturnValue retVal) { + chooserPanel.closeAndReturn(retVal); + } + + public HelyxFileFilter getFilter() { + return buttonsPanel.getSelectedFilter(); + } + + public void fixSelection() { + // fileSystemPanel.fixSelection(); + } + + public SshParameters getSshParameters() { + return sshParameters; + } + + public boolean isRemote() { + return getSshParameters() != null; + } + + public boolean isSaveAs() { + return saveAs; + } + + public void setSaveAs(boolean saveAs) { + this.saveAs = saveAs; + } + + /* + * For tests purposes only + */ + public void setFavoritesPanel(FavoritesPanel favoritesPanel) { + this.favoritesPanel = favoritesPanel; + } + + public void setUriPanel(URIPanel uriPanel) { + this.uriPanel = uriPanel; + } + + /* + * Resources + */ + + private static final String BROWSER_CHECKINGSFTPLINKSTASK = ResourcesUtil.getString("browser.checkingSFtpLinksTask"); + +} diff --git a/src/eu/engys/util/filechooser/gui/FileChooserPanel.java b/src/eu/engys/util/filechooser/gui/FileChooserPanel.java new file mode 100644 index 0000000..eda5b10 --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/FileChooserPanel.java @@ -0,0 +1,337 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.gui; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.io.File; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.cache.SoftRefFilesCache; +import org.apache.log4j.Level; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.connection.SshParameters; +import eu.engys.util.filechooser.AbstractFileChooser; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.authentication.MemoryAuthStore; +import eu.engys.util.filechooser.authentication.UserAuthenticatorFactory; +import eu.engys.util.filechooser.authentication.authenticator.UseCentralsFromSessionUserAuthenticator; +import eu.engys.util.filechooser.util.EngysFileSystemManager; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ExecUtil; + +public class FileChooserPanel extends JPanel { + + private static final Logger logger = LoggerFactory.getLogger(FileChooserPanel.class); + public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY = "MultiSelectionEnabledChangedProperty"; + public static final String MULTI_SELECTION_MODE_CHANGED_PROPERTY = "SelectionModeChangedProperty"; + + private static final String TABLE_KEY = "TABLE"; + private static final String LOADING_KEY = "LOADING"; + + private CardLayout cardLayout; + + private JPanel cardLayoutPanel; + private URIPanel uriPanel; + private FileSystemPanel fileSystemPanel; + private FavoritesPanel favoritesPanel; + private LoadingPanel loadingPanel; + private ButtonsPanel buttonsPanel; + + private FileChooserController controller; + private final AbstractFileChooser chooser; + + private Accessory accessory; + private Options options; + private SshParameters sshParameters; + private HelyxFileFilter[] filters; + private boolean enableSaveAs; + private File fileToSelect; + + FileChooserPanel(AbstractFileChooser chooser, Accessory accessory, Options options, SshParameters sshParameters, boolean enableSaveAs, HelyxFileFilter... filters) { + super(new BorderLayout()); + setName("filechooser.panel"); + this.chooser = chooser; + this.accessory = accessory; + this.options = options; + this.sshParameters = sshParameters; + this.enableSaveAs = enableSaveAs; + this.filters = filters; + + setLogLevelToWarning(SoftRefFilesCache.class); + setLogLevelToWarning(EngysFileSystemManager.class); + setLogLevelToWarning(MemoryAuthStore.class); + setLogLevelToWarning(UseCentralsFromSessionUserAuthenticator.class); + setLogLevelToWarning(UserAuthenticatorFactory.class); + } + + public void layoutComponents() { + this.controller = new FileChooserController(sshParameters); + this.controller.setSaveAs(enableSaveAs); + this.uriPanel = new URIPanel(controller); + this.favoritesPanel = new FavoritesPanel(controller); + this.fileSystemPanel = new FileSystemPanel(controller, accessory); + this.loadingPanel = new LoadingPanel(); + this.buttonsPanel = new ButtonsPanel(controller, filters); + this.controller.setBrowser(this); + + this.cardLayoutPanel = new JPanel(cardLayout = new CardLayout()); + cardLayoutPanel.add(new JScrollPane(loadingPanel), LOADING_KEY); + + if (accessory != null) { + JSplitPane fileSystemAndPreviewPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, fileSystemPanel, accessory.getPanel()); + fileSystemAndPreviewPane.setOneTouchExpandable(false); + fileSystemAndPreviewPane.setDividerLocation(450); + cardLayoutPanel.add(fileSystemAndPreviewPane, TABLE_KEY); + } else { + cardLayoutPanel.add(fileSystemPanel, TABLE_KEY); + } + + JPanel centralPanel = new JPanel(new BorderLayout()); + centralPanel.add(cardLayoutPanel, BorderLayout.CENTER); + + if (options != null) { + centralPanel.add(options.getPanel(), BorderLayout.SOUTH); + } + + JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, favoritesPanel, centralPanel); + mainSplitPane.setOneTouchExpandable(false); + mainSplitPane.setDividerLocation(180); + + JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); + mainPanel.add(uriPanel, BorderLayout.NORTH); + mainPanel.add(mainSplitPane, BorderLayout.CENTER); + mainPanel.add(buttonsPanel, BorderLayout.SOUTH); + mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + add(mainPanel, BorderLayout.CENTER); + } + + public void initialize(final String initialPath) { + new Thread(new Runnable() { + @Override + public void run() { + showLoading(); + initializeInAThread(initialPath); + } + }).start(); + } + + private void initializeInAThread(final String initialPath) { + try { + boolean thereIsAValidFileToSelect = fileToSelect != null && fileToSelect.getParent() != null; + if (thereIsAValidFileToSelect) { + goToURL(fileToSelect.getParent()); + } else { + goToURL(initialPath); + } + + showTable(); + + controller.applyFilter(); + + if (thereIsAValidFileToSelect) { + selectFileOnTable(); + } + + } catch (FileSystemException e1) { + logger.error("Can't initialize default location", e1.getMessage()); + } + } + + private void goToURL(final String initialPath) throws FileSystemException { + if (initialPath != null && !initialPath.isEmpty()) { + controller.goToURL(initialPath, false); + } else { + if (controller.isRemote()) { + controller.goToURL(VFSUtils.getRemoteUserHome(sshParameters), false); + } else { + controller.goToURL(VFSUtils.getUserHome()); + } + } + } + + private void selectFileOnTable() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + fileSystemPanel.selectFileByName(fileToSelect.getName()); + } + }); + } + + public void showTable() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + loadingPanel.stop(); + fileSystemPanel.resetScroll(); + cardLayout.show(cardLayoutPanel, TABLE_KEY); + } + }); + } + + public void showLoading() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + cardLayout.show(cardLayoutPanel, LOADING_KEY); + loadingPanel.start(); + } + }); + } + + // Called from outside + public FileObject[] getFileObjects() { + if (controller.isSaveAs()) { + FileObject[] fos = new FileObject[1]; + try { + String newFileName = uriPanel.getNewFileName(); + boolean hasFilter = controller.getFilter() != null && !controller.getFilter().isAllFilesFilter(); + if (hasFilter) { + newFileName = fixFileExtension(newFileName); + } + fos[0] = uriPanel.getFileObject().resolveFile(newFileName); + return fos; + } catch (FileSystemException e) { + return null; + } + } else { + FileObject[] selectedFileObjects = getSelectedFileObjects(); + if (selectedFileObjects == null) { + selectedFileObjects = new FileObject[] { uriPanel.getFileObject() }; + } + return selectedFileObjects; + } + } + + private String fixFileExtension(String newFileName) { + String extension = FilenameUtils.getExtension(newFileName); + if (!controller.getFilter().isValidExtension(extension)) { + return newFileName += "." + controller.getFilter().getExtensions()[0]; + } + return newFileName; + } + + FileObject[] getSelectedFileObjects() { + FileObject[] selectedFileObjects = fileSystemPanel.getSelectedFileObjects(); + if (selectedFileObjects != null && selectedFileObjects.length > 0) { + return selectedFileObjects; + } else { + return null; + } + } + + public static void setLogLevelToWarning(Class klass) { + org.apache.log4j.Logger.getLogger(klass).setLevel(Level.WARN); + } + + public void setSelectionMode(SelectionMode selectionMode) { + controller.setSelectionMode(selectionMode); + } + + public void setMultiSelectionEnabled(boolean b) { + fileSystemPanel.setMultiSelection(b); + } + + public void setSelectedFile(File fileToSelect) { + this.fileToSelect = fileToSelect; + } + + public FileChooserController getController() { + return controller; + } + + public URIPanel getUriPanel() { + return uriPanel; + } + + public FavoritesPanel getFavoritesPanel() { + return favoritesPanel; + } + + public ButtonsPanel getButtonsPanel() { + return buttonsPanel; + } + + public FileSystemPanel getFileSystemPanel() { + return fileSystemPanel; + } + + public LoadingPanel getLoadingPanel() { + return loadingPanel; + } + + public ButtonsPanel getStatusPanel() { + return buttonsPanel; + } + + public JButton getOkButton() { + return buttonsPanel.getOkButton(); + } + + public HelyxFileFilter getSelectedFilter() { + return buttonsPanel.getSelectedFilter(); + } + + public Accessory getAccessory() { + return accessory; + } + + public void closeAndReturn(ReturnValue retVal) { + chooser.setReturnValue(retVal); + chooser.disposeDialog(); + } + +} diff --git a/src/eu/engys/util/filechooser/gui/FileSystemPanel.java b/src/eu/engys/util/filechooser/gui/FileSystemPanel.java new file mode 100644 index 0000000..3d72b65 --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/FileSystemPanel.java @@ -0,0 +1,416 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.swing.ActionMap; +import javax.swing.BorderFactory; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JToolBar; +import javax.swing.KeyStroke; +import javax.swing.ListSelectionModel; +import javax.swing.RowSorter; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.RowSorterEvent; +import javax.swing.event.RowSorterListener; +import javax.swing.table.TableColumnModel; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileType; + +import eu.engys.util.ArchiveUtils; +import eu.engys.util.filechooser.actions.DeleteFileAction; +import eu.engys.util.filechooser.actions.ExtractArchiveAction; +import eu.engys.util.filechooser.actions.NewFolderAction; +import eu.engys.util.filechooser.actions.pathnavigation.BaseNavigateActionGoUp; +import eu.engys.util.filechooser.actions.pathnavigation.BaseNavigateActionOpen; +import eu.engys.util.filechooser.actions.pathnavigation.BaseNavigateActionRefresh; +import eu.engys.util.filechooser.table.FileNameWithType; +import eu.engys.util.filechooser.table.FileNameWithTypeComparator; +import eu.engys.util.filechooser.table.FileSize; +import eu.engys.util.filechooser.table.FileSystemTableModel; +import eu.engys.util.filechooser.table.QuickSearchKeyAdapter; +import eu.engys.util.filechooser.table.renderer.FileNameWithTypeTableCellRenderer; +import eu.engys.util.filechooser.table.renderer.FileSizeTableCellRenderer; +import eu.engys.util.filechooser.table.renderer.FileTypeTableCellRenderer; +import eu.engys.util.filechooser.table.renderer.MixedDateTableCellRenderer; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.textfields.PromptTextField; +import eu.engys.util.ui.treetable.TableFilter; + +public class FileSystemPanel extends JPanel { + + private static final String ACTION_OPEN = "OPEN"; + private static final String ACTION_GO_UP = "GO_UP"; + private static final String ACTION_REFRESH = "REFRESH"; + private static final String ACTION_DELETE = "DELETE"; + private static final String ACTION_APPROVE = "ACTION APPROVE"; + + public static final String NAME = "chooser.filesystempanel"; + public static final String CREATE_FOLDER = "create.folder"; + public static final String DELETE_FILE = "delete.file"; + public static final String EXTRACT_ARCHIVE = "extract.archive"; + + private JTable table; + private FileChooserController controller; + private JScrollPane scrollPane; + private HelyxFileFilter appliedFilter; + private final Accessory accessory; + private TableFilter tableFilter; + private TableRowSorter sorter; + private JTextField searchField; + + public FileSystemPanel(FileChooserController controller, Accessory accessory) { + super(new BorderLayout(0, 5)); + setName(NAME); + this.controller = controller; + this.accessory = accessory; + this.appliedFilter = HelyxFileFilter.getAllFilesFilter(); + layoutComponents(); + } + + private void layoutComponents() { + createTable(); + scrollPane = new JScrollPane(table); + scrollPane.setPreferredSize(new Dimension(scrollPane.getPreferredSize().width, 300)); + add(createFileSystemBar(), BorderLayout.NORTH); + add(scrollPane, BorderLayout.CENTER); + } + + private void createTable() { + FileSystemTableModel model = new FileSystemTableModel(); + this.table = new JTable(model); + populateActionMap(); + populateInputMap(); + setColumnSize(); + + sorter = createSorter(); + table.setRowSorter(sorter); + + tableFilter = new TableFilter(""); + tableFilter.setColumnsWhereToSearch(0); + sorter.setRowFilter(tableFilter); + + table.setFillsViewportHeight(true); + table.setShowGrid(false); + table.setColumnSelectionAllowed(false); + + setRenderer(); + addListeners(); + } + + private JComponent createFileSystemBar() { + JButton createFolderButton = new JButton(new NewFolderAction(controller)); + createFolderButton.setName(CREATE_FOLDER); + + JButton deleteFileButton = new JButton(new DeleteFileAction(controller)); + deleteFileButton.setName(DELETE_FILE); + + JButton extractArchiveButton = new JButton(new ExtractArchiveAction(controller)); + extractArchiveButton.setName(EXTRACT_ARCHIVE); + + JToolBar bar = UiUtil.getToolbar("filesystem.toolbar"); + bar.add(searchField = createSearchField()); + bar.add(createFolderButton); + bar.add(deleteFileButton); + bar.add(extractArchiveButton); + + bar.setBorder(BorderFactory.createEmptyBorder()); + + return bar; + } + + private JTextField createSearchField() { + final PromptTextField filterField = new PromptTextField(); + filterField.setPrompt("Search (* = any string, ? = any character)"); + filterField.getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void removeUpdate(DocumentEvent e) { + filter(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + filter(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + filter(); + } + + }); + return filterField; + } + + private void filter() { + tableFilter.setFilterText(searchField.getText()); + sorter.sort(); + } + + public void resetFilter() { + searchField.setText(""); + filter(); + } + + private void setColumnSize() { + TableColumnModel columnModel = table.getColumnModel(); + columnModel.getColumn(0).setMinWidth(140); + columnModel.getColumn(1).setMaxWidth(80); + columnModel.getColumn(2).setMaxWidth(80); + columnModel.getColumn(3).setMaxWidth(180); + columnModel.getColumn(3).setMinWidth(120); + } + + private void setRenderer() { + table.setDefaultRenderer(FileSize.class, new FileSizeTableCellRenderer()); + table.setDefaultRenderer(FileNameWithType.class, new FileNameWithTypeTableCellRenderer()); + table.setDefaultRenderer(Date.class, new MixedDateTableCellRenderer()); + table.setDefaultRenderer(FileType.class, new FileTypeTableCellRenderer()); + } + + private void addListeners() { + addMouseListener(); + addSelectionListener(); + addKeyListener(); + addAccessoryListener(); + } + + private void addMouseListener() { + table.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + boolean isLeftButton = e.getButton() == MouseEvent.BUTTON1; + boolean isDoubleClick = e.getClickCount() == 2; + boolean isSomethingSelected = table.getSelectedRows().length > 0; + if (isLeftButton && isDoubleClick && isSomethingSelected) { + table.getActionMap().get(ACTION_OPEN).actionPerformed(null); + } + } + }); + } + + private void addKeyListener() { + table.addKeyListener(new QuickSearchKeyAdapter(table)); + } + + private void addSelectionListener() { + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + + @Override + public void valueChanged(ListSelectionEvent e) { + controller.updateNewFileName(); + controller.updateOkButton(); + } + }); + } + + private void addAccessoryListener() { + if (accessory != null) { + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + + @Override + public void valueChanged(ListSelectionEvent e) { + accessory.onSelectionChanged(); + } + }); + } + } + + private void populateInputMap() { + InputMap inputMap = table.getInputMap(JComponent.WHEN_FOCUSED); + inputMap.put(KeyStroke.getKeyStroke("ENTER"), ACTION_OPEN); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_MASK), ACTION_APPROVE); + + inputMap.put(KeyStroke.getKeyStroke("BACK_SPACE"), ACTION_GO_UP); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0), ACTION_GO_UP); + + inputMap.put(KeyStroke.getKeyStroke("F5"), ACTION_REFRESH); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0), ACTION_REFRESH); + + inputMap.put(KeyStroke.getKeyStroke("DELETE"), ACTION_DELETE); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_CANCEL, 0), ACTION_DELETE); + + } + + private void populateActionMap() { + ActionMap actionMap = table.getActionMap(); + actionMap.put(ACTION_OPEN, new BaseNavigateActionOpen(controller)); + actionMap.put(ACTION_GO_UP, new BaseNavigateActionGoUp(controller)); + actionMap.put(ACTION_REFRESH, new BaseNavigateActionRefresh(controller)); + actionMap.put(ACTION_DELETE, new DeleteFileAction(controller)); + } + + public FileObject getSelectedFileObject() { + int selectedRow = table.getSelectedRow(); + if (selectedRow > -1) { + int convertedRowIndex = table.convertRowIndexToModel(selectedRow); + return ((FileSystemTableModel) table.getModel()).get(convertedRowIndex); + } + return null; + } + + public FileObject[] getSelectedFileObjects() { + int[] selectedRows = table.getSelectedRows(); + FileObject[] fileObjects = new FileObject[selectedRows.length]; + for (int i = 0; i < selectedRows.length; i++) { + fileObjects[i] = ((FileSystemTableModel) table.getModel()).get(table.convertRowIndexToModel(selectedRows[i])); + } + return fileObjects; + } + + public void applyFilter(HelyxFileFilter selectedFilter) { + this.appliedFilter = selectedFilter; + if (controller.getUriPanel().getFileObject() != null) { + controller.goToURL(controller.getUriPanel().getFileObject()); + } + } + + public void setContent(FileObject[] fileObjects) { + try { + _setContent(fileObjects); + table.clearSelection(); + } catch (FileSystemException e) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), e.getMessage(), "File Chooser Error", JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + } + } + + private void _setContent(FileObject[] fileObjectsWithParent) throws FileSystemException { + List filteredObjects = new ArrayList<>(); + for (FileObject fileObject : fileObjectsWithParent) { + if (!VFSUtils.isHiddenFile(fileObject)) { + if (fileObject.getType() == FileType.FILE) { + manageFiles(filteredObjects, fileObject); + } else if (fileObject.getType() == FileType.FOLDER) { + filteredObjects.add(fileObject); + } + } + + } + ((FileSystemTableModel) table.getModel()).setContent(filteredObjects.toArray(new FileObject[0])); + } + + private void manageFiles(List filteredObjects, FileObject fileObject) throws FileSystemException { + boolean showOnlyFolders = controller.getSelectionMode().isDirsOnly(); + boolean showOnlyFoldersAndArchives = controller.getSelectionMode().isDirsAndArchives(); + if (showOnlyFolders) { + return; + } else { + if (showOnlyFoldersAndArchives) { + File file = new File(VFSUtils.decode(fileObject.getName().getURI(), controller.getSshParameters())); + if (ArchiveUtils.isArchive(file)) { + filteredObjects.add(fileObject); + } + } else { + filter(filteredObjects, fileObject); + } + } + } + + private void filter(List filteredObjects, FileObject fileObject) { + String fileName = fileObject.getName().getBaseName(); + String fileExtension = fileObject.getName().getExtension(); + for (String ext : appliedFilter.getExtensions()) { + boolean filterIsAllFiles = ext.equals("*"); + boolean extensionMatchesExtension = fileExtension.equalsIgnoreCase(ext); + boolean extensionMatchesName = fileExtension.isEmpty() && fileName.equalsIgnoreCase(ext); + + if (filterIsAllFiles || extensionMatchesExtension || extensionMatchesName) { + filteredObjects.add(fileObject); + } + } + } + + public void resetScroll() { + scrollPane.getVerticalScrollBar().setValue(0); + } + + private TableRowSorter createSorter() { + TableRowSorter sorter = new TableRowSorter(table.getModel()); + final FileNameWithTypeComparator fileNameWithTypeComparator = new FileNameWithTypeComparator(); + sorter.addRowSorterListener(new RowSorterListener() { + @SuppressWarnings("unchecked") + @Override + public void sorterChanged(RowSorterEvent e) { + RowSorterEvent.Type type = e.getType(); + if (type.equals(RowSorterEvent.Type.SORT_ORDER_CHANGED)) { + List sortKeys = e.getSource().getSortKeys(); + for (RowSorter.SortKey sortKey : sortKeys) { + if (sortKey.getColumn() == FileSystemTableModel.COLUMN_NAME) { + fileNameWithTypeComparator.setSortOrder(sortKey.getSortOrder()); + } + } + } + } + }); + sorter.setComparator(FileSystemTableModel.COLUMN_NAME, fileNameWithTypeComparator); + return sorter; + } + + public void setMultiSelection(boolean b) { + int selectionMode = b ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : ListSelectionModel.SINGLE_SELECTION; + table.getSelectionModel().setSelectionMode(selectionMode); + } + + public void selectFileByName(String selectedFileName) { + if (selectedFileName != null) { + FileSystemTableModel model = (FileSystemTableModel) table.getModel(); + int index = model.getIndexByName(selectedFileName); + if (index != -1) { + table.getSelectionModel().setSelectionInterval(index, index); + table.scrollRectToVisible(table.getCellRect(index, 0, false)); + } + } + + } + +} diff --git a/src/eu/engys/util/filechooser/gui/LoadingPanel.java b/src/eu/engys/util/filechooser/gui/LoadingPanel.java new file mode 100644 index 0000000..e74547a --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/LoadingPanel.java @@ -0,0 +1,94 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.util.Timer; +import java.util.TimerTask; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +import eu.engys.util.ui.ExecUtil; + +public class LoadingPanel extends JPanel { + + private static final String LOADING = "Loading..."; + private static final String LOADING_FULL = "Loading.............."; + private JLabel loadingLabel; + private Timer timer; + + public LoadingPanel() { + super(new BorderLayout()); + setName("chooser.loadingpanel"); + setOpaque(true); + setBackground(Color.WHITE); + layoutComponents(); + } + + private void layoutComponents() { + loadingLabel = new JLabel(LOADING); + loadingLabel.setForeground(Color.LIGHT_GRAY); + loadingLabel.setFont(new Font("Monotype Corsiva", 1, 28)); + add(loadingLabel); + } + + public void start() { + timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + updateLabel(); + } + + }, 0, 800); + } + + private void updateLabel() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + String current = loadingLabel.getText(); + if (LOADING_FULL.equals(current)) { + loadingLabel.setText(LOADING); + } else { + loadingLabel.setText(current + "."); + } + } + }); + } + + public void stop() { + if (timer != null) { + timer.cancel(); + timer = null; + } + loadingLabel.setText(LOADING); + } + +} diff --git a/src/eu/engys/util/filechooser/gui/Options.java b/src/eu/engys/util/filechooser/gui/Options.java new file mode 100644 index 0000000..fd69107 --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/Options.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import javax.swing.JPanel; + +public interface Options { + + void onSelectionChanged(); + + JPanel getPanel(); + +} diff --git a/src/eu/engys/util/filechooser/gui/URIPanel.java b/src/eu/engys/util/filechooser/gui/URIPanel.java new file mode 100644 index 0000000..d53fc7f --- /dev/null +++ b/src/eu/engys/util/filechooser/gui/URIPanel.java @@ -0,0 +1,219 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.gui; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +import javax.swing.AbstractAction; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.JToolBar; +import javax.swing.KeyStroke; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import net.java.dev.designgridlayout.Componentizer; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.filechooser.actions.favorite.AddFavorite; +import eu.engys.util.filechooser.actions.pathnavigation.BaseNavigateAction; +import eu.engys.util.filechooser.actions.pathnavigation.BaseNavigateActionGoUp; +import eu.engys.util.filechooser.actions.pathnavigation.BaseNavigateActionRefresh; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.builder.PanelBuilder; + +public class URIPanel extends JPanel { + + private static final Logger LOGGER = LoggerFactory.getLogger(URIPanel.class); + + public static final String NAME = "chooser.uripanel"; + public static final String NAME_LABEL = "Name:"; + public static final String LOOK_IN = "Look in:"; + public static final String SAVE_IN = "Save in:"; + private static final String ACTION_FOCUS_ON_TABLE = "FOCUS ON TABLE"; + + public static final String ADD_FAVORITE = "add.favorite"; + public static final String UP_FOLDER = "up.folder"; + public static final String REFRESH = "refresh"; + + private JTextField pathField; + + private FileChooserController controller; + private FileObject fileObject; + private JTextField newFileNameField; + private BreadCrumbsPanel breadCrumbs; + + public URIPanel(FileChooserController controller) { + super(new BorderLayout()); + setName(NAME); + this.controller = controller; + layoutComponents(); + } + + private void layoutComponents() { + pathField = createPathField(); + breadCrumbs = new BreadCrumbsPanel(controller); + + PanelBuilder pb = new PanelBuilder(); + + String pathLabel = controller.isSaveAs() ? SAVE_IN : LOOK_IN; + pb.addComponent(pathLabel, Componentizer.create().prefAndMore(pathField).minToPref(createURIActionsBar()).component()); + pathField.setName(pathLabel); + + if (controller.isSaveAs()) { + newFileNameField = new JTextField(15); + newFileNameField.getDocument().addDocumentListener(new NotEmptyListener()); + newFileNameField.setText(""); + pb.addComponent(NAME_LABEL, newFileNameField); + } + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(pb.removeMargins().getPanel(), BorderLayout.NORTH); + panel.add(breadCrumbs, BorderLayout.CENTER); + + add(panel, BorderLayout.CENTER); + } + + public String getNewFileName() { + return newFileNameField == null ? null : newFileNameField.getText(); + } + + private JTextField createPathField() { + final JTextField field = new JTextField(30); + field.setToolTipText(NAV_PATHTOOLTIP); + + InputMap inputMapPath = field.getInputMap(JComponent.WHEN_FOCUSED); + inputMapPath.put(KeyStroke.getKeyStroke("ENTER"), "OPEN_PATH"); + inputMapPath.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), ACTION_FOCUS_ON_TABLE); + + field.getActionMap().put("OPEN_PATH", new BaseNavigateAction(controller) { + + @Override + protected void performLongOperation(CheckBeforeActionResult actionResult) { + controller.goToURL(field.getText().trim(), false); + controller.updateOkButton(); + } + + @Override + protected boolean canGoUrl() { + return true; + } + + @Override + protected boolean canExecuteDefaultAction() { + return false; + } + + }); + + field.getActionMap().put(ACTION_FOCUS_ON_TABLE, new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + controller.fixSelection(); + } + }); + return field; + } + + private JComponent createURIActionsBar() { + JButton goUpButton = new JButton(new BaseNavigateActionGoUp(controller)); + goUpButton.setName(UP_FOLDER); + + JButton refreshButton = new JButton(new BaseNavigateActionRefresh(controller)); + refreshButton.setName(REFRESH); + + JButton addCurrentLocationToFavoriteButton = new JButton(new AddFavorite(controller)); + addCurrentLocationToFavoriteButton.setName(ADD_FAVORITE); + addCurrentLocationToFavoriteButton.setText(""); + + JToolBar bar = UiUtil.getToolbar("uri.panel.toolbar"); + + bar.add(goUpButton); + bar.add(refreshButton); + bar.add(addCurrentLocationToFavoriteButton); + + return bar; + } + + public void setFileObject(FileObject fileObject) { + try { + this.fileObject = fileObject; + pathField.setText(VFSUtils.decode(fileObject.getURL().toString(), controller.getSshParameters())); + breadCrumbs.updatePanel(fileObject); + } catch (FileSystemException e) { + LOGGER.error("Can't get URL", e); + } + } + + public void updateFileName() { + FileObject fo = controller.getSelectedFileObject(); + if (controller.isSaveAs() && fo != null) { + newFileNameField.setText(fo.getName().getBaseName()); + } + } + + public FileObject getFileObject() { + return fileObject; + } + + private class NotEmptyListener implements DocumentListener { + @Override + public void removeUpdate(DocumentEvent e) { + checkNotEmpty(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + checkNotEmpty(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + checkNotEmpty(); + } + + private void checkNotEmpty() { + controller.updateOkButton(); + } + } + + /** + * Resources + */ + + private static final String NAV_PATHTOOLTIP = ResourcesUtil.getString("nav.pathTooltip"); +} diff --git a/src/eu/engys/util/filechooser/table/FileNameWithType.java b/src/eu/engys/util/filechooser/table/FileNameWithType.java new file mode 100644 index 0000000..7ccc1f9 --- /dev/null +++ b/src/eu/engys/util/filechooser/table/FileNameWithType.java @@ -0,0 +1,79 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table; + +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileType; + +public class FileNameWithType { + + private FileName fileName; + private FileType fileType; + + public FileNameWithType(FileName fileName, FileType fileType) { + super(); + this.fileName = fileName; + this.fileType = fileType; + } + + public FileName getFileName() { + return fileName; + } + + public void setFileName(FileName fileName) { + this.fileName = fileName; + } + + public FileType getFileType() { + return fileType; + } + + public void setFileType(FileType fileType) { + this.fileType = fileType; + } + + @Override + public String toString() { + return fileName.getBaseName(); + } + +} diff --git a/src/eu/engys/util/filechooser/table/FileNameWithTypeComparator.java b/src/eu/engys/util/filechooser/table/FileNameWithTypeComparator.java new file mode 100644 index 0000000..ec78b8b --- /dev/null +++ b/src/eu/engys/util/filechooser/table/FileNameWithTypeComparator.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table; + +import java.util.Comparator; + +import javax.swing.SortOrder; + +import org.apache.commons.vfs2.FileType; + +import eu.engys.util.filechooser.ParentFileObject; + +public class FileNameWithTypeComparator implements Comparator { + private SortOrder sortOrder = SortOrder.ASCENDING; + + @Override + public int compare(FileNameWithType o1, FileNameWithType o2) { + return compareTo(o1, o2); + } + + public int compareTo(FileNameWithType o1, FileNameWithType o2) { + if (o1 == null || o1.getFileType() == null || o1.getFileName() == null) { + return -1; + } + if (o2 == null || o2.getFileType() == null || o2.getFileName() == null) { + return 1; + } + // folders first first + boolean folder1 = FileType.FOLDER.equals(o1.getFileType()); + boolean folder2 = FileType.FOLDER.equals(o2.getFileType()); + int result = 0; + + int sortOrderSign = SortOrder.ASCENDING.equals(sortOrder) ? 1 : -1; + String o1BaseName = o1.getFileName().getBaseName(); + String o2BaseName = o2.getFileName().getBaseName(); + + if (o1BaseName.equalsIgnoreCase(ParentFileObject.PARENT_NAME)) { + result = -1 * sortOrderSign; + } else { + if (o2BaseName.equalsIgnoreCase(ParentFileObject.PARENT_NAME)) { + result = 1 * sortOrderSign; + } else if (folder1 & !folder2) { + result = -1 * sortOrderSign; + } else if (!folder1 & folder2) { + result = 1 * sortOrderSign; + } else { + result = o1BaseName.compareToIgnoreCase(o2BaseName); + } + } + + return result; + } + + public void setSortOrder(SortOrder sortOrder) { + this.sortOrder = sortOrder; + } +} diff --git a/src/eu/engys/util/filechooser/table/FileObjectComparator.java b/src/eu/engys/util/filechooser/table/FileObjectComparator.java new file mode 100644 index 0000000..bb59ed0 --- /dev/null +++ b/src/eu/engys/util/filechooser/table/FileObjectComparator.java @@ -0,0 +1,78 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table; + +import java.util.Comparator; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileObjectComparator implements Comparator { + + private static final Logger LOGGER = LoggerFactory.getLogger(FileObjectComparator.class); + private FileNameWithTypeComparator fileNameWithTypeComparator = new FileNameWithTypeComparator(); + + @Override + public int compare(FileObject o1, FileObject o2) { + if (o1 != null && o2 != null) { + try { + return fileNameWithTypeComparator.compare(new FileNameWithType(o1.getName(), o1.getType()), new FileNameWithType(o2.getName(), o2.getType())); + } catch (FileSystemException e) { + return 0; + } + } + return 0; + } + + private int compareTypes(FileType type1, FileType type2) { + if (type1.equals(FileType.FILE) && !type2.equals(FileType.FILE)) { + return 1; + } else if (!type1.equals(FileType.FILE) && type2.equals(FileType.FILE)) { + return -1; + } + return 0; + } + +} diff --git a/src/eu/engys/util/filechooser/table/FileSize.java b/src/eu/engys/util/filechooser/table/FileSize.java new file mode 100644 index 0000000..cd80ac7 --- /dev/null +++ b/src/eu/engys/util/filechooser/table/FileSize.java @@ -0,0 +1,166 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table; + +import java.text.DecimalFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; + +public class FileSize implements Comparable { + + private static final long K = 1024; + private static final long M = K * K; + private static final long G = M * K; + private static final long T = G * K; + + private long bytes; + + public FileSize(String string) { + Pattern p = Pattern.compile("([\\d,.]+)\\s?([kKmMgGtT]{1})[Bb]{1}"); + Matcher matcher = p.matcher(string); + if (matcher.matches()) { + double count = Double.parseDouble(matcher.group(1).replace(',', '.')); + long multiplier = 1; + if (StringUtils.isNotBlank(matcher.group(2))) { + multiplier = getMultiplier(matcher.group(2).charAt(0)); + } + bytes = (long) (count * multiplier); + } + } + + public FileSize(long bytes) { + super(); + this.bytes = bytes; + } + + public long getBytes() { + return bytes; + } + + public void setBytes(long bytes) { + this.bytes = bytes; + } + + @Override + public String toString() { + return convertToStringRepresentation(bytes); + } + + public long getMultiplier(char multiplierChar) { + long multiplier = 1; + multiplierChar = Character.toLowerCase(multiplierChar); + switch (multiplierChar) { + case 't': + multiplier = multiplier * 1024; + case 'g': + multiplier = multiplier * 1024; + case 'm': + multiplier = multiplier * 1024; + case 'k': + multiplier = multiplier * 1024; + break; + } + return multiplier; + } + + public static String convertToStringRepresentation(final long value) { + final long[] dividers = new long[] { T, G, M, K, 1 }; + final String[] units = new String[] { "TB", "GB", "MB", "KB", "B" }; + if (value == 0) { + return format(0, 1, "B"); + } else if (value < 1) { + return "Folder"; + } + String result = null; + for (int i = 0; i < dividers.length; i++) { + final long divider = dividers[i]; + if (value >= divider) { + result = format(value, divider, units[i]); + break; + } + } + return result; + } + + private static String format(final long value, final long divider, final String unit) { + final double result = divider > 1 ? (double) value / (double) divider : (double) value; + DecimalFormat decimalFormat = new DecimalFormat(); + decimalFormat.setMaximumFractionDigits(1); + decimalFormat.setMinimumFractionDigits(0); + decimalFormat.setGroupingUsed(false); + decimalFormat.setDecimalSeparatorAlwaysShown(false); + return decimalFormat.format(result) + " " + unit; + } + + @Override + public int compareTo(FileSize o) { + int result; + if (o == null || bytes > o.bytes) { + result = 1; + } else if (bytes < o.bytes) { + result = -1; + } else { + result = 0; + } + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + FileSize fileSize = (FileSize) o; + + return bytes == fileSize.bytes; + + } + + @Override + public int hashCode() { + return (int) (bytes ^ (bytes >>> 32)); + } +} diff --git a/src/eu/engys/util/filechooser/table/FileSystemTableModel.java b/src/eu/engys/util/filechooser/table/FileSystemTableModel.java new file mode 100644 index 0000000..d7d9e64 --- /dev/null +++ b/src/eu/engys/util/filechooser/table/FileSystemTableModel.java @@ -0,0 +1,173 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table; + +import java.util.Arrays; +import java.util.Date; + +import javax.swing.table.AbstractTableModel; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.ui.ResourcesUtil; + +public class FileSystemTableModel extends AbstractTableModel { + + private static final String MODEL_NAME = ResourcesUtil.getString("model.name"); + private static final String MODEL_SIZE = ResourcesUtil.getString("model.size"); + private static final String MODEL_TYPE = ResourcesUtil.getString("model.type"); + private static final String MODEL_DATELASTMOD = ResourcesUtil.getString("model.dateLastMod"); + + public static final int COLUMN_NAME = 0; + protected static final int COLUMN_SIZE = 1; + protected static final int COLUMN_TYPE = 2; + protected static final int COLUMN_LAST_MOD_DATE = 3; + private static final String[] COLUMN_NAMES = new String[] { MODEL_NAME, MODEL_SIZE, MODEL_TYPE, MODEL_DATELASTMOD }; + private static final Logger LOGGER = LoggerFactory.getLogger(FileSystemTableModel.class); + + private FileObject[] fileObjects = new FileObject[0]; + private FileObjectComparator fileObjectComparator = new FileObjectComparator(); + + @Override + public int getColumnCount() { + return 4; + } + + @Override + public int getRowCount() { + return fileObjects.length; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + FileObject fileObject = fileObjects[rowIndex]; + boolean isFile = false; + try { + isFile = FileType.FILE.equals(fileObject.getType()); + } catch (FileSystemException e1) { + LOGGER.warn("Can't check file type " + fileObject.getName().getBaseName(), e1); + } + if (columnIndex == COLUMN_NAME) { + try { + return new FileNameWithType(fileObject.getName(), fileObject.getType()); + } catch (FileSystemException e) { + return new FileNameWithType(fileObject.getName(), null); + } + } else if (columnIndex == COLUMN_TYPE) { + try { + return fileObject.getType().getName(); + } catch (FileSystemException e) { + LOGGER.warn("Can't get file type " + fileObject.getName().getBaseName(), e); + return "?"; + } + } else if (columnIndex == COLUMN_SIZE) { + try { + long size = -1; + if (isFile) { + size = fileObject.getContent().getSize(); + } + return new FileSize(size); + } catch (FileSystemException e) { + LOGGER.warn("Can't get size " + fileObject.getName().getBaseName(), e); + return new FileSize(-1); + } + } else if (columnIndex == COLUMN_LAST_MOD_DATE) { + try { + + long lastModifiedTime = fileObject.getContent().getLastModifiedTime(); + return new Date(lastModifiedTime); + } catch (FileSystemException e) { + LOGGER.warn("Can't get last mod date " + fileObject.getName().getBaseName(), e); + return null; + } + } + return "?"; + } + + @Override + public Class getColumnClass(int columnIndex) { + if (columnIndex == COLUMN_NAME) { + return FileNameWithType.class; + } else if (columnIndex == COLUMN_TYPE) { + return FileType.class; + } else if (columnIndex == COLUMN_SIZE) { + return FileSize.class; + } else if (columnIndex == COLUMN_LAST_MOD_DATE) { + return Date.class; + } + return super.getColumnClass(columnIndex); + } + + @Override + public String getColumnName(int column) { + return COLUMN_NAMES[column]; + } + + public void setContent(FileObject... fileObjects) { + this.fileObjects = fileObjects; + Arrays.sort(fileObjects, fileObjectComparator); + fireTableDataChanged(); + } + + public FileObject[] getContent() { + return fileObjects; + } + + public FileObject get(int row) { + return fileObjects[row]; + } + + public int getIndexByName(String nameToSelect) { + for (int i = 0; i < fileObjects.length; i++) { + String foName = fileObjects[i].getName().getBaseName(); + if (nameToSelect.equals(foName)) { + return i; + } + } + return -1; + } + +} diff --git a/src/eu/engys/util/filechooser/table/QuickSearchKeyAdapter.java b/src/eu/engys/util/filechooser/table/QuickSearchKeyAdapter.java new file mode 100644 index 0000000..0a6c91e --- /dev/null +++ b/src/eu/engys/util/filechooser/table/QuickSearchKeyAdapter.java @@ -0,0 +1,93 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.table; + +import java.awt.Rectangle; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +import javax.swing.JTable; + +import org.apache.commons.vfs2.FileObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class QuickSearchKeyAdapter extends KeyAdapter { + + private static final Logger LOGGER = LoggerFactory.getLogger(QuickSearchKeyAdapter.class); + + private long lastTimeTyped = 0; + private long typeTimeout = 500; + private static final String LETTERS = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"; + private static final String DIGITS = "0123456789"; + private static final String OTHER_CHARS = "!@#$%^&*()()-_=+[];:'\",./ "; + private static final String ALLOWED_CHARS = LETTERS + DIGITS + OTHER_CHARS; + private StringBuilder sb; + private final JTable table; + + public QuickSearchKeyAdapter(JTable table) { + this.table = table; + sb = new StringBuilder(); + } + + @Override + public void keyTyped(KeyEvent e) { + char keyChar = e.getKeyChar(); + if (ALLOWED_CHARS.indexOf(keyChar) > -1) { + if (System.currentTimeMillis() > lastTimeTyped + typeTimeout) { + sb.setLength(0); + } + sb.append(keyChar); + selectNextFileStarting(sb.toString()); + lastTimeTyped = System.currentTimeMillis(); + } + + } + + private void selectNextFileStarting(String string) { + LOGGER.debug("Looking for file starting with {}", string); + int selectedRow = table.getSelectedRow(); + selectedRow = selectedRow < 0 ? 0 : selectedRow; + LOGGER.debug("Starting search with row {}", selectedRow); + boolean fullLoop; + int started = selectedRow; + do { + LOGGER.debug("Checking table row {}", selectedRow); + int convertRowIndexToModel = table.convertRowIndexToModel(selectedRow); + LOGGER.debug("Table row {} is row {} from model", selectedRow, convertRowIndexToModel); + FileObject fileObject = ((FileSystemTableModel) table.getModel()).get(convertRowIndexToModel); + LOGGER.debug("Checking {} if begins with {}", fileObject.getName().getBaseName(), string); + if (fileObject.getName().getBaseName().toLowerCase().startsWith(string.toLowerCase())) { + table.getSelectionModel().setSelectionInterval(selectedRow, selectedRow); + table.scrollRectToVisible(new Rectangle(table.getCellRect(selectedRow, 0, true))); + break; + } + selectedRow++; + selectedRow = selectedRow >= table.getRowCount() ? 0 : selectedRow; + fullLoop = selectedRow == started; + } while (!fullLoop); + } +} diff --git a/src/eu/engys/util/filechooser/table/renderer/DateTableCellRenderer.java b/src/eu/engys/util/filechooser/table/renderer/DateTableCellRenderer.java new file mode 100644 index 0000000..8e764f0 --- /dev/null +++ b/src/eu/engys/util/filechooser/table/renderer/DateTableCellRenderer.java @@ -0,0 +1,83 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table.renderer; + +import java.awt.Component; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.SwingConstants; +import javax.swing.table.DefaultTableCellRenderer; + +public class DateTableCellRenderer extends DefaultTableCellRenderer { + + private DateFormat dateFormatFull = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private DateFormat dateFormatHourOnly = new SimpleDateFormat("HH:mm:ss"); + private DateFormat dateOnly = new SimpleDateFormat("yyyy-MM-dd"); + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + Date d = (Date) value; + String s = "-"; + if (d != null) { + s = d.toString(); + DateFormat df = dateOnly; + if (dateOnly.format(d).equals(dateOnly.format(new Date()))) { + df = dateFormatHourOnly; + l.setToolTipText(dateFormatFull.format(d)); + } + l.setToolTipText(dateFormatFull.format(d)); + s = df.format(d); + + } + l.setText(s); + l.setHorizontalAlignment(SwingConstants.RIGHT); + + return l; + + } + +} diff --git a/src/eu/engys/util/filechooser/table/renderer/FileNameWithTypeTableCellRenderer.java b/src/eu/engys/util/filechooser/table/renderer/FileNameWithTypeTableCellRenderer.java new file mode 100644 index 0000000..5d1a94c --- /dev/null +++ b/src/eu/engys/util/filechooser/table/renderer/FileNameWithTypeTableCellRenderer.java @@ -0,0 +1,134 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table.renderer; + +import static eu.engys.util.ui.FileChooserUtils.EXCEL_EXTENSION_NEW; +import static eu.engys.util.ui.FileChooserUtils.EXCEL_EXTENSION_OLD; +import static eu.engys.util.ui.FileChooserUtils.PDF_EXTENSION; + +import java.awt.Component; +import java.io.File; + +import javax.swing.Icon; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileType; + +import eu.engys.util.ApplicationInfo; +import eu.engys.util.filechooser.table.FileNameWithType; +import eu.engys.util.filechooser.util.VFSUtils; +import eu.engys.util.ui.ResourcesUtil; + +public class FileNameWithTypeTableCellRenderer extends DefaultTableCellRenderer { + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + FileNameWithType fileNameWithType = (FileNameWithType) value; + FileName fileName = fileNameWithType.getFileName(); + label.setText(fileName.getBaseName()); + label.setToolTipText(fileName.getPath()); + + FileType fileType = fileNameWithType.getFileType(); + Icon icon = null; + if (FileType.FOLDER.equals(fileType)) { + String decodePath = VFSUtils.decode(fileName.getURI(), null); + File file = decodePath == null ? null : new File(decodePath); + if (isSuitable(file)) { + label.setText(label.getText()); + if (ApplicationInfo.getVendor() != null) { + icon = ResourcesUtil.getIcon(ApplicationInfo.getVendor().toLowerCase() + ".case"); + } + } else { + icon = FOLDEROPEN; + } + } else if (VFSUtils.isArchive(fileName)) { + if ("jar".equalsIgnoreCase(fileName.getExtension())) { + icon = JARICON; + } else { + icon = FOLDERZIPPER; + } + } else if (FileType.FILE.equals(fileType)) { + if (PDF_EXTENSION.equalsIgnoreCase(fileName.getExtension())) { + icon = PDF_ICON; + } else if (EXCEL_EXTENSION_OLD.equalsIgnoreCase(fileName.getExtension()) || EXCEL_EXTENSION_NEW.equalsIgnoreCase(fileName.getExtension())) { + icon = EXCEL_ICON; + } else { + icon = FILE; + } + } else if (FileType.IMAGINARY.equals(fileType)) { + icon = SHORTCUT; + } + label.setIcon(icon); + return label; + } + + private boolean isSuitable(File file) { + if (file != null && file.exists() && file.isDirectory()) { + File constant = new File(file, "constant"); + File system = new File(file, "system"); + if (constant.exists() && constant.isDirectory() && system.exists() && system.isDirectory()) { + File controlDict = new File(system, "controlDict"); + return controlDict.exists(); + } + return false; + } + return false; + } + + /** + * Resources + */ + + private static final Icon FILE = ResourcesUtil.getIcon("file"); + private static final Icon JARICON = ResourcesUtil.getIcon("jarIcon"); + private static final Icon SHORTCUT = ResourcesUtil.getIcon("shortCut"); + private static final Icon FOLDEROPEN = ResourcesUtil.getIcon("folderOpen"); + private static final Icon FOLDERZIPPER = ResourcesUtil.getIcon("folderZipper"); + + private static final Icon PDF_ICON = ResourcesUtil.getIcon("file.pdf"); + private static final Icon EXCEL_ICON = ResourcesUtil.getIcon("file.excel"); + +} diff --git a/src/eu/engys/util/filechooser/table/renderer/FileSizeTableCellRenderer.java b/src/eu/engys/util/filechooser/table/renderer/FileSizeTableCellRenderer.java new file mode 100644 index 0000000..a5e0ecf --- /dev/null +++ b/src/eu/engys/util/filechooser/table/renderer/FileSizeTableCellRenderer.java @@ -0,0 +1,65 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table.renderer; + +import java.awt.Component; + +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.SwingConstants; +import javax.swing.table.DefaultTableCellRenderer; + +import eu.engys.util.filechooser.table.FileSize; + +public class FileSizeTableCellRenderer extends DefaultTableCellRenderer { + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + FileSize valueAt = (FileSize) table.getValueAt(row, column); + label.setText(valueAt.toString() + " "); + label.setHorizontalAlignment(SwingConstants.RIGHT); + + return label; + } + +} diff --git a/src/eu/engys/util/filechooser/table/renderer/FileTypeTableCellRenderer.java b/src/eu/engys/util/filechooser/table/renderer/FileTypeTableCellRenderer.java new file mode 100644 index 0000000..74b243d --- /dev/null +++ b/src/eu/engys/util/filechooser/table/renderer/FileTypeTableCellRenderer.java @@ -0,0 +1,63 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table.renderer; + +import java.awt.Component; + +import javax.swing.JTable; +import javax.swing.SwingConstants; +import javax.swing.table.DefaultTableCellRenderer; + +public class FileTypeTableCellRenderer extends DefaultTableCellRenderer { + + public FileTypeTableCellRenderer() { + super(); + setHorizontalAlignment(SwingConstants.RIGHT); + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setText(value + " "); + return this; + } +} diff --git a/src/eu/engys/util/filechooser/table/renderer/MixedDateTableCellRenderer.java b/src/eu/engys/util/filechooser/table/renderer/MixedDateTableCellRenderer.java new file mode 100644 index 0000000..5359902 --- /dev/null +++ b/src/eu/engys/util/filechooser/table/renderer/MixedDateTableCellRenderer.java @@ -0,0 +1,66 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table.renderer; + +import java.awt.Component; +import java.util.Date; + +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +public class MixedDateTableCellRenderer extends DefaultTableCellRenderer { + + private static final long DURATION_THRESHOLD = 1000l * 60 * 60 * 24 * 60; + + private RelativeDateTableCellRenderer relativeDateTableCellRenderer = new RelativeDateTableCellRenderer(); + private DateTableCellRenderer dateTableCellRenderer = new DateTableCellRenderer(); + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + if (value != null && value instanceof Date && ((Date) value).getTime() > System.currentTimeMillis() - DURATION_THRESHOLD) { + return relativeDateTableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + } + return dateTableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + + } + +} diff --git a/src/eu/engys/util/filechooser/table/renderer/RelativeDateTableCellRenderer.java b/src/eu/engys/util/filechooser/table/renderer/RelativeDateTableCellRenderer.java new file mode 100644 index 0000000..1e6e916 --- /dev/null +++ b/src/eu/engys/util/filechooser/table/renderer/RelativeDateTableCellRenderer.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.table.renderer; + +import java.awt.Component; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.SwingConstants; +import javax.swing.table.DefaultTableCellRenderer; + +import org.ocpsoft.prettytime.PrettyTime; + +public class RelativeDateTableCellRenderer extends DefaultTableCellRenderer { + + private PrettyTime prettyTime = new PrettyTime(); + private DateFormat dateFormatFull = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + Date d = (Date) value; + String s = "-"; + String tooltip = ""; + + if (d != null) { + String formattedTime = prettyTime.format(d); + s = formattedTime; + tooltip = dateFormatFull.format(d); + } + l.setToolTipText(tooltip); + l.setText(s); + l.setHorizontalAlignment(SwingConstants.RIGHT); + + return l; + + } + +} diff --git a/src/eu/engys/util/filechooser/uri/Protocol.java b/src/eu/engys/util/filechooser/uri/Protocol.java new file mode 100644 index 0000000..3d4f31e --- /dev/null +++ b/src/eu/engys/util/filechooser/uri/Protocol.java @@ -0,0 +1,113 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package eu.engys.util.filechooser.uri; + +/** + *

+ * T1ODO Disable the SSL port option when not supported in the connection dialog + * It's probably better/faster than removing the SSL member For the file + * protocol no port will be associated, need to handle that case using a -1 + * value in the connection dialog + *

+ * Enumeration holding protocol constants + * + * @author Yves Zoundi + * @version 0.0.1 + */ +public enum Protocol { // Protocol constants + SMB("SMB", 445, "Connect to windows LAN or SAMBA"), + SFTP("SFTP", 22, "Connect to a SSH server"), + FTP("FTP", 21, "Connect to a FTP server"), + WEBDAV("WEBDAV", 9800, "Connect to a WEBDAV server"), + HTTP("HTTP", 80, "Connect to a HTTP server"), + HTTPS("HTTPS", 443, "HTTP connection over SSL"), + FILE("FILE", -1, "Local files"); + + private final String name; // displayed name + private final Integer port; // port number + private final String description; // protocol description + + /** + * Create a new protocol + * + * @param name + * The name of the protocol + * @param port + * The port used by the protocol + */ + Protocol(final String name, final int port, final String description) { + this.name = name; + this.port = port; + this.description = description; + } + + /** + * Returns the protocol name + * + * @return the protocol name + */ + public final String getName() { + return name; + } + + /** + * Returns the protocol port number + * + * @return the protocol port number + */ + public final int getPort() { + return port; + } + + /** + * Returns the protocol description + * + * @return the protocol description + */ + public String getDescription() { + return description; + } + + @Override + public String toString() { + return this.name; + } +} diff --git a/src/eu/engys/util/filechooser/uri/VFSURIParser.java b/src/eu/engys/util/filechooser/uri/VFSURIParser.java new file mode 100644 index 0000000..847d83a --- /dev/null +++ b/src/eu/engys/util/filechooser/uri/VFSURIParser.java @@ -0,0 +1,157 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package eu.engys.util.filechooser.uri; + + +/** + * VFSURIParser class for bookmarks URIs + * + * @author Yves Zoundi + * @author Stan Love + * @version 0.0.6 + */ +public final class VFSURIParser { + private static final char PATH_SEPARATOR = '/'; + private String username; + private String password; + private String path; + private String hostname; + private String portnumber; + private Protocol protocol; + + /** + * Create a new instance of VFSURIParser + * + * @param fileURI + * The VFS file URI to parse + */ + public VFSURIParser(final String fileURI) { + this(fileURI, true); + } + + public VFSURIParser(final String fileURI, boolean assignDefaultPort) { + if (fileURI == null) { + throw new NullPointerException("file URI is null"); + } + + VFSURIValidator v = new VFSURIValidator(); + boolean valid = v.isValid(fileURI); + if (valid) { + hostname = v.getHostname(); + username = v.getUser(); + password = v.getPassword(); + path = v.getFile(); + portnumber = v.getPort(); + String p = v.getProtocol(); + + // fix up parsing results + protocol = Protocol.valueOf(p.toUpperCase()); + if ((portnumber == null) && (!p.equalsIgnoreCase("file"))) { + portnumber = String.valueOf(protocol.getPort()); + } + if (path == null) { + path = String.valueOf(PATH_SEPARATOR); + } + } else { + hostname = null; + username = null; + password = null; + path = fileURI; + portnumber = null; + protocol = null; + } + + } + + /** + * Returns the VFS hostname + * + * @return the VFS hostname + */ + public String getHostname() { + return hostname; + } + + /** + * Returns the VFS password + * + * @return the VFS password + */ + public String getPassword() { + return password; + } + + /** + * Returns the VFS path + * + * @return the VFS path + */ + public String getPath() { + return path; + } + + /** + * Returns the VFS port number + * + * @return the VFS port number + */ + public String getPortnumber() { + return portnumber; + } + + /** + * Returns the VFS protocol + * + * @return the VFS protocol + */ + public Protocol getProtocol() { + return protocol; + } + + /** + * Returns the VFS username + * + * @return the VFS username + */ + public String getUsername() { + return username; + } +} diff --git a/src/eu/engys/util/filechooser/uri/VFSURIValidator.java b/src/eu/engys/util/filechooser/uri/VFSURIValidator.java new file mode 100644 index 0000000..25d32c9 --- /dev/null +++ b/src/eu/engys/util/filechooser/uri/VFSURIValidator.java @@ -0,0 +1,2854 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package eu.engys.util.filechooser.uri; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * VFS URIs validator + * + * @author Stan Love + * @version 0.0.4 + */ +public class VFSURIValidator { + private String local_uri, local_protocol, local_user, local_pass; + private String local_hostname, local_port, local_file; + + public boolean assertEquals(String _s1, String _s2) { + if ((_s1 == null) || (_s2 == null)) { + System.out.println("FATAL assertEquals -- _s1 || _s2 == null"); + System.out.println("_s1=" + _s1 + "="); + System.out.println("_s2=" + _s2 + "="); + Exception e = new Exception(""); + e.printStackTrace(); + System.exit(10); + } + if (_s1.equals(_s2)) { + } else { + System.out.println("FATAL assertEquals -- _s1 != _s2 "); + System.out.println("_s1=" + _s1 + "="); + System.out.println("_s2=" + _s2 + "="); + Exception e = new Exception(""); + e.printStackTrace(); + System.exit(10); + } + return false; + } + + public boolean assertNull(String _s1) { + if (_s1 != null) { + System.out.println("FATAL assertNull -- _s1 != null"); + Exception e = new Exception(""); + e.printStackTrace(); + System.exit(10); + } + return false; + } + + public boolean assertnotNull(String _s1) { + if (_s1 == null) { + System.out.println("FATAL assertnoNull -- _s1 != null"); + Exception e = new Exception(""); + e.printStackTrace(); + System.exit(10); + } + return false; + } + + public String getUri() { + if (local_uri.equals("")) + local_uri = null; + return local_uri; + } + + public String getProtocol() { + if ((local_protocol != null) && (local_protocol.equals(""))) + local_protocol = null; + return local_protocol; + } + + public String getUser() { + if ((local_user != null) && (local_user.equals(""))) + local_user = null; + return local_user; + } + + public String getPassword() { + if ((local_pass != null) && (local_pass.equals(""))) + local_pass = null; + return local_pass; + } + + public String getHostname() { + if ((local_hostname != null) && (local_hostname.equals(""))) + local_hostname = null; + return local_hostname; + } + + public String getPort() { + if (local_port == null) { + return local_port; + } + if (local_port.startsWith(":")) { + local_port = local_port.substring(1); + } + if ((local_port != null) && (local_port.equals(""))) + local_port = null; + return local_port; + } + + public String getFile() { + if ((local_file != null) && (local_file.equals(""))) + local_file = null; + return local_file; + } + + public boolean isValid(String _uri) { + boolean ret = false; + boolean ends_with_slash = false; + + String protocol = null; + String user_pass = null; + String hostname = null; + String port = null; + String bad_port = null; + String drive = null; + String file = null; + + /* + * System.out.println(); System.out.println(); System.out.println(); + */ + + local_uri = null; + local_protocol = null; + local_user = null; + local_pass = null; + local_hostname = null; + local_port = null; + local_file = null; + // file://(drive_letter:)/ + // file://(drive_letter:)/file_path + // Pattern p_file1 = + // Pattern.compile("(file|FILE)://([a-z][ ]*:)*?(/.*)"); + Pattern p_file1 = Pattern.compile("(file|FILE)://(/*)([a-zA-Z][ ]*:)*(.*)"); + Matcher m_file1 = p_file1.matcher(_uri); + + if (m_file1.matches()) { + // System.out.println("file matcher"); + protocol = m_file1.group(1); + String path_start = m_file1.group(2); + drive = m_file1.group(3); + file = m_file1.group(4); + + /* + * System.out.println("uri="+_uri+"="); + * System.out.println("drive="+drive+"="); + * System.out.println("file="+file+"="); + * System.out.println("path_start="+path_start+"="); + */ + local_uri = _uri; + local_protocol = protocol; + local_user = null; + local_pass = null; + local_hostname = null; + local_port = null; + if ((drive != null) && (file != null)) { + local_file = drive + file; + } else if ((path_start != null) && (drive == null) && (file != null)) { + local_file = path_start + file; + } else if ((drive != null) && (file == null)) { + local_file = drive; + } else { + local_file = file; + } + return true; + } + + /* + * //look for a bad port number + * //ftp://(username:pass)*?@hostname(:[0-9]+)*?/.* Pattern p_ftp1 = + * Pattern.compile( + * "(ftp|FTP|sftp|SFTP|http|HTTP|https|HTTPS|webdav|WEBDAV|smb|SMB)://(.*?:.*?@)*(.*?)?([ ]*:[^0-9]+)*?[ ]*[^:]/.*" + * ); Matcher m_ftp1 = p_ftp1.matcher(_uri); if(m_ftp1.matches())return + * false; + * + * if (m_file1.matches()) { //System.out.println("file matcher"); + * protocol = m_file1.group(1); drive = m_file1.group(2); file = + * m_file1.group(3); + * + * //System.out.println("uri="+_uri+"="); + * //System.out.println("file="+file+"="); + * //System.out.println("drive="+drive+"="); local_uri = _uri; + * local_protocol = protocol; local_user = null; local_pass = null; + * local_hostname = null; local_port = null; if ((drive != null) && + * (file != null)) { local_file = drive + file; } else { local_file = + * file; } return true; } + * + * /* //look for a bad port number + * //ftp://(username:pass)*?@hostname(:[0-9]+)*?/.* Pattern p_ftp1 = + * Pattern.compile( + * "(ftp|FTP|sftp|SFTP|http|HTTP|https|HTTPS|webdav|WEBDAV|smb|SMB)://(.*?:.*?@)*(.*?)?([ ]*:[^0-9]+)*?[ ]*[^:]/.*" + * ); Matcher m_ftp1 = p_ftp1.matcher(_uri); if(m_ftp1.matches())return + * false; + */ + + // remove trailing slash if present + if (_uri.endsWith("/")) { + int iend = _uri.length(); + _uri = _uri.substring(0, iend - 1); + ends_with_slash = true; + } + // ftp://(username:pass)*?@hostname(:[0-9]+)*?/.* + // "(ftp|FTP|sftp|SFTP|http|HTTP|https|HTTPS|webdav|WEBDAV|smb|SMB)://(.*?:.*?@)*([^:]+)([ ]*:[0-9]+)*([ ]*:)*(/.*)"); + // "(ftp|FTP|sftp|SFTP|http|HTTP|https|HTTPS|webdav|WEBDAV|smb|SMB)://(.+:.+@)*([^:]+)([ ]*:[0-9]+)*([ ]*:)*(/.*)"); + Pattern p_ftp2 = Pattern.compile("(ftp|FTP|sftp|SFTP|http|HTTP|https|HTTPS|webdav|WEBDAV|smb|SMB)://(.+:.+@)*([^:]+?/*)([ ]*:[0-9]+)*([ ]*:)*(/.*)"); + Matcher m_ftp2 = p_ftp2.matcher(_uri); + + Pattern p_ftp3 = Pattern.compile("(ftp|FTP|sftp|SFTP|http|HTTP|https|HTTPS|webdav|WEBDAV|smb|SMB)://(.+:.+@)*([^:]+)([ ]*:[0-9]+)*([ ]*:)*(/*?.*)"); + Matcher m_ftp3 = p_ftp3.matcher(_uri); + + if (m_ftp2.matches()) { + // System.out.println("ftp2 matcher"); + ret = true; + protocol = m_ftp2.group(1); + user_pass = m_ftp2.group(2); + hostname = m_ftp2.group(3); + + port = m_ftp2.group(4); + bad_port = m_ftp2.group(5); // this should be null on all valid port + // inputs + file = m_ftp2.group(6); + if (ends_with_slash) { + file = file + "/"; + } + if (hostname == null) { + protocol = null; + user_pass = null; + port = null; + bad_port = null; + file = null; + ret = false; + } + + } else if (m_ftp3.matches()) { + // System.out.println("ftp3 matcher"); + ret = true; + protocol = m_ftp3.group(1); + user_pass = m_ftp3.group(2); + hostname = m_ftp3.group(3); + + port = m_ftp3.group(4); + bad_port = m_ftp3.group(5); // this should be null on all valid port + // inputs + file = m_ftp3.group(6); + if (ends_with_slash) { + file = file + "/"; + } + if (hostname == null) { + protocol = null; + user_pass = null; + port = null; + bad_port = null; + file = null; + ret = false; + } + } else { + // System.out.println("did not match"); + } + + if (ret == true) { + // leave the various regex parts of the string here in case we want + // to do more validation/debugging in the future + } + + if ((hostname != null) && hostname.contains("@")) { + user_pass = hostname.substring(0, hostname.indexOf('@')); + hostname = hostname.substring(hostname.indexOf('@') + 1); + } + // System.out.println("uri="+_uri+"="); + // System.out.println("protocol="+protocol+"="); + // System.out.println("user_pass="+user_pass+"="); + // System.out.println("hostname="+hostname+"="); + // System.out.println("port="+port+"="); + // System.out.println("bad_port="+bad_port+"="); + // System.out.println("file="+file+"="); + + if ((hostname != null) && (hostname.startsWith(":") || hostname.endsWith(":") || hostname.contains(":"))) { + // System.out.println("bad hostname="+hostname+"="); + ret = false; + } + + if (bad_port != null) { + // System.out.println("bad_port found="+bad_port+"="); + ret = false; + } + + if (ret == false) { // don't parse any bad inputs + return ret; + } + local_uri = _uri; + local_protocol = protocol; + int colon_position = -1; + if ((user_pass == null) || (user_pass.equals(""))) { + colon_position = -1; + } else { + colon_position = user_pass.indexOf(':'); + } + if ((user_pass == null) || (user_pass.equals(""))) { + local_user = null; + local_pass = null; + } else if (colon_position == -1) { + local_user = user_pass; + local_pass = null; + } else { + local_user = user_pass.substring(0, colon_position); + local_pass = user_pass.substring(colon_position); + } + // System.out.println("raw local_pass="+local_pass+"="); + if (local_pass != null) { + if (local_pass.endsWith("@")) { + local_pass = local_pass.substring(0, local_pass.length() - 1); + } + if (local_pass.startsWith(":")) { + local_pass = local_pass.substring(1); + } + } + local_hostname = hostname; + local_port = port; + local_file = file; + + return ret; + } + + public void error_msg(String _s) { + System.out.println("Error in test=" + _s + "="); + Exception e = new Exception(""); + e.printStackTrace(); + System.exit(10); + } + + /** + * @param args + */ + public static void main(String[] args) { + // test code + String s; + + /* + * v.assertEquals(v.getProtocol(),"files"); v.assertNull(v.getUser()); + * v.assertNull(v.getHostname()); v.assertNull(v.getPassword()); + * v.assertNull(v.getPort()); v.assertEquals(v.getFile(),"c:"); + */ + // unknown protocol names + s = "files://c:"; + + VFSURIValidator v = new VFSURIValidator(); + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "files://c:"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "FTPS://c:"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "ftps://c:"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "files123://c:"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "fiLE://c:"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + // file tests + s = "file://c:"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "c:"); + + s = "file://d:"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "d:"); + + s = "file://e:"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "e:"); + + s = "file://z:"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "z:"); + + s = "file://c:/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "c:/"); + + s = "file://d:/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "d:/"); + + s = "file://e:/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "e:/"); + + s = "file://z:/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "z:/"); + + s = "file://c:/a"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "c:/a"); + + s = "file://d:/a"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "d:/a"); + + s = "file://e:/b"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "e:/b"); + + s = "file://z:/b"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "z:/b"); + + s = "FILE://c:"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "c:"); + + s = "FILE://d:"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "d:"); + + s = "FILE://e:"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "e:"); + + s = "FILE://z:"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "z:"); + + s = "FILE://c:/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "c:/"); + + s = "FILE://d:/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "d:/"); + + s = "FILE://e:/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "e:/"); + + s = "FILE://z:/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "z:/"); + + s = "FILE://c:/a"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "c:/a"); + + s = "FILE://d:/a"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "d:/a"); + + s = "FILE://e:/b"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "e:/b"); + + s = "FILE://z:/b"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FILE"); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "z:/b"); + + // ftp tests + s = "ftp://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "ftp"); + v.assertNull(v.getUser()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "ftp://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "ftp"); + v.assertNull(v.getUser()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPassword()); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "ftp://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "ftp"); + v.assertNull(v.getUser()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPassword()); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "ftp://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "ftp://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "ftp"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "ftp://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "ftp"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "ftp://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "ftp://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "ftp"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "ftp://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "ftp"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "ftp: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "ftp:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "ftp:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "ftp://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "ftp://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + // System.exit(10); + s = "FTP://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FTP"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "FTP://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FTP"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "FTP://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FTP"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "FTP://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "FTP://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "FTP://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "FTP://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "FTP://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "FTP://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "FTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "FTP: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "FTP:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "FTP:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "FTP://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "FTP://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + // sftp tests + s = "sftp://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "sftp"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "sftp://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "sftp"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "sftp://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "sftp"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "sftp://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "sftp://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "sftp"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "sftp://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "sftp"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "sftp://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "sftp://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "sftp"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "sftp://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "sftp"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "sftp: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "sftp:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "sftp:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "sftp://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "sftp://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SFTP://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SFTP"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SFTP://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SFTP"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SFTP://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SFTP"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SFTP://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SFTP://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SFTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SFTP://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SFTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SFTP://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SFTP://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SFTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SFTP://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SFTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "SFTP: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SFTP:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + + s = "SFTP:/ /user:pass:@machine"; + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SFTP://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SFTP://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + // http tests + s = "http://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "http"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "http://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "http"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "http://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "http"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "http://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "http://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "http"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "http://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "http"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "http://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "http://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "http"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "http://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "http"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "http: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "http:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "http:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "http://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "http://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTP://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTP"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTP://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTP"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTP://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTP"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTP://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTP://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTP://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTP://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTP://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTP://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTP"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "HTTP: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTP:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTP:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTP://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTP://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + // https tests + s = "https://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "https"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "https://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "https"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "https://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "https"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "https://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "https://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "https"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "https://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "https"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "https://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "https://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "https"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "https://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "https"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "https: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "https:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "https:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "https://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "https://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTPS://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTPS"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTPS://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTPS"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTPS://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTPS"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTPS://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTPS://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTPS"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTPS://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTPS"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTPS://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTPS://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTPS"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "HTTPS://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "HTTPS"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "HTTPS: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTPS:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTPS:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTPS://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "HTTPS://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + // webdav tests + s = "webdav://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "webdav"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "webdav://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "webdav"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "webdav://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "webdav"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "webdav://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "webdav://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "webdav"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "webdav://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "webdav"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "webdav://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "webdav://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "webdav"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "webdav://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + + s = "webdav: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "webdav:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "webdav:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "webdav://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "webdav://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "WEBDAV://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "WEBDAV"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "WEBDAV://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "WEBDAV"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "WEBDAV://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "WEBDAV"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "WEBDAV://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "WEBDAV://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "WEBDAV"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "WEBDAV://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "WEBDAV"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "WEBDAV://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "WEBDAV://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "WEBDAV"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "WEBDAV://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "WEBDAV"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "WEBDAV: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "WEBDAV:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "WEBDAV:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "WEBDAV://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "WEBDAV://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + // smb tests + s = "smb://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "smb"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "smb://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "smb"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "smb://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "smb"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "smb://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "smb://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "smb"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "smb://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "smb"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "smb://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "smb://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "smb"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "smb://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "smb"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "smb: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "smb:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "smb:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "smb://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "smb://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SMB://machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SMB"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SMB://machine:1/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SMB"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "1"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SMB://machine:12345/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SMB"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "12345"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SMB://machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SMB://user:pass@machine/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SMB"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SMB://user:pass@machine:123/the_file"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SMB"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass"); + v.assertEquals(v.getHostname(), "machine"); + v.assertEquals(v.getPort(), "123"); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SMB://user:pass@machine:/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SMB://user:pass:@machine/the_file"; // can ":" be part of a + // password? + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SMB"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_file"); + + s = "SMB://user:pass:@machine/the_dir/"; + + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "SMB"); + v.assertEquals(v.getUser(), "user"); + v.assertEquals(v.getPassword(), "pass:"); + v.assertEquals(v.getHostname(), "machine"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/the_dir/"); + + s = "SMB: //user:pass:@machine/the_file"; // failure tests + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SMB:/ /user:pass:@machine/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SMB:/ /user:pass:@machine"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SMB://user:pass:@:123/a"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "SMB://user:pass:@machine:a/the_file"; + + if (v.isValid(s)) { + v.error_msg(s); + } + v.assertNull(v.getProtocol()); + v.assertNull(v.getUser()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPassword()); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + // add tests from Yves + s = "sftp://shell.sf.net"; + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "sftp"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "shell.sf.net"); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "file:///C:/home/birdman"; + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "C:/home/birdman"); + + s = "file:///home/birdman"; + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/home/birdman"); + + s = "file://home/birdman"; + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "file"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertNull(v.getHostname()); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "home/birdman"); + + s = "webdav://myserver.net/home/yves"; + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "webdav"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "myserver.net"); + v.assertNull(v.getPort()); + v.assertEquals(v.getFile(), "/home/yves"); + + s = "ftp://ftp.ca.freebsd.org"; + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "ftp"); + v.assertNull(v.getUser()); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "ftp.ca.freebsd.org"); + v.assertNull(v.getPort()); + v.assertNull(v.getFile()); + + s = "sftp://yves@shell.sf.net:28"; + if (!v.isValid(s)) { + v.error_msg(s); + } + v.assertEquals(v.getProtocol(), "sftp"); + v.assertEquals(v.getUser(), "yves"); + v.assertNull(v.getPassword()); + v.assertEquals(v.getHostname(), "shell.sf.net"); + v.assertEquals(v.getPort(), "28"); + v.assertNull(v.getFile()); + + System.out.println("all done"); + } +} diff --git a/src/eu/engys/util/filechooser/util/CompositeTaskContext.java b/src/eu/engys/util/filechooser/util/CompositeTaskContext.java new file mode 100644 index 0000000..0307794 --- /dev/null +++ b/src/eu/engys/util/filechooser/util/CompositeTaskContext.java @@ -0,0 +1,79 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.util; + +/** + */ +public class CompositeTaskContext extends TaskContext { + + private TaskContext[] taskContext; + + public CompositeTaskContext(String name, TaskContext[] taskContext) { + super(name, 0); + this.taskContext = taskContext; + } + + @Override + public void setStop(boolean stop) { + for (TaskContext context : taskContext) { + context.setStop(stop); + } + } + + @Override + public int getMax() { + int max = 0; + for (TaskContext context : taskContext) { + max += context.getMax(); + } + return max; + } + + @Override + public int getCurrentProgress() { + int progress = 0; + for (TaskContext context : taskContext) { + progress += context.getMax(); + } + return progress; + } +} diff --git a/src/eu/engys/util/filechooser/util/EngysFileSystemManager.java b/src/eu/engys/util/filechooser/util/EngysFileSystemManager.java new file mode 100644 index 0000000..c5b4c0f --- /dev/null +++ b/src/eu/engys/util/filechooser/util/EngysFileSystemManager.java @@ -0,0 +1,48 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.util; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileType; +import org.apache.commons.vfs2.NameScope; +import org.apache.commons.vfs2.impl.StandardFileSystemManager; + +public class EngysFileSystemManager extends StandardFileSystemManager { + + @Override + public FileName resolveName(FileName base, String name, NameScope scope) { + FileName fileName; + try { + fileName = super.resolveName(base, name, scope); + } catch (Exception e) { + String scheme = StringUtils.removeEnd(base.getRootURI(), "/"); + fileName = new InvalidFileName(name, scheme, "invalid", FileType.FILE); + } + return fileName; + } + +} diff --git a/src/eu/engys/util/filechooser/util/FileNameWrapper.java b/src/eu/engys/util/filechooser/util/FileNameWrapper.java new file mode 100644 index 0000000..f0e1cef --- /dev/null +++ b/src/eu/engys/util/filechooser/util/FileNameWrapper.java @@ -0,0 +1,153 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.util; + +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileType; +import org.apache.commons.vfs2.NameScope; +import org.apache.commons.vfs2.provider.AbstractFileName; + +public class FileNameWrapper extends AbstractFileName { + + protected FileName fileName; + + public FileNameWrapper(FileName fileName) { + super(fileName.getScheme(), fileName.getPath(), fileName.getType()); + this.fileName = fileName; + } + + @Override + public String getBaseName() { + return fileName.getBaseName(); + } + + @Override + public int getDepth() { + return fileName.getDepth(); + } + + @Override + public String getExtension() { + return fileName.getExtension(); + } + + @Override + public String getFriendlyURI() { + return fileName.getFriendlyURI(); + } + + @Override + public FileName getParent() { + return fileName.getParent(); + } + + @Override + public String getPath() { + return fileName.getPath(); + } + + @Override + public String getPathDecoded() throws FileSystemException { + return fileName.getPathDecoded(); + } + + @Override + public String getRelativeName(FileName name) throws FileSystemException { + return fileName.getRelativeName(name); + } + + @Override + public FileName getRoot() { + return fileName.getRoot(); + } + + @Override + public String getRootURI() { + return fileName.getRootURI(); + } + + @Override + public String getScheme() { + return fileName.getScheme(); + } + + @Override + public FileType getType() { + return fileName.getType(); + } + + @Override + public String getURI() { + return fileName.getURI(); + } + + @Override + public boolean isAncestor(FileName ancestor) { + return fileName.isAncestor(ancestor); + } + + @Override + public boolean isDescendent(FileName descendent) { + return fileName.isDescendent(descendent); + } + + @Override + public boolean isDescendent(FileName descendent, NameScope nameScope) { + return fileName.isDescendent(descendent, nameScope); + } + + @Override + public int compareTo(FileName o) { + return fileName.compareTo(o); + } + + @Override + public FileName createName(String absPath, FileType type) { + return ((AbstractFileName) fileName).createName(absPath, type); + } + + @Override + protected void appendRootUri(StringBuilder buffer, boolean addPassword) { + + } +} diff --git a/src/eu/engys/util/filechooser/util/FileObjectWrapper.java b/src/eu/engys/util/filechooser/util/FileObjectWrapper.java new file mode 100644 index 0000000..a773e91 --- /dev/null +++ b/src/eu/engys/util/filechooser/util/FileObjectWrapper.java @@ -0,0 +1,176 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.util; + +import java.net.URL; +import java.util.List; + +import org.apache.commons.vfs2.FileContent; +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSelector; +import org.apache.commons.vfs2.FileSystem; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileType; +import org.apache.commons.vfs2.NameScope; +import org.apache.commons.vfs2.operations.FileOperations; + +public class FileObjectWrapper implements FileObject { + protected FileObject parent; + + public FileObjectWrapper(FileObject parent) { + super(); + this.parent = parent; + } + + public FileName getName() { + return parent.getName(); + } + + public URL getURL() throws FileSystemException { + return parent.getURL(); + } + + public boolean exists() throws FileSystemException { + return parent.exists(); + } + + public boolean isHidden() throws FileSystemException { + return parent.isHidden(); + } + + public boolean isReadable() throws FileSystemException { + return parent.isReadable(); + } + + public boolean isWriteable() throws FileSystemException { + return parent.isWriteable(); + } + + public FileType getType() throws FileSystemException { + return parent.getType(); + } + + public FileObject getParent() throws FileSystemException { + return parent.getParent(); + } + + public FileSystem getFileSystem() { + return parent.getFileSystem(); + } + + public FileObject[] getChildren() throws FileSystemException { + return parent.getChildren(); + } + + public FileObject getChild(String name) throws FileSystemException { + return parent.getChild(name); + } + + public FileObject resolveFile(String name, NameScope scope) throws FileSystemException { + return parent.resolveFile(name, scope); + } + + public FileObject resolveFile(String path) throws FileSystemException { + return parent.resolveFile(path); + } + + public FileObject[] findFiles(FileSelector selector) throws FileSystemException { + return parent.findFiles(selector); + } + + public void findFiles(FileSelector selector, boolean depthwise, List selected) throws FileSystemException { + parent.findFiles(selector, depthwise, selected); + } + + public boolean delete() throws FileSystemException { + return parent.delete(); + } + + public int delete(FileSelector selector) throws FileSystemException { + return parent.delete(selector); + } + + public void createFolder() throws FileSystemException { + parent.createFolder(); + } + + public void createFile() throws FileSystemException { + parent.createFile(); + } + + public void copyFrom(FileObject srcFile, FileSelector selector) throws FileSystemException { + parent.copyFrom(srcFile, selector); + } + + public void moveTo(FileObject destFile) throws FileSystemException { + parent.moveTo(destFile); + } + + public boolean canRenameTo(FileObject newfile) { + return parent.canRenameTo(newfile); + } + + public FileContent getContent() throws FileSystemException { + return parent.getContent(); + } + + public void close() throws FileSystemException { + parent.close(); + } + + public void refresh() throws FileSystemException { + parent.refresh(); + } + + public boolean isAttached() { + return parent.isAttached(); + } + + public boolean isContentOpen() { + return parent.isContentOpen(); + } + + public FileOperations getFileOperations() throws FileSystemException { + return parent.getFileOperations(); + } +} diff --git a/src/eu/engys/util/filechooser/util/HelyxFileFilter.java b/src/eu/engys/util/filechooser/util/HelyxFileFilter.java new file mode 100644 index 0000000..19d4d4f --- /dev/null +++ b/src/eu/engys/util/filechooser/util/HelyxFileFilter.java @@ -0,0 +1,84 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.util; + +import java.io.File; + +import org.apache.commons.io.FilenameUtils; + +public class HelyxFileFilter { + + private static final String[] ALL_FILES_FILTER_EXTENSIONS = new String[] { "*" }; + public static final String ALL_FILES_FILTER_DESCRIPTION = "All Files (*.*)"; + private final String description; + private String[] extensions; + private static HelyxFileFilter allFilesFilter = new HelyxFileFilter(ALL_FILES_FILTER_DESCRIPTION, ALL_FILES_FILTER_EXTENSIONS); + + /** + * Example: Fluent File (*.msh, *.cas)", "msh", "cas" + */ + public HelyxFileFilter(String description, String... extensions) { + this.description = description; + this.extensions = extensions; + } + + public static HelyxFileFilter getAllFilesFilter() { + return allFilesFilter; + } + + public boolean isAllFilesFilter() { + return ALL_FILES_FILTER_DESCRIPTION.equals(description) && ALL_FILES_FILTER_EXTENSIONS.equals(extensions); + } + + public String getDescription() { + return description; + } + + public String[] getExtensions() { + return extensions; + } + + public boolean isValidExtension(String extensionToCheck) { + for (String ext : extensions) { + if (ext.equalsIgnoreCase(extensionToCheck)) { + return true; + } + } + return false; + } + + public boolean accepts(File file) { + if (extensions == null) { + return false; + } + if (isAllFilesFilter()) { + return true; + } + String fileExtension = FilenameUtils.getExtension(file.getName()); + return isValidExtension(fileExtension); + } + +} diff --git a/src/eu/engys/util/filechooser/util/InvalidFileName.java b/src/eu/engys/util/filechooser/util/InvalidFileName.java new file mode 100644 index 0000000..e8495fa --- /dev/null +++ b/src/eu/engys/util/filechooser/util/InvalidFileName.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.filechooser.util; + +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileType; +import org.apache.commons.vfs2.provider.AbstractFileName; + +public class InvalidFileName extends AbstractFileName { + + private String originalName; + + public InvalidFileName(String originalName, String scheme, String absPath, FileType type) { + super(scheme, absPath, type); + this.originalName = originalName; + } + + @Override + public FileName createName(String absPath, FileType type) { + return new InvalidFileName("", getScheme(), absPath, type); + } + + @Override + protected void appendRootUri(StringBuilder buffer, boolean addPassword) { + buffer.append(getScheme()); + } + + public String getOriginalName() { + return originalName; + } + +} diff --git a/src/eu/engys/util/filechooser/util/SelectionMode.java b/src/eu/engys/util/filechooser/util/SelectionMode.java new file mode 100644 index 0000000..45f459a --- /dev/null +++ b/src/eu/engys/util/filechooser/util/SelectionMode.java @@ -0,0 +1,79 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.util; + +/** + */ +public enum SelectionMode { + + FILES_ONLY("Files only"), + DIRS_ONLY("Dirs only"), + DIRS_AND_FILES("Dirs and files"), + DIRS_AND_ARCHIVES("Dirs and archives"); + + private String name; + + private SelectionMode(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public boolean isDirsOnly() { + return this.equals(DIRS_ONLY); + } + + public boolean isFilesOnly() { + return this.equals(FILES_ONLY); + } + + public boolean isDirsAndFiles() { + return this.equals(DIRS_AND_FILES); + } + + public boolean isDirsAndArchives() { + return this.equals(DIRS_AND_ARCHIVES); + } + +} diff --git a/src/eu/engys/util/filechooser/util/TaskContext.java b/src/eu/engys/util/filechooser/util/TaskContext.java new file mode 100644 index 0000000..39e3d57 --- /dev/null +++ b/src/eu/engys/util/filechooser/util/TaskContext.java @@ -0,0 +1,94 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eu.engys.util.filechooser.util; + +/** + */ +public class TaskContext { + private int max; + private volatile int currentProgress; + private volatile boolean stop; + private String name; + + private boolean indeterminate; + + public TaskContext(String name, int max) { + this.max = max; + this.name = name; + } + + public void setIndeterminate(boolean indeterminate) { + this.indeterminate = indeterminate; + } + + public boolean isIndeterminate() { + return indeterminate; + } + + public String getName() { + return name; + } + + public boolean isStop() { + return stop; + } + + public void setStop(boolean stop) { + this.stop = stop; + } + + public int getCurrentProgress() { + return currentProgress; + } + + public void setCurrentProgress(int currentProgress) { + this.currentProgress = currentProgress; + } + + public int getMax() { + return max; + } + + public void setMax(int max) { + this.max = max; + } +} diff --git a/src/eu/engys/util/filechooser/util/VFSUtils.java b/src/eu/engys/util/filechooser/util/VFSUtils.java new file mode 100644 index 0000000..b022dba --- /dev/null +++ b/src/eu/engys/util/filechooser/util/VFSUtils.java @@ -0,0 +1,547 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +/* + * Copyright 2012 Krzysztof Otrebski (krzysztof.otrebski@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package eu.engys.util.filechooser.util; + +import static eu.engys.util.ui.FileChooserUtils.DEFAULT_SSH_PORT; + +import java.awt.Component; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import javax.swing.Icon; +import javax.swing.JOptionPane; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.vfs2.CacheStrategy; +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileSystemManager; +import org.apache.commons.vfs2.FileSystemOptions; +import org.apache.commons.vfs2.FileType; +import org.apache.commons.vfs2.UserAuthenticationData; +import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder; +import org.apache.commons.vfs2.impl.StandardFileSystemManager; +import org.apache.commons.vfs2.provider.UriParser; +import org.apache.commons.vfs2.provider.sftp.SftpFileObject; +import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Joiner; + +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; +import eu.engys.util.connection.SshParameters; +import eu.engys.util.filechooser.LinkFileObject; +import eu.engys.util.filechooser.authentication.AuthStore; +import eu.engys.util.filechooser.authentication.MemoryAuthStore; +import eu.engys.util.filechooser.authentication.UserAuthenticationDataWrapper; +import eu.engys.util.filechooser.authentication.UserAuthenticationInfo; +import eu.engys.util.filechooser.authentication.UserAuthenticatorFactory; +import eu.engys.util.filechooser.authentication.authenticator.OtrosUserAuthenticator; +import eu.engys.util.filechooser.uri.Protocol; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.ResourcesUtil; + +/** + * A helper class to deal with commons-vfs file abstractions + * + * @author Yves Zoundi + * @author Jojada Tirtowidjojo + * @author Stephan Schuster + * @version 0.0.5 + */ +public final class VFSUtils { + + private static final Logger logger = LoggerFactory.getLogger(VFSUtils.class); + + public enum LocationType { + file, sftp; + + public String toString() { + if (Util.isWindows() && equals(file)) { + return super.toString() + WIN_PROTOCOL_PREFIX; + } + return super.toString() + UNIX_PROTOCOL_PREFIX; + }; + + public static String[] toStringArray() { + return new String[] { file.toString(), sftp.toString() }; + }; + } + + private static final int SYMBOLIC_LINK_MAX_SIZE = 128; + + private static FileSystemManager fileSystemManager; + private static FileSystemOptions fileSystemOptions = new FileSystemOptions(); + public static final String UNIX_PROTOCOL_PREFIX = "://"; + public static final String WIN_PROTOCOL_PREFIX = ":///"; + private static final File HOME_DIRECTORY = new File(System.getProperty("user.home")); + + public static final File CONFIG_DIRECTORY = new File(HOME_DIRECTORY, ".otrosvfsbrowser"); + public static final File USER_AUTH_FILE = new File(CONFIG_DIRECTORY, "auth.xml"); + public static final File USER_AUTH_FILE_BAK = new File(CONFIG_DIRECTORY, "auth.xml.bak"); + private static ReadWriteLock aLock = new ReentrantReadWriteLock(true); + + // File size localized strings + + private static final Map schemeIconMap = new HashMap(); + private static final Set archivesSuffixes = new HashSet(); + + static { + schemeIconMap.put("file", ResourcesUtil.getIcon("drive")); + schemeIconMap.put("sftp", ResourcesUtil.getIcon("networkCloud")); + schemeIconMap.put("ftp", ResourcesUtil.getIcon("networkCloud")); + schemeIconMap.put("smb", ResourcesUtil.getIcon("sambaShare")); + schemeIconMap.put("http", ResourcesUtil.getIcon("networkCloud")); + schemeIconMap.put("https", ResourcesUtil.getIcon("networkCloud")); + schemeIconMap.put("zip", ResourcesUtil.getIcon("folderZipper")); + schemeIconMap.put("tar", ResourcesUtil.getIcon("folderZipper")); + schemeIconMap.put("jar", ResourcesUtil.getIcon("jarIcon")); + schemeIconMap.put("tgz", ResourcesUtil.getIcon("folderZipper")); + schemeIconMap.put("tbz", ResourcesUtil.getIcon("folderZipper")); + + archivesSuffixes.add("zip"); + archivesSuffixes.add("tar"); + archivesSuffixes.add("jar"); + archivesSuffixes.add("tgz"); + archivesSuffixes.add("gz"); + archivesSuffixes.add("bz2"); + archivesSuffixes.add("tar"); + archivesSuffixes.add("tbz"); + archivesSuffixes.add("tgz"); + + } + + public static FileSystemManager getFileSystemManager() { + aLock.readLock().lock(); + + try { + if (fileSystemManager == null) { + try { + EngysFileSystemManager fm = new EngysFileSystemManager(); + // fm.setClassLoader(StandardFileSystemManager.class.getClassLoader()); + fm.setConfiguration(StandardFileSystemManager.class.getResource("providers.xml")); + fm.setCacheStrategy(CacheStrategy.MANUAL); + fm.init(); + logger.trace("Supported schemes: {} ", Joiner.on(", ").join(fm.getSchemes())); + fileSystemManager = fm; + } catch (Exception exc) { + throw new RuntimeException(exc); + } + } + + return fileSystemManager; + } finally { + aLock.readLock().unlock(); + } + } + + public static String getFriendlyName(String fileName) { + return getFriendlyName(fileName, true); + } + + public static String getFriendlyName(String fileName, boolean excludeLocalFilePrefix) { + if (fileName == null) { + return ""; + } + StringBuilder filePath = new StringBuilder(); + + int pos = fileName.lastIndexOf('@'); + + if (pos == -1) { + filePath.append(fileName); + } else { + int pos2 = fileName.indexOf(UNIX_PROTOCOL_PREFIX); + + if (pos2 == -1) { + filePath.append(fileName); + } else { + String protocol = fileName.substring(0, pos2); + + filePath.append(protocol).append(UNIX_PROTOCOL_PREFIX).append(fileName.substring(pos + 1, fileName.length())); + } + } + + String returnedString = filePath.toString(); + + if (excludeLocalFilePrefix && returnedString.startsWith(LocationType.file.toString())) { + return filePath.substring(LocationType.file.toString().length()); + } + + return returnedString; + } + + public static FileObject createFileSystemRoot(FileObject fileObject) { + try { + return fileObject.getFileSystem().getRoot(); + } catch (FileSystemException ex) { + return null; + } + } + + public static FileObject[] getFiles(Component parent, FileObject folder) { + try { + return getChildren(folder); + } catch (FileSystemException ex) { + String url = folder == null ? "non existing file" : folder.getName().getPath(); + VFSUtils.showErrorMessage(parent, url, ex); + return new FileObject[0]; + } + } + + public static FileObject getRootFileSystem(FileObject fileObject) { + try { + if ((fileObject == null) || !fileObject.exists()) { + return null; + } + + return fileObject.getFileSystem().getRoot(); + } catch (FileSystemException ex) { + return null; + } + } + + public static boolean isHiddenFile(FileObject fileObject) { + try { + return fileObject.getName().getBaseName().charAt(0) == '.'; + } catch (Exception ex) { + return false; + } + } + + public static boolean isRoot(FileObject fileObject) { + try { + return fileObject.getParent() == null; + } catch (FileSystemException ex) { + return false; + } + } + + public static FileObject resolveFileObject(String filePath) throws FileSystemException { + return resolveFileObject(filePath, null); + } + + public static FileObject resolveFileObject(String filePath, SshParameters sshParameters) throws FileSystemException { + logger.trace("Resolving file: {}", filePath); + if (filePath.startsWith(LocationType.sftp.toString())) { + SftpFileSystemConfigBuilder builder = SftpFileSystemConfigBuilder.getInstance(); + builder.setStrictHostKeyChecking(fileSystemOptions, "no"); + builder.setUserDirIsRoot(fileSystemOptions, false); + builder.setCompression(fileSystemOptions, "zlib,none"); + } + + AuthStore sessionAuthStore = new MemoryAuthStore(); + if (sshParameters != null) { + String host = sshParameters.getHost(); + String user = sshParameters.getUser(); + String pwd = sshParameters.getSshpwd(); + String key = sshParameters.getSshkey(); + int port = sshParameters.getPort(); + if (host != null && user != null && pwd != null && key != null) { + setAuthenticationFromSSHParameters(sessionAuthStore, host, user, pwd, key); + } + } + return resolveFileObject(sessionAuthStore, filePath); + } + + private static void setAuthenticationFromSSHParameters(AuthStore sessionAuthStore, String host, String user, String pwd, String key) { + UserAuthenticationInfo auInfo = new UserAuthenticationInfo(Protocol.SFTP.getName(), host, user); + UserAuthenticationDataWrapper authenticationData = new UserAuthenticationDataWrapper(); + authenticationData.setData(UserAuthenticationData.USERNAME, user.toCharArray()); + authenticationData.setData(UserAuthenticationData.PASSWORD, pwd.toCharArray()); + authenticationData.setData(UserAuthenticationDataWrapper.SSH_KEY, key.toCharArray()); + sessionAuthStore.add(auInfo, authenticationData); + } + + private static FileObject resolveFileObject(AuthStore sessionAuthStore, String filePath) throws FileSystemException { + UserAuthenticatorFactory factory = new UserAuthenticatorFactory(); + OtrosUserAuthenticator authenticator = factory.getUiUserAuthenticator(sessionAuthStore, filePath, fileSystemOptions); + if (filePath.startsWith(LocationType.sftp.toString())) { + SftpFileSystemConfigBuilder builder = SftpFileSystemConfigBuilder.getInstance(); + builder.setStrictHostKeyChecking(fileSystemOptions, "no"); + builder.setUserDirIsRoot(fileSystemOptions, false); + builder.setCompression(fileSystemOptions, "zlib,none"); + + } + + DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(fileSystemOptions, authenticator); + FileObject resolveFile; + try { + resolveFile = getFileSystemManager().resolveFile(filePath, fileSystemOptions);// SLOW ACTION (circa 120ms) + resolveFile.getType(); + } catch (FileSystemException e) { + logger.error("Error resolving file " + filePath, e.getMessage()); + e.printStackTrace(); + throw e; + } + return resolveFile; + } + + public static boolean exists(FileObject fileObject) { + if (fileObject == null) { + return false; + } + + try { + return fileObject.exists(); + } catch (FileSystemException ex) { + return false; + } + } + + public static boolean isDirectory(FileObject fileObject) { + try { + return fileObject.getType().equals(FileType.FOLDER); + } catch (FileSystemException ex) { + logger.info("Exception when checking if fileobject is folder", ex); + return false; + } + } + + public static boolean isLocalFile(FileObject fileObject) { + try { + return fileObject.getURL().getProtocol().equalsIgnoreCase("file") && FileType.FILE.equals(fileObject.getType()); + } catch (FileSystemException e) { + logger.info("Exception when checking if fileobject is local file", e); + return false; + } + } + + public static boolean isFileSystemRoot(FileObject folder) { + return isRoot(folder); + } + + public static boolean isParent(FileObject folder, FileObject file) { + try { + FileObject parent = file.getParent(); + + return parent != null && parent.equals(folder); + + } catch (FileSystemException ex) { + return false; + } + } + + public static String getRemoteUserHome(SshParameters sshParameters) throws FileSystemException { + return "/home/" + sshParameters.getUser(); + } + + public static FileObject getUserHome() throws FileSystemException { + return resolveFileObject(Util.isUnix() ? PrefUtil.USER_DIR : PrefUtil.USER_HOME); + } + + public static void checkForSftpLinks(FileObject[] files, TaskContext taskContext) { + logger.trace("Checking for SFTP links"); + taskContext.setMax(files.length); + long ts = System.currentTimeMillis(); + for (int i = 0; i < files.length && !taskContext.isStop(); i++) { + FileObject fileObject = files[i]; + try { + if (fileObject instanceof SftpFileObject) { + SftpFileObject sftpFileObject = (SftpFileObject) fileObject; + long size = sftpFileObject.getContent().getSize(); + if (sftpFileObject.getType() == FileType.FILE && size < SYMBOLIC_LINK_MAX_SIZE && size != 0) { + if (!pointToItself(sftpFileObject)) { + files[i] = new LinkFileObject(sftpFileObject); + } + } + + } + taskContext.setCurrentProgress(i); + } catch (Exception e) { + + } + + } + long checkDuration = System.currentTimeMillis() - ts; + logger.trace("Checking SFTP links took {} ms [{}ms/file]", checkDuration, (float) checkDuration / files.length); + } + + public static boolean pointToItself(FileObject fileObject) throws FileSystemException { + if (!fileObject.getURL().getProtocol().equalsIgnoreCase("file") && FileType.FILE.equals(fileObject.getType())) { + logger.trace("Checking if {} is pointing to itself", fileObject.getName().getFriendlyURI()); + FileObject[] children = VFSUtils.getChildren(fileObject); + logger.trace("Children number of {} is {}", fileObject.getName().getFriendlyURI(), children.length); + if (children.length == 1) { + FileObject child = children[0]; + if (child.getContent().getSize() != child.getContent().getSize()) { + return false; + } + if (child.getName().getBaseName().equals(fileObject.getName().getBaseName())) { + return true; + } + } + } + return false; + } + + public static FileObject[] getChildren(FileObject fileObject) throws FileSystemException { + FileObject[] result; + if (isLocalFileSystem(fileObject) && isArchive(fileObject)) { + String extension = fileObject.getName().getExtension(); + result = VFSUtils.resolveFileObject(extension + ":" + fileObject.getURL().toString() + "!/").getChildren(); + } else { + result = fileObject.getChildren(); + } + return filterInvalidFiles(result); + } + + private static FileObject[] filterInvalidFiles(FileObject[] result) { + List validFileObjects = new ArrayList<>(); + for (FileObject fo : result) { + if (fo.getName() instanceof InvalidFileName) { + logger.warn("Invalid filename filtered: {}", ((InvalidFileName) fo.getName()).getOriginalName()); + } else { + if (isLocalFileSystem(fo) && isInvalidFolder(fo)) { + logger.warn("Invalid folder filtered: {}", fo.getName()); + } else { + validFileObjects.add(fo); + } + } + } + return validFileObjects.toArray(new FileObject[0]); + } + + private static boolean isInvalidFolder(FileObject folder) { + try { + if (folder.getType() != FileType.FOLDER) { + return false; + } + + File file = new File(decode(folder.getName().getURI(), null)); + String[] files = UriParser.encode(file.list()); + + return files == null; + } catch (Exception e) { + return true; + } + } + + public static boolean isArchive(FileObject fileObject) { + return isArchive(fileObject.getName()); + } + + public static boolean isArchive(FileName fileName) { + String extension = fileName.getExtension(); + return archivesSuffixes.contains(extension.toLowerCase()); + } + + private static boolean isLocalFileSystem(FileObject fileObject) { + return fileObject.getName().getScheme().equalsIgnoreCase("file"); + } + + public static Icon getIconForFileSystem(String url) { + String schema = "file"; + if (null != url) { + int indexOf = url.indexOf(UNIX_PROTOCOL_PREFIX); + if (indexOf > 0) { + schema = url.substring(0, indexOf); + } + } + return schemeIconMap.get(schema); + } + + public static boolean canGoUrl(FileObject fileObject) throws FileSystemException { + if (VFSUtils.pointToItself(fileObject)) { + return false; + } + if (VFSUtils.isLocalFile(fileObject)) { + return false; + } + return true; + + } + + public static String encode(String url, SshParameters sshParameters) { + String fixedUrl = url.replace("\\", "/"); + if (sshParameters != null) { + String host = sshParameters.getHost(); + String port = String.valueOf(sshParameters.getPort()); + String typePrefix = LocationType.sftp.toString(); + if (port.equals(DEFAULT_SSH_PORT)) { + return typePrefix + host + fixedUrl; + } else { + return typePrefix + host + ":" + port + fixedUrl; + } + } else { + String typePrefix = LocationType.file.toString(); + return typePrefix + fixedUrl; + } + } + + public static String decode(String path, SshParameters sshParameters) { + if (path.startsWith(LocationType.file.toString())) { + return StringUtils.removeStart(path, LocationType.file.toString()); + } else if (path.startsWith(LocationType.sftp.toString()) && sshParameters != null) { + String noType = StringUtils.removeStart(path, LocationType.sftp.toString()); + String noHost = StringUtils.removeStart(noType, sshParameters.getHost()); + String noPort = StringUtils.removeStart(noHost, ":" + sshParameters.getPort()); + return noPort; + } + return null; + } + + public static void showErrorMessage(final Component parent, final String url, final Exception e) { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + String message = "Error opening " + url; + if (e != null) { + message += "\n" + e.getMessage(); + if (message.contains("descendent")) { + message = message.replace("descendent", ""); + } + } + logger.error(message); + JOptionPane.showMessageDialog(parent, message, "File System Error", JOptionPane.ERROR_MESSAGE); + } + }); + } +} diff --git a/src/eu/engys/util/plaf/HelyxOSLookAndFeel.java b/src/eu/engys/util/plaf/HelyxOSLookAndFeel.java new file mode 100644 index 0000000..5b1b433 --- /dev/null +++ b/src/eu/engys/util/plaf/HelyxOSLookAndFeel.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.plaf; + +import javax.swing.UIManager; + +import com.pagosoft.plaf.PgsLookAndFeel; +import com.pagosoft.plaf.PlafOptions; + +public class HelyxOSLookAndFeel implements ILookAndFeel { + + private final double[] BG_COLOR = { 0.8, 0.8, 0.8 }; + private final double[] BG2_COLOR = { 0.2, 0.2, 0.2 }; + private final double[] SELECT_COLOR = { 1.0, 1.0, 1.0 }; + + @Override + public double[] get3DColor1() { + return BG_COLOR; + } + + @Override + public double[] get3DColor2() { + return BG2_COLOR; + } + + @Override + public double[] get3DSelectionColor() { + return SELECT_COLOR; + } + + @Override + public int getMainWidth() { + return 650; + } + + @Override + public int getSecondaryWidth() { + return 180; + } + + @Override + public void init() { + initPgsLAF(); + } + + private void initPgsLAF() { + try { + PlafOptions.setClearBorderEnabled(true); + PlafOptions.useExtraMargin(false); + PlafOptions.useShadowBorder(false); + PlafOptions.setOfficeScrollBarEnabled(true); + UIManager.setLookAndFeel(new PgsLookAndFeel()); + } catch (Exception e) { + } + + } +} diff --git a/src/eu/engys/util/plaf/ILookAndFeel.java b/src/eu/engys/util/plaf/ILookAndFeel.java new file mode 100644 index 0000000..32dbe88 --- /dev/null +++ b/src/eu/engys/util/plaf/ILookAndFeel.java @@ -0,0 +1,42 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.plaf; + + +public interface ILookAndFeel { + + public void init(); + + public double[] get3DColor1(); + public double[] get3DColor2(); + + public double[] get3DSelectionColor(); + + public int getMainWidth(); + public int getSecondaryWidth(); + +} diff --git a/src/eu/engys/util/plaf/TestLookAndFeel.java b/src/eu/engys/util/plaf/TestLookAndFeel.java new file mode 100644 index 0000000..a3e7d23 --- /dev/null +++ b/src/eu/engys/util/plaf/TestLookAndFeel.java @@ -0,0 +1,66 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.plaf; + + +public class TestLookAndFeel implements ILookAndFeel { + + private static final double[] BG_COLOR = {0.3, 0.6, 0.9}; + private static final double[] BG2_COLOR = {0.1, 0.2, 0.4}; + private static final double[] SELECT_COLOR = {1.0, 1.0, 1.0}; + + @Override + public double[] get3DColor1() { + return BG_COLOR; + } + + @Override + public double[] get3DColor2() { + return BG2_COLOR; + } + + @Override + public double[] get3DSelectionColor() { + return SELECT_COLOR; + } + + @Override + public int getMainWidth() { + return 550; + } + + @Override + public int getSecondaryWidth() { + return 180; + } + + @Override + public void init() { + } + +} + diff --git a/src/eu/engys/util/progress/ConsoleMonitor.java b/src/eu/engys/util/progress/ConsoleMonitor.java new file mode 100644 index 0000000..0ea2e2d --- /dev/null +++ b/src/eu/engys/util/progress/ConsoleMonitor.java @@ -0,0 +1,181 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.progress; + +import java.awt.Window; +import java.util.List; +import java.util.concurrent.Callable; + +import javax.swing.JDialog; + +public class ConsoleMonitor implements ProgressMonitor { + + @Override + public void setTotal(int i) { + } + + @Override + public int getTotal() { + return 0; + } + + @Override + public void setParent(Window parent) { + } + + @Override + public void start(String message, boolean canStop, Runnable r) { + System.out.println("START " + message); + r.run(); + } + + @Override + public void start(String message) { + System.out.println("START " + message); + } + + @Override + public void end() { + System.out.println("END"); + } + + @Override + public void error(String message) { + System.err.println("ERROR: " + message); + } + + @Override + public void error(String message, int indentLevel) { + System.err.println("ERROR: " + message); + } + + @Override + public void info(String message) { + System.out.println("INFO: " + message); + } + + @Override + public void infoN(String message) { + System.out.print("INFO: " + message); + } + + @Override + public void info(String message, int indentLevel) { + System.out.println("INFO: " + message); + } + + @Override + public void infoN(String message, int indentLevel) { + System.out.println("INFO: " + message); + } + + @Override + public void debug(String message) { + System.out.print(message); + } + + @Override + public void warning(String message) { + System.out.println("WARNING: " + message); + } + + @Override + public void warning(String message, int indentLevel) { + System.out.println("WARNING: " + message); + } + + @Override + public void warning(List invalidFiles) { + System.out.println("WARNING: " + invalidFiles); + } + + @Override + public int getCurrent() { + return 0; + } + + @Override + public void setCurrent(String string, int i) { + } + + @Override + public void setCurrent(String string, int i, int indentLevel) { + } + + @Override + public void setCurrent(String string, int min, int max, int indentLevel) { + } + + @Override + public String getMessages() { + return null; + } + + @Override + public boolean hasErrors() { + return false; + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isIndeterminate() { + return false; + } + + @Override + public void setIndeterminate(boolean b) { + } + + @Override + public Boolean start(String message, boolean canStop, Callable c) { + System.out.println("START " + message); + try { + return c.call(); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + @Override + public JDialog getDialog() { + return null; + } + + @Override + public boolean canStop() { + return false; + } + + @Override + public void stop() { + } +} diff --git a/src/eu/engys/util/progress/ProgressBar.java b/src/eu/engys/util/progress/ProgressBar.java new file mode 100644 index 0000000..18800b8 --- /dev/null +++ b/src/eu/engys/util/progress/ProgressBar.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ +package eu.engys.util.progress; + +import javax.swing.JProgressBar; + +import eu.engys.util.ui.ExecUtil; + +public class ProgressBar extends JProgressBar { + + private int value; + + public ProgressBar(int min, int max) { + super(min, max); + } + + @Override + public void setValue(final int value) { + this.value = value; + ExecUtil.invokeLater(new Runnable() { + public void run() { + ProgressBar.super.setValue(value); + } + }); + } + + @Override + public int getValue() { + return value; + } + + @Override + public void setIndeterminate(final boolean b) { + ExecUtil.invokeLater(new Runnable() { + public void run() { + ProgressBar.super.setIndeterminate(b); + } + }); + } +} diff --git a/src/eu/engys/util/progress/ProgressDialog.java b/src/eu/engys/util/progress/ProgressDialog.java new file mode 100644 index 0000000..7512df6 --- /dev/null +++ b/src/eu/engys/util/progress/ProgressDialog.java @@ -0,0 +1,261 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.progress; + +import java.awt.BorderLayout; +import java.awt.HeadlessException; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BoundedRangeModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JEditorPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; + +public class ProgressDialog extends JDialog { + + private final Action CLOSE_ACTION = new AbstractAction("Close") { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + }; + + private final Action STOP_ACTION = new AbstractAction("Stop") { + @Override + public void actionPerformed(ActionEvent e) { + monitor.stop(); + } + }; + + private JEditorPane statusArea = new JEditorPane("text/html", null); + private ProgressBar progressBar; + private JCheckBox keepOpen; + private ProgressMonitor monitor; + + private JButton closeButton; + private JButton stopButton; + + public ProgressDialog(Window window) throws HeadlessException { + super(window, "Progress", JDialog.DEFAULT_MODALITY_TYPE); + setSize(500, 300); + setLocationRelativeTo(null); + } + + public void init(ProgressMonitor monitor) { + this.monitor = monitor; + + progressBar = new ProgressBar(0, monitor.getTotal()); + + if (monitor.isIndeterminate()) { + progressBar.setIndeterminate(true); + progressBar.setStringPainted(false); + } else { + progressBar.setStringPainted(monitor.getTotal() > 0); + progressBar.setValue(monitor.getCurrent() < 0 ? 0 : monitor.getCurrent()); + } + + keepOpen = new JCheckBox("Keep dialog open on errors", true); + + statusArea.setText(monitor.getMessages()); + + final JScrollPane statusScrollPane = new JScrollPane(statusArea); + statusScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { + + BoundedRangeModel brm = statusScrollPane.getVerticalScrollBar().getModel(); + boolean wasAtBottom = true; + + public void adjustmentValueChanged(AdjustmentEvent e) { + if (!brm.getValueIsAdjusting()) { + if (wasAtBottom) + brm.setValue(brm.getMaximum()); + } else + wasAtBottom = ((brm.getValue() + brm.getExtent()) == brm.getMaximum()); + + } + }); + + JPanel centerPanel = new JPanel(new BorderLayout()); + centerPanel.add(statusScrollPane, BorderLayout.CENTER); + centerPanel.add(keepOpen, BorderLayout.SOUTH); + + closeButton = new JButton(CLOSE_ACTION); + stopButton = new JButton(STOP_ACTION); + + List buttons = new ArrayList(); + buttons.add(closeButton); + buttons.add(stopButton); + JComponent buttonsPanel = UiUtil.getCommandRow(buttons); + + JPanel contents = (JPanel) getContentPane(); + contents.setLayout(new BorderLayout(UiUtil.STANDARD_BORDER, UiUtil.STANDARD_BORDER)); + contents.setBorder(UiUtil.getStandardBorder()); + contents.add(progressBar, BorderLayout.NORTH); + contents.add(centerPanel, BorderLayout.CENTER); + contents.add(buttonsPanel, BorderLayout.SOUTH); + + setDefaultCloseOperation(HIDE_ON_CLOSE); + closeButton.setVisible(false); + stopButton.setVisible(false); + } + + public void start() { + ExecUtil.invokeLater(new Runnable() { + public void run() { + _start(); + } + }); + } + + public void startImmediately() { + ExecUtil.invokeAndWait(new Runnable() { + public void run() { + _start(); + } + }); + } + + private void _start() { + _update(); + + stopButton.setVisible(monitor.canStop()); + + if (!monitor.isFinished()) { + setVisible(true); + } + } + + public void end() { + if (isVisible()) { + ExecUtil.invokeAndWait(new Runnable() { + public void run() { + _end(); + } + }); + } else { + ExecUtil.invokeLater(new Runnable() { + public void run() { + _end(); + } + }); + } + } + + private void _end() { + if (monitor.isFinished()) { + progressBar.setIndeterminate(false); + progressBar.setValue(progressBar.getMaximum()); + String messages = monitor.getMessages(); + statusArea.setText(messages); + + if (!(keepOpen.isSelected() && monitor.hasErrors())) { + if (isVisible()) { + setVisible(false); + } + } + closeButton.setVisible(isVisible()); + stopButton.setVisible(false); + } else { + } + } + + public void update() { + ExecUtil.invokeLater(new Runnable() { + public void run() { + _update(); + } + }); + } + + private void _update() { + if (monitor.getCurrent() != monitor.getTotal()) { + String messages = monitor.getMessages(); + statusArea.setText(messages); + + if (monitor.isIndeterminate() != progressBar.isIndeterminate()) { + progressBar.setIndeterminate(monitor.isIndeterminate()); + progressBar.setStringPainted(false); + } + + if (!monitor.isIndeterminate()) { + if (monitor.getTotal() != progressBar.getMaximum()) + progressBar.setMaximum(monitor.getTotal()); + + if (monitor.getTotal() > 0) { + progressBar.setStringPainted(true); + progressBar.setValue(monitor.getCurrent()); + } else { + progressBar.setStringPainted(false); + } + } + + } else { + progressBar.setStringPainted(true); + progressBar.setValue(progressBar.getMaximum()); +// CLOSE_ACTION.setEnabled(true); + } + } + + public static void runOnEDT(final Runnable runnable) { + if (SwingUtilities.isEventDispatchThread()) { + // System.out.println("ProgressDialog.runOnEDT() is EDT"); + // Thread.dumpStack(); + runnable.run(); + } else { + SwingUtilities.invokeLater(runnable); + } + } + + public static void waitOnEDT(final Runnable runnable) { + if (SwingUtilities.isEventDispatchThread()) { + // System.out.println("ProgressDialog.runOnEDT() is EDT"); + // Thread.dumpStack(); + runnable.run(); + } else { + try { + SwingUtilities.invokeAndWait(runnable); + } catch (InvocationTargetException | InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/eu/engys/util/progress/ProgressMonitor.java b/src/eu/engys/util/progress/ProgressMonitor.java new file mode 100644 index 0000000..78ddbd1 --- /dev/null +++ b/src/eu/engys/util/progress/ProgressMonitor.java @@ -0,0 +1,79 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.progress; + +import java.awt.Window; +import java.util.List; +import java.util.concurrent.Callable; + +import javax.swing.JDialog; + +public interface ProgressMonitor { + + void setTotal(int i); + int getTotal(); + + + void start(String string, boolean canStop, Runnable r); + Boolean start(String string, boolean canStop, Callable c); + + void start(String string); + void end(); + + void debug(String message); + void error(String message); + void error(String message, int indentLevel); + void info(String message); + void info(String message, int indentLevel); + void infoN(String message); + void infoN(String message, int indentLevel); + void warning(String message); + void warning(String message, int indentLevel); + void warning(List invalidFiles); + + int getCurrent(); + void setCurrent(String string, int i); + void setCurrent(String string, int i, int indentLevel); + void setCurrent(String string, int min, int max, int indentLevel); + + + String getMessages(); + + boolean hasErrors(); + + boolean isFinished(); + + boolean isIndeterminate(); + void setIndeterminate(boolean b); + public JDialog getDialog(); + + void setParent(Window parent); + + boolean canStop(); + void stop(); + +} diff --git a/src/eu/engys/util/progress/ProgressMonitorImpl.java b/src/eu/engys/util/progress/ProgressMonitorImpl.java new file mode 100644 index 0000000..45c1c43 --- /dev/null +++ b/src/eu/engys/util/progress/ProgressMonitorImpl.java @@ -0,0 +1,358 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.progress; + +import java.awt.Window; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import javax.inject.Inject; + +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; + +public class ProgressMonitorImpl implements ProgressMonitor { + + // private static final Logger logger = + // LoggerFactory.getLogger(ProgressMonitorImpl.class); + + private static final String INDENT = " "; + + private static final String START = "
";
+	private static final String END = "
"; + + private static final String START_INFO = ""; + private static final String END_INFO = "\n"; + private static final String END_INFO_N = ""; + + private static final String START_B = ""; + private static final String END_B = " currentTask = null; + private boolean stoppable = false; + + @Override + public void start(String status, boolean canStop, Runnable r) { + final ExecutorService executor = Executors.newSingleThreadExecutor(); + this.currentTask = executor.submit(r); + prepareStart(status, canStop); + dialog().start(); + try { + currentTask.get(); + } catch (ExecutionException | InterruptedException e) { + error(e); + executor.shutdownNow(); + end(); + e.printStackTrace(); + } + } + + @Override + public Boolean start(String status, boolean canStop, final Callable c) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future task = executor.submit(c); + prepareStart(status, canStop); + dialog().start(); + try { + return task.get(); + } catch (ExecutionException | InterruptedException e) { + e.printStackTrace(); + } + return false; + } + + @Override + public void start(String status) { + prepareStart(status, false); + dialog().start(); + } + + private void prepareStart(String status, boolean canStop) { + stoppable = canStop; + finished = false; + hasErrors = false; + if (current != -1) { + current = -1; + } + sb.append(START); + if (status != null) + info(START_B + status + END_B); + current = 0; + } + + @Override + public boolean canStop() { + return stoppable; + } + + @Override + public void stop() { + if (stoppable) { + if (currentTask != null) { + currentTask.cancel(true); + } + } + } + + @Override + public void end() { + finished = true; + if (current != total) + current = total; + dialog().end(); + } + + @Override + public int getCurrent() { + return current; + } + + @Override + public String getMessages() { + return sb.toString() + END; + } + + @Override + public boolean isIndeterminate() { + return indeterminate; + } + + @Override + public void setIndeterminate(boolean indeterminate) { + this.indeterminate = indeterminate; + dialog().update(); + } + + @Override + public void setCurrent(String msg, int current) { + if (current == -1) + throw new IllegalStateException("not started yet"); + this.current = current; + if (msg != null) + info(msg); + dialog().update(); + } + + @Override + public void setCurrent(String msg, int current, int indentLevel) { + if (current == -1) + throw new IllegalStateException("not started yet"); + this.current = current; + if (msg != null) + info(msg, indentLevel); + dialog().update(); + } + + @Override + public void setCurrent(String msg, int min, int max, int indentLevel) { + if (current == -1) + throw new IllegalStateException("not started yet"); + this.total = max; + this.current = min; + if (msg != null) { + sb.append(START_INFO); + sb.append(addIndentation(msg, indentLevel)); + sb.append(END_INFO); + } + dialog().update(); + } + + @Override + public boolean isFinished() { + return finished; + } + + @Override + public void info(String message, int indentLevel) { + info(addIndentation(message, indentLevel)); + } + + @Override + public void infoN(String message, int indentLevel) { + infoN(addIndentation(message, indentLevel)); + } + + @Override + public void info(String message) { + sb.append(START_INFO); + sb.append(message); + sb.append(END_INFO); + dialog().update(); + } + + @Override + public void infoN(String message) { + sb.append(START_INFO); + sb.append(message); + sb.append(END_INFO_N); + dialog().update(); + } + + @Override + public void warning(String message, int indentLevel) { + warning(addIndentation(message, indentLevel)); + } + + private static String addIndentation(String message, int indentLevel) { + String toAppend = ""; + for (int i = 0; i < indentLevel; i++) { + toAppend += INDENT; + } + toAppend += message; + return toAppend; + } + + @Override + public void debug(String message) { +// logger.info(message); +// sb.append(START_INFO); + sb.append(message); +// sb.append(END_INFO); + dialog().update(); + } + + @Override + public void warning(String message) { + // logger.warn(message); + sb.append(START_WARING); + sb.append(message); + sb.append(END_WARNING); + dialog().update(); + } + + @Override + public void warning(List list) { + StringBuilder sb = new StringBuilder(); + for (String name : list) { + sb.append("\n"); + sb.append("\t"); + sb.append(name); + } + warning(sb.toString()); + } + + @Override + public void error(String message, int indentLevel) { + error(addIndentation(message, indentLevel)); + } + + @Override + public void error(String message) { + // logger.error(message); + hasErrors = true; + sb.append(START_ERROR); + sb.append(message); + sb.append(END_ERROR); + dialog().update(); + } + + private void error(Throwable t) { + StackTraceElement[] stackTrace = t.getStackTrace(); + StringBuilder sb = new StringBuilder(); + for (StackTraceElement el : stackTrace) { + sb.append(START_ERROR); + sb.append(" "); + sb.append(el.toString()); + sb.append(END_ERROR); + } + } + + @Override + public boolean hasErrors() { + return hasErrors; + } + +} diff --git a/src/eu/engys/util/progress/SilentMonitor.java b/src/eu/engys/util/progress/SilentMonitor.java new file mode 100644 index 0000000..532c028 --- /dev/null +++ b/src/eu/engys/util/progress/SilentMonitor.java @@ -0,0 +1,162 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.progress; + +import java.awt.Window; +import java.util.List; +import java.util.concurrent.Callable; + +import javax.swing.JDialog; + +public class SilentMonitor implements ProgressMonitor { + + @Override + public void setTotal(int i) { + } + + @Override + public int getTotal() { + return 0; + } + + @Override + public void setParent(Window parent) { + } + + @Override + public void start(String string, boolean canStop, Runnable r) { + r.run(); + } + + @Override + public void start(String message) { + } + + @Override + public void end() { + } + + @Override + public void error(String message) { + } + + @Override + public void error(String message, int indentLevel) { + } + + @Override + public void info(String message) { + } + + @Override + public void infoN(String message) { + } + + @Override + public void info(String message, int indentLevel) { + } + + @Override + public void infoN(String message, int indentLevel) { + } + + @Override + public void debug(String message) { + } + + @Override + public void warning(String message) { + } + + @Override + public void warning(String message, int indentLevel) { + } + + @Override + public void warning(List invalidFiles) { + } + + @Override + public int getCurrent() { + return 0; + } + + @Override + public void setCurrent(String string, int i) { + } + + @Override + public void setCurrent(String string, int i, int indentLevel) { + } + + @Override + public void setCurrent(String string, int min, int max, int indentLevel) { + + } + + @Override + public String getMessages() { + return null; + } + + @Override + public boolean hasErrors() { + return false; + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isIndeterminate() { + return false; + } + + @Override + public void setIndeterminate(boolean b) { + } + + @Override + public Boolean start(String string, boolean canStop, Callable c) { + return false; + } + + @Override + public JDialog getDialog() { + return null; + } + @Override + public boolean canStop() { + return false; + } + @Override + public void stop() { + } + +} diff --git a/src/eu/engys/util/progress/VTKProgressConsoleWrapper.java b/src/eu/engys/util/progress/VTKProgressConsoleWrapper.java new file mode 100644 index 0000000..ccc62dc --- /dev/null +++ b/src/eu/engys/util/progress/VTKProgressConsoleWrapper.java @@ -0,0 +1,52 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.progress; + +import vtk.vtkAlgorithm; + +public class VTKProgressConsoleWrapper { + + private vtkAlgorithm algo; + private String title; + + public VTKProgressConsoleWrapper(String title, vtkAlgorithm algo, ProgressMonitor monitor) { + this.title = title; + this.algo = algo; + } + + public void onProgress() { + System.err.println( (int) (algo.GetProgress() * 100)); + } + + public void onStart() { + System.err.println("Loading " + title + "... "); + } + + public void onEnd() { + System.out.println("done"); + } + +} diff --git a/src/eu/engys/util/progress/VTKProgressMonitorWrapper.java b/src/eu/engys/util/progress/VTKProgressMonitorWrapper.java new file mode 100644 index 0000000..2fcf39a --- /dev/null +++ b/src/eu/engys/util/progress/VTKProgressMonitorWrapper.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.progress; + +import vtk.vtkAlgorithm; + +public class VTKProgressMonitorWrapper { + + private vtkAlgorithm algo; + private ProgressMonitor monitor; + private String title; + + public VTKProgressMonitorWrapper(String title, vtkAlgorithm algo, ProgressMonitor monitor) { + this.title = title; + this.algo = algo; + this.monitor = monitor; + } + + public void onProgress() { + monitor.setCurrent(null, (int) (algo.GetProgress() * 100)); + } + + public void onStart() { + monitor.infoN("Loading " + title + "... ", 1); + } + + public void onEnd() { + monitor.info("done"); + } + +} diff --git a/src/eu/engys/util/ui/ASCIIArt.java b/src/eu/engys/util/ui/ASCIIArt.java new file mode 100644 index 0000000..8ddee27 --- /dev/null +++ b/src/eu/engys/util/ui/ASCIIArt.java @@ -0,0 +1,65 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +public class ASCIIArt { + + private static final int VOID = -16777216; + + public static String toAA(String text) { + int width = 200; + int height = 30; + + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.getGraphics(); + g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12)); + + Graphics2D graphics = (Graphics2D) g; +// graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + graphics.drawString(text, 0, 20); + + StringBuilder sb = new StringBuilder(); + for (int y = 0; y < height; y++) { + StringBuilder row = new StringBuilder(); + for (int x = 0; x < width; x++) { + int rgb = image.getRGB(x, y); + row.append(rgb == VOID ? " " : "#" ); + } + + if (!row.toString().trim().isEmpty()) { + sb.append(row); + sb.append("\n"); + } + } + + return sb.toString(); + } +} diff --git a/src/eu/engys/util/ui/BigButton.java b/src/eu/engys/util/ui/BigButton.java new file mode 100644 index 0000000..171ff25 --- /dev/null +++ b/src/eu/engys/util/ui/BigButton.java @@ -0,0 +1,40 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui; + +import java.awt.Dimension; + +import javax.swing.Action; +import javax.swing.JButton; + +public class BigButton extends JButton { + public BigButton(Action action) { + super(action); + setName((String) action.getValue(Action.NAME)); + setPreferredSize(new Dimension(120, 60)); + } +} diff --git a/src/eu/engys/util/ui/ButtonBar.java b/src/eu/engys/util/ui/ButtonBar.java new file mode 100644 index 0000000..4fc0816 --- /dev/null +++ b/src/eu/engys/util/ui/ButtonBar.java @@ -0,0 +1,207 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Rectangle; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.AbstractButton; +import javax.swing.BoxLayout; +import javax.swing.JComponent; + +public class ButtonBar extends JComponent { + private class ButtonBarLayout extends BoxLayout { + + public void layoutContainer(Container container) { + super.layoutContainer(container); + Rectangle rectangle = new Rectangle(); + Component acomponent[]; + int k = (acomponent = container.getComponents()).length; + for (int i = 0; i < k; i++) { + Component component = acomponent[i]; + Rectangle rectangle1 = component.getBounds(); + if (getOrientation() == 0) + rectangle = rectangle1.height <= rectangle.height ? rectangle : rectangle1; + else + rectangle = rectangle1.width <= rectangle.width ? rectangle : rectangle1; + } + + k = (acomponent = container.getComponents()).length; + for (int j = 0; j < k; j++) { + Component component1 = acomponent[j]; + Rectangle rectangle2 = component1.getBounds(); + if (getOrientation() == 0) { + rectangle2.y = rectangle.y; + rectangle2.height = rectangle.height; + } else { + rectangle2.x = rectangle.x; + rectangle2.width = rectangle.width; + } + component1.setBounds(rectangle2); + } + + } + + public ButtonBarLayout(Container container, int i) { + super(container, i); + } + } + + public static final String uiClassID = "ButtonBarUI"; + + public static final int HORIZONTAL = 0; + public static final int VERTICAL = 1; + + private static final String POS_KEY = "JButton.segmentPosition"; + private static final String ONLY = "only"; + private static final String FIRST = "first"; + private static final String MIDDLE = "middle"; + private static final String LAST = "last"; + private int orientation; + + public ButtonBar() { + this(HORIZONTAL); + } + + public String getUIClassID() { + return uiClassID; + } + + public ButtonBar(int orientation) { + this.orientation = orientation; + if (orientation == HORIZONTAL) + setLayout(new ButtonBarLayout(this, ButtonBarLayout.LINE_AXIS)); + else + setLayout(new ButtonBarLayout(this, ButtonBarLayout.PAGE_AXIS)); + setName("ButtonBar"); + } + + public Component add(Component component) { + return addButton((AbstractButton) component); + } + + public AbstractButton addButton(AbstractButton abstractbutton) { + abstractbutton.getMaximumSize(); + Component acomponent[] = getComponents(); + int i = acomponent.length; + String s = null; + if (i == 0) + s = ONLY; + else if (i >= 1) { + s = LAST; + AbstractButton abstractbutton1 = (AbstractButton) acomponent[i - 1]; + if (i == 1) + abstractbutton1.putClientProperty(POS_KEY, FIRST); + else + abstractbutton1.putClientProperty(POS_KEY, MIDDLE); + } + abstractbutton.putClientProperty(POS_KEY, s); + abstractbutton.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent propertychangeevent) { + if ("componentOrientation".equals(propertychangeevent.getPropertyName())) { + JComponent jcomponent = (JComponent) propertychangeevent.getSource(); + String s1 = (String) jcomponent.getClientProperty(POS_KEY); + if (s1.equals(FIRST) || s1.equals(LAST)) + jcomponent.putClientProperty(POS_KEY, s1.equals(FIRST) ? LAST : FIRST); + } + } + + }); + super.add(abstractbutton); + return abstractbutton; + } + + public void remove(Component component) { + removeButton((AbstractButton) component); + } + + public void removeButton(AbstractButton abstractbutton) { + Component acomponent[] = getComponents(); + int i = acomponent.length; + int j = 0; + Component acomponent1[]; + int l = (acomponent1 = acomponent).length; + for (int k = 0; k < l; k++) { + Component component = acomponent1[k]; + if (component == abstractbutton) + break; + j++; + } + + if (i == j) + return; + String s = null; + AbstractButton abstractbutton1 = null; + if (i == 2) { + s = ONLY; + abstractbutton1 = j != 0 ? (AbstractButton) acomponent[0] : (AbstractButton) acomponent[1]; + } else if (i > 2) + if (j == 0) { + s = FIRST; + abstractbutton1 = (AbstractButton) acomponent[j + 1]; + } else if (j == i - 1) { + s = LAST; + abstractbutton1 = (AbstractButton) acomponent[j - 1]; + } + if (abstractbutton1 != null) + abstractbutton1.putClientProperty(POS_KEY, s); + super.remove(abstractbutton); + } + + public int getOrientation() { + return orientation; + } + + // public static void main(String[] args) { + // SwingUtilities.invokeLater(new Runnable() { + // + // @Override + // public void run() { + // new HelyxLookAndFeel().init(); + // + // ButtonBar bar = new ButtonBar(); + // bar.add(new JButton("pippo")); + // bar.add(new JButton("3")); + // + // JToolBar toolBar = new JToolBar(JToolBar.HORIZONTAL); + // toolBar.add(new JButton("pippo1")); + // toolBar.add(new JButton("pippo2")); + // toolBar.add(bar); + // toolBar.setRollover(true); + // + // JPanel panel = new JPanel(new BorderLayout()); + // panel.add(toolBar, BorderLayout.NORTH); + // panel.add(new JLabel(""), BorderLayout.CENTER); + // + // UiUtil.show("prova", panel); + // } + // }); + // } +} diff --git a/src/eu/engys/util/ui/CheckBoxPanel.java b/src/eu/engys/util/ui/CheckBoxPanel.java new file mode 100644 index 0000000..ef03fb1 --- /dev/null +++ b/src/eu/engys/util/ui/CheckBoxPanel.java @@ -0,0 +1,95 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.UIManager; + +import eu.engys.util.ui.builder.PanelBuilder; + +public class CheckBoxPanel extends JPanel { + + private JCheckBox titleComponent; // displayed in the titled border + + private PanelBuilder builder; + + public CheckBoxPanel(PanelBuilder builder, JCheckBox checkBox) { + this.builder = builder; + this.titleComponent = checkBox; + + layoutComponents(); + } + + private void layoutComponents() { + setLayout(new BorderLayout()); + + add(titleComponent, BorderLayout.CENTER); + add(builder.getPanel(), BorderLayout.CENTER); + + setBorder(new ComponentTitledBorder(null, titleComponent)); + + setupTitleComponent(); + placeTitleComponent(); + } + + private void placeTitleComponent() { + Insets insets = this.getInsets(); + Rectangle containerRectangle = this.getBounds(); + Rectangle componentRectangle = ((ComponentTitledBorder) getBorder()).getComponentRect(containerRectangle, insets); + titleComponent.setBounds(componentRectangle); + } + + private void setupTitleComponent() { + Font font = BorderFactory.createTitledBorder("").getTitleFont(); + Color color = BorderFactory.createTitledBorder("").getTitleColor(); + color = UIManager.getColor("TitledBorder.titleColor"); + + titleComponent.setFont(font); + titleComponent.setForeground(color); + titleComponent.setFocusable(false); + titleComponent.setContentAreaFilled(false); + + titleComponent.addActionListener(new CheckBoxPanel.EnableDisableAction()); + } + + private class EnableDisableAction implements ActionListener { + public void actionPerformed(ActionEvent e) { + builder.setEnabled(titleComponent.isSelected()); + } + } + +} diff --git a/src/eu/engys/util/ui/ChooseFileAction.java b/src/eu/engys/util/ui/ChooseFileAction.java new file mode 100644 index 0000000..2491123 --- /dev/null +++ b/src/eu/engys/util/ui/ChooseFileAction.java @@ -0,0 +1,80 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.event.ActionEvent; +import java.io.File; + +import javax.swing.AbstractAction; +import javax.swing.SwingUtilities; + +import eu.engys.util.Symbols; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.textfields.FileTextField; + +public class ChooseFileAction extends AbstractAction { + + private final FileTextField textField; + private final SelectionMode mode; + private boolean selectFile; + + ChooseFileAction(boolean selectFile, FileTextField textField, SelectionMode mode) { + super(Symbols.DOTS); + this.selectFile = selectFile; + this.textField = textField; + this.mode = mode; + } + + @Override + public void actionPerformed(ActionEvent e) { + File file = textField.getValue(); + HelyxFileChooser chooser = null; + if (selectFile) { + chooser = new HelyxFileChooser(); + chooser.selectFile(file); + } else { + if (file != null) { + chooser = new HelyxFileChooser(file.getAbsolutePath()); + } else { + chooser = new HelyxFileChooser(); + } + } + chooser.setParent(SwingUtilities.getWindowAncestor(textField)); + + if (mode != null) { + chooser.setSelectionMode(mode); + } + + ReturnValue retVal = chooser.showOpenDialog(); + if (retVal.isApprove()) { + textField.setValue(chooser.getSelectedFile()); + } + + } + +} diff --git a/src/eu/engys/util/ui/ChooserPanel.java b/src/eu/engys/util/ui/ChooserPanel.java new file mode 100644 index 0000000..d93b898 --- /dev/null +++ b/src/eu/engys/util/ui/ChooserPanel.java @@ -0,0 +1,168 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.Transient; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.AbstractButton; +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JPanel; +import javax.swing.JRadioButton; + +public class ChooserPanel extends JPanel implements ActionListener { + + public static final String NONE = "NONE"; + + private ButtonGroup buttonGroup = new ButtonGroup(); + private Map buttons = new HashMap(); + boolean propagateEnable; + + public ChooserPanel(String title, boolean propagateEnable) { + super(new GridLayout(0, 1, 2, 2)); + this.propagateEnable = propagateEnable; + if (title != null && !title.isEmpty()) { + setBorder(BorderFactory.createTitledBorder(title)); + } + } + + public ChooserPanel(String title) { + this(title, true); + } + + @Override + @Transient + public Dimension getPreferredSize() { + if (buttons.isEmpty()) { + return new Dimension(4, 4); + } + return super.getPreferredSize(); + } + + public String getSelectedState() { + if (buttonGroup.getSelection() != null) + return buttonGroup.getSelection().getActionCommand(); + else + return NONE; + } + + public boolean hasSelection() { + return buttonGroup.getSelection() != null; + } + + public void selectFirst() { + if (!buttons.isEmpty()) { + buttonGroup.getElements().nextElement().setSelected(true); + } + } + + public void select(String targetField) { + if (buttons.containsKey(targetField)) { + buttons.get(targetField).setSelected(true); + } + } + + public void unselect(String targetField) { + if (!buttons.isEmpty()) { + for (String key : buttons.keySet()) { + if (!key.equals(targetField)) { + buttons.get(key).setSelected(true); + return; + } + } + } + } + + public void selectNone() { + if (!buttons.isEmpty()) { + buttonGroup.clearSelection(); + } + } + + public void reset() { + buttonGroup.clearSelection(); + setEnabled(true); + } + + private JRadioButton createChoice(String choice, int offset) { + JRadioButton radio = new JRadioButton(choice); + radio.setName(choice); + radio.setActionCommand(choice); + radio.addActionListener(this); + radio.setBorder(BorderFactory.createEmptyBorder(0, offset, 0, 0)); + return radio; + } + + public void addChoice(String choice, int offset) { + JRadioButton radio = createChoice(choice, offset); + add(radio); + buttonGroup.add(radio); + buttons.put(choice, radio); + } + + public void addChoice(String choice) { + addChoice(choice, UiUtil.ONE_SPACE); + } + + public void addChoices(int offset, String... choices) { + JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT)); + for (String choice : choices) { + JRadioButton radio = createChoice(choice, offset); + p.add(radio); + buttonGroup.add(radio); + buttons.put(choice, radio); + } + add(p); + } + + public AbstractButton getButton(String key) { + return buttons.get(key); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() instanceof AbstractButton) { + firePropertyChange("selection", false, true); + } + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + if (propagateEnable) { + for (String key : buttons.keySet()) { + buttons.get(key).setEnabled(enabled); + } + } + } +} diff --git a/src/eu/engys/util/ui/ComponentTitledBorder.java b/src/eu/engys/util/ui/ComponentTitledBorder.java new file mode 100644 index 0000000..9f8b7ab --- /dev/null +++ b/src/eu/engys/util/ui/ComponentTitledBorder.java @@ -0,0 +1,202 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Rectangle; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JRadioButton; +import javax.swing.border.Border; +import javax.swing.border.TitledBorder; + +/** + * Special titled border that includes a component in the title area + */ +public class ComponentTitledBorder extends TitledBorder { + JComponent component; + //Border border; + + public ComponentTitledBorder(Border border, JComponent component) { + this(border, component, LEFT, TOP); + } + + public ComponentTitledBorder(Border border, JComponent component, int titleJustification, int titlePosition) { + //TitledBorder needs border, title, justification, position, font, and color + super(border, null, titleJustification, titlePosition, null, null); + this.component = component; + if (border == null) { + this.border = super.getBorder(); + } + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Rectangle borderR = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING, width - (EDGE_SPACING * 2), height - (EDGE_SPACING * 2)); + Insets borderInsets; + if (border != null) { + borderInsets = border.getBorderInsets(c); + } else { + borderInsets = new Insets(0, 0, 0, 0); + } + + Rectangle rect = new Rectangle(x, y, width, height); + Insets insets = getBorderInsets(c); + Rectangle compR = getComponentRect(rect, insets); + int diff; + switch (titlePosition) { + case ABOVE_TOP: + diff = compR.height + TEXT_SPACING; + borderR.y += diff; + borderR.height -= diff; + break; + case TOP: + case DEFAULT_POSITION: + diff = insets.top / 2 - borderInsets.top - EDGE_SPACING; + borderR.y += diff; + borderR.height -= diff; + break; + case BELOW_TOP: + case ABOVE_BOTTOM: + break; + case BOTTOM: + diff = insets.bottom / 2 - borderInsets.bottom - EDGE_SPACING; + borderR.height -= diff; + break; + case BELOW_BOTTOM: + diff = compR.height + TEXT_SPACING; + borderR.height -= diff; + break; + } + border.paintBorder(c, g, borderR.x, borderR.y, borderR.width, borderR.height); + Color col = g.getColor(); + g.setColor(new Color(255, 255, 255, 0)); + g.fillRect(compR.x, compR.y, compR.width, compR.height); + g.setColor(col); + } + + public Insets getBorderInsets(Component c, Insets insets) { + Insets borderInsets; + if (border != null) { + borderInsets = border.getBorderInsets(c); + } else { + borderInsets = new Insets(0, 0, 0, 0); + } + insets.top = EDGE_SPACING + TEXT_SPACING + borderInsets.top; + insets.right = EDGE_SPACING + TEXT_SPACING + borderInsets.right; + insets.bottom = EDGE_SPACING + TEXT_SPACING + borderInsets.bottom; + insets.left = EDGE_SPACING + TEXT_SPACING + borderInsets.left; + + if (c == null || component == null) { + return insets; + } + + int compHeight = component.getPreferredSize().height; + + switch (titlePosition) { + case ABOVE_TOP: + insets.top += compHeight + TEXT_SPACING; + break; + case TOP: + case DEFAULT_POSITION: + insets.top += Math.max(compHeight, borderInsets.top) - borderInsets.top; + break; + case BELOW_TOP: + insets.top += compHeight + TEXT_SPACING; + break; + case ABOVE_BOTTOM: + insets.bottom += compHeight + TEXT_SPACING; + break; + case BOTTOM: + insets.bottom += Math.max(compHeight, borderInsets.bottom) - borderInsets.bottom; + break; + case BELOW_BOTTOM: + insets.bottom += compHeight + TEXT_SPACING; + break; + } + return insets; + } + + public JComponent getTitleComponent() { + return component; + } + + public void setTitleComponent(JComponent component) { + this.component = component; + } + + public Rectangle getComponentRect(Rectangle rect, Insets borderInsets) { + Dimension compD = component.getPreferredSize(); + Rectangle compR = new Rectangle(0, 0, compD.width, compD.height); + switch (titlePosition) { + case ABOVE_TOP: + compR.y = EDGE_SPACING; + break; + case TOP: + case DEFAULT_POSITION: + if (component instanceof JButton) { + compR.y = EDGE_SPACING + (borderInsets.top - EDGE_SPACING - TEXT_SPACING - compD.height) / 2; + } else if (component instanceof JRadioButton) { + compR.y = (borderInsets.top - EDGE_SPACING - TEXT_SPACING - compD.height) / 2; + } else if (component instanceof JCheckBox) { + compR.y = (borderInsets.top - EDGE_SPACING - TEXT_SPACING - compD.height) / 2; + } + break; + case BELOW_TOP: + compR.y = borderInsets.top - compD.height - TEXT_SPACING; + break; + case ABOVE_BOTTOM: + compR.y = rect.height - borderInsets.bottom + TEXT_SPACING; + break; + case BOTTOM: + compR.y = rect.height - borderInsets.bottom + TEXT_SPACING + (borderInsets.bottom - EDGE_SPACING - TEXT_SPACING - compD.height) / 2; + break; + case BELOW_BOTTOM: + compR.y = rect.height - compD.height - EDGE_SPACING; + break; + } + switch (titleJustification) { + case LEFT: + case DEFAULT_JUSTIFICATION: + //compR.x = TEXT_INSET_H + borderInsets.left; + compR.x = TEXT_INSET_H + borderInsets.left - EDGE_SPACING; + break; + case RIGHT: + compR.x = rect.width - borderInsets.right - TEXT_INSET_H - compR.width; + break; + case CENTER: + compR.x = (rect.width - compR.width) / 2; + break; + } + return compR; + } +} diff --git a/src/eu/engys/util/ui/ComponentsFactory.java b/src/eu/engys/util/ui/ComponentsFactory.java new file mode 100644 index 0000000..095b0d4 --- /dev/null +++ b/src/eu/engys/util/ui/ComponentsFactory.java @@ -0,0 +1,445 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.Color; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.util.HashMap; + +import javax.swing.ComboBoxModel; +import javax.swing.Icon; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPasswordField; +import javax.swing.JTextArea; +import javax.swing.ListCellRenderer; +import javax.swing.SwingConstants; +import javax.swing.UIManager; +import javax.swing.event.ListDataListener; + +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.builder.JCheckBoxController; +import eu.engys.util.ui.builder.JComboBoxController; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.util.ui.textfields.IntegerField; +import eu.engys.util.ui.textfields.SpinnerField; +import eu.engys.util.ui.textfields.StringField; + +public class ComponentsFactory { + + public static JLabel labelField(String text) { + return new JLabel(text); + } + + public static JTextArea labelArea() { + return new JTextArea(); + } + + public static JLabel[] labelArrayField(String... strings) { + JLabel[] value = new JLabel[strings.length]; + for (int i = 0; i < value.length; i++) { + value[i] = labelField(strings[i]); + } + return value; + } + + public static JCheckBox checkField() { + JCheckBox checkBox = new JCheckBox(); + checkBox.setOpaque(false); + return checkBox; + } + + public static JCheckBox checkField(String string) { + JCheckBox checkBox = new JCheckBox(string); + checkBox.setOpaque(false); + return checkBox; + } + + public static JCheckBox checkField(boolean def) { + JCheckBox checkBox = new JCheckBox(); + checkBox.setSelected(def); + checkBox.setOpaque(false); + return checkBox; + } + + public static JCheckBox checkField(String string, boolean def) { + JCheckBox checkBox = new JCheckBox(string); + checkBox.setSelected(def); + checkBox.setOpaque(false); + return checkBox; + } + + public static JCheckBox checkField(String string, boolean def, Color color) { + JCheckBox checkBox = new JCheckBox(string); + checkBox.setSelected(def); + checkBox.setOpaque(false); + checkBox.putClientProperty("Synthetica.background", color); + checkBox.putClientProperty("Synthetica.background.alpha", UIManager.get("Synthetica.checkbox.background.alpha")); + return checkBox; + } + + public static StringField stringField() { + return new StringField(); + } + + public static StringField stringField(boolean checkEmptyStrings, boolean checkForbidden) { + return new StringField(checkEmptyStrings, checkForbidden); + } + + public static StringField stringField(String text, Integer columns) { + return new StringField(text, columns, true, true); + } + + public static StringField stringField(String text) { + return new StringField(text); + } + + public static JPasswordField passwordField() { + return new JPasswordField(20); + } + + public static SpinnerField spinnerField() { + return new SpinnerField(0, Integer.MAX_VALUE, 0); + } + + public static SpinnerField spinnerField(Integer lb, Integer ub) { + return new SpinnerField(lb, ub, Math.max(0, lb)); + } + + public static IntegerField intField() { + return new IntegerField(0, Integer.MAX_VALUE, 0); + } + + public static IntegerField intField(Integer lb, Integer ub) { + return new IntegerField(lb, ub, Math.max(0, lb)); + } + + public static IntegerField intField(Integer def) { + return new IntegerField(0, Integer.MAX_VALUE, def); + } + + public static IntegerField[] intArrayField(Integer dimensions) { + IntegerField[] value = new IntegerField[dimensions]; + for (int i = 0; i < value.length; i++) { + value[i] = intField(); + } + return value; + } + + public static DoubleField doubleField() { + return new DoubleField(-Double.MAX_VALUE, Double.MAX_VALUE, 0.0); + } + + public static DoubleField doubleField(Double def) { + return new DoubleField(-Double.MAX_VALUE, Double.MAX_VALUE, def); + } + + public static DoubleField doubleField(Integer places) { + return new DoubleField(-Double.MAX_VALUE, Double.MAX_VALUE, 0.0, places); + } + + public static DoubleField doubleField(Integer places, Double d) { + return new DoubleField(-Double.MAX_VALUE, Double.MAX_VALUE, d, places); + } + + public static DoubleField doubleField(Double lb, Double ub) { + return new DoubleField(lb, ub, lb); + } + + public static DoubleField doubleField(Double def, Double lb, Double ub) { + return new DoubleField(lb, ub, def); + } + + public static DoubleField[] doublePointField() { + return new DoubleField[] { doubleField(), doubleField(), doubleField() }; + } + + public static DoubleField[] doublePointField(Integer places) { + return new DoubleField[] { doubleField(places), doubleField(places), doubleField(places) }; + } + + public static DoubleField[] doublePointField(Double d1, Double d2, Double d3) { + return new DoubleField[] { doubleField(d1), doubleField(d2), doubleField(d3) }; + } + + public static DoubleField[] doublePointField(Double d1, Double d2, Double d3, Double lb, Double ub ) { + return new DoubleField[] { doubleField(d1, lb, ub), doubleField(d2,lb, ub), doubleField(d3, lb, ub) }; + } + + public static DoubleField[] doublePointField(Integer places, Double d) { + return new DoubleField[] { doubleField(places, d), doubleField(places, d), doubleField(places, d) }; + } + + public static DoubleField[] doubleArrayField(Integer dimensions) { + DoubleField[] value = new DoubleField[dimensions]; + for (int i = 0; i < value.length; i++) { + value[i] = doubleField(); + } + return value; + } + + public static DoubleField[] doubleArrayField(Integer dimensions, Integer places) { + DoubleField[] value = new DoubleField[dimensions]; + for (int i = 0; i < value.length; i++) { + value[i] = doubleField(places); + } + return value; + } + + public static class SelectField extends JComboBox { + + private final class SelectFieldCellRenderer implements ListCellRenderer { + + private ListCellRenderer delegate; + + private HashMap iconFromKey = new HashMap<>(); + private HashMap labelFromKey = new HashMap<>(); + + private SelectFieldCellRenderer(ListCellRenderer renderer) { + this.delegate = renderer; + } + + @Override + public Component getListCellRendererComponent(JList list, T value, int index, boolean isSelected, boolean cellHasFocus) { + delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + String text = labelFromKey.get(value); + Icon icon = iconFromKey.get(value); + + if (delegate instanceof JLabel) { + JLabel label = (JLabel) delegate; + label.setText(text); + label.setIcon(icon); + return label; + } else { + return new JLabel(text, icon, SwingConstants.LEFT); + } + } + + public void addItem(T key, String label, Icon icon) { + labelFromKey.put(key, label); + iconFromKey.put(key, icon); + } + + public void removeAllItems() { + labelFromKey.clear(); + iconFromKey.clear(); + } + } + + private SelectFieldCellRenderer renderer; + + public SelectField(T[] keys) { + this(); + for (T string : keys) { + addItem(string); + } + } + + public SelectField(T[] keys, final String[] labels, final Icon[] icons) { + this(); + for (int i = 0; i < keys.length; i++) { + addItem(keys[i], labels[i], icons[i]); + } + } + + public SelectField() { + super(); + } + + @Override + protected void fireActionEvent() { + super.fireActionEvent(); + firePropertyChange("value", null, getSelectedItem()); + } + + @Override + public void addItem(T item) { + super.addItem(item); + setMaximumRowCount(getItemCount()); + } + + public void addItem(T key, String label, Icon icon) { + addItem(key); + if (renderer == null) { + renderer = new SelectFieldCellRenderer(getRenderer()); + setRenderer(renderer); + } + renderer.addItem(key, label, icon); + } + + @Override + public void removeAllItems() { + super.removeAllItems(); + if (renderer != null) { + renderer.removeAllItems(); + } + } + } + + public static SelectField selectField() { + SelectField combo = new SelectField(); + return combo; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static JComboBox selectField(final ListBuilder builder) { + final JComboBox combo = selectField(); + combo.setModel(new ComboBoxModel() { + + private Object selected; + + @Override + public void removeListDataListener(ListDataListener l) { + } + + @Override + public int getSize() { + return builder.getSourceElements().length; + } + + @Override + public Object getElementAt(int index) { + return builder.getSourceElements()[index]; + } + + @Override + public void addListDataListener(ListDataListener l) { + } + + @Override + public void setSelectedItem(Object anItem) { + this.selected = anItem; + combo.revalidate(); + combo.repaint(); + } + + @Override + public Object getSelectedItem() { + return selected; + } + }); + return combo; + } + + public static JComboBox selectField(String... items) { + JComboBox combo = new SelectField<>(items); + return combo; + } + + public static JComboBox selectField(final String[] keys, final String[] labels) { + return selectField(keys, labels, new Icon[keys.length]); + } + + public static SelectField selectField(final String[] keys, final String[] labels, final Icon[] icons) { + SelectField combo = new SelectField<>(keys, labels, icons); + return combo; + } + + private static JComboBoxWithItemsSupport selectFieldWithItemSupport() { + JComboBoxWithItemsSupport combo = new JComboBoxWithItemsSupport() { + @Override + protected void fireActionEvent() { + super.fireActionEvent(); + firePropertyChange("value", null, getSelectedItem()); + } + }; + return combo; + } + + public static JComboBoxWithItemsSupport selectFieldWithItemSupport(final String[] items) { + JComboBoxWithItemsSupport combo = selectFieldWithItemSupport(); + for (String string : items) { + combo.addItem(string); + } + return combo; + } + + public static JComboBoxWithItemsSupport selectFieldWithItemSupport(final String[] keys, final String[] items) { + JComboBoxWithItemsSupport combo = selectFieldWithItemSupport(keys); + combo.setLabels(items); + return combo; + } + + public static JComboBoxController comboBoxControllerField() { + JComboBoxController combo = new JComboBoxController() { + @Override + protected void fireActionEvent() { + super.fireActionEvent(); + firePropertyChange("value", null, getSelectedItem()); + } + }; + return combo; + } + + public static JCheckBoxController checkBoxControllerField(String name) { + JCheckBoxController combo = new JCheckBoxController(name) { + @Override + protected void fireActionPerformed(ActionEvent event) { + super.fireActionPerformed(event); + firePropertyChange("value", null, isSelected()); + } + }; + return combo; + } + + public static RadioFieldPanel radioField(final String[] keys, final String[] items) { + RadioFieldPanel panel = new RadioFieldPanel(); + for (int i = 0; i < keys.length; i++) { + panel.addButton(items[i], keys[i]); + } + if (keys.length == 1) { + panel.select(keys[0]); + } + return panel; + } + + public static RadioFieldPanel radioField(String... items) { + RadioFieldPanel panel = new RadioFieldPanel(); + for (String string : items) { + panel.addButton(string); + } + if (items.length == 1) { + panel.select(items[0]); + } + return panel; + } + + public static ListFieldPanel listField(ListBuilder listBuilder) { + return new ListFieldPanel(listBuilder); + } + + public static FileFieldPanel fileField(SelectionMode mode, String tooltip, boolean selectFile) { + return fileField(mode, tooltip, "", selectFile); + } + + public static FileFieldPanel fileField(SelectionMode mode, String tooltip, String prompt, boolean selectFile) { + return new FileFieldPanel(mode, tooltip, prompt, selectFile); + } + +} diff --git a/src/eu/engys/util/ui/CopyPasteSupport.java b/src/eu/engys/util/ui/CopyPasteSupport.java new file mode 100644 index 0000000..a6cd33f --- /dev/null +++ b/src/eu/engys/util/ui/CopyPasteSupport.java @@ -0,0 +1,224 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui; + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.StringTokenizer; + +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JTable; +import javax.swing.KeyStroke; + +public class CopyPasteSupport { + + public static void addSupportTo(JTable table) { + KeyStroke copy = KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK, false); + // Identifying the copy KeyStroke user can modify this + // to copy on some other Key combination. + KeyStroke paste = KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK, false); + // Identifying the Paste KeyStroke user can modify this + // to copy on some other Key combination. + + CopyPasteListener cpl = new CopyPasteListener(table); + + table.registerKeyboardAction(cpl, "Copy", copy, JComponent.WHEN_FOCUSED); + table.registerKeyboardAction(cpl, "Paste", paste, JComponent.WHEN_FOCUSED); + + table.setColumnSelectionAllowed(true); + table.setRowSelectionAllowed(true); + } + + static class CopyPasteListener implements ActionListener { + + private JTable table; + + public CopyPasteListener(JTable table) { + this.table = table; + } + + @Override + public void actionPerformed(ActionEvent e) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + + if (e.getActionCommand().equals("Copy")) { + StringBuffer sbf = new StringBuffer(); + // Check to ensure we have selected only a contiguous block of + // cells + int numcols = table.getSelectedColumnCount(); + int numrows = table.getSelectedRowCount(); + + int[] rowsselected = table.getSelectedRows(); + int[] colsselected = table.getSelectedColumns(); + if (!((numrows - 1 == rowsselected[rowsselected.length - 1] - rowsselected[0] && numrows == rowsselected.length) && (numcols - 1 == colsselected[colsselected.length - 1] + - colsselected[0] && numcols == colsselected.length))) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Invalid Copy Selection", "Invalid Copy Selection", JOptionPane.ERROR_MESSAGE); + return; + } + for (int i = 0; i < numrows; i++) { + for (int j = 0; j < numcols; j++) { + sbf.append(table.getValueAt(rowsselected[i], colsselected[j])); + if (j < numcols - 1) + sbf.append("\t"); + } + sbf.append("\n"); + } + StringSelection stsel = new StringSelection(sbf.toString()); + + clipboard.setContents(stsel, stsel); + } + if (e.getActionCommand().equals("Paste")) { + System.out.println("Trying to Paste"); + int[] selRows = table.getSelectedRows(); + int[] selCols = table.getSelectedColumns(); + + int startRow = selRows[0]; + int startCol = selCols[0]; + + try { + String copiedString = (String) clipboard.getContents(this).getTransferData(DataFlavor.stringFlavor); + System.out.println("String is:" + copiedString); + + String[][] data = stringToArray(copiedString); + TypeOfCopy type = decodeTypeOfCopy(data, selRows, selCols); + + if (type == TypeOfCopy.ERROR) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Invalid Paste Selection", "Invalid Paste Selection", JOptionPane.ERROR_MESSAGE); + } else { + System.out.println(String.format("Paste %d x %d -> %d x %d", data.length, data[0].length, selRows.length, selCols.length)); + switch (type) { + case CELL: + for (int i = 0; i < selRows.length; i++) { + for (int j = 0; j < selCols.length; j++) { + table.setValueAt(getEditedValue(data[0][0]), selRows[i], selCols[j]); + } + } + break; + + case ROW: + for (int i = 0; i < selRows.length; i++) { + for (int j = 0; j < selCols.length; j++) { + table.setValueAt(getEditedValue(data[0][j]), selRows[i], selCols[j]); + } + } + break; + + case COLUMN: + for (int i = 0; i < selRows.length; i++) { + for (int j = 0; j < selCols.length; j++) { + table.setValueAt(getEditedValue(data[j][0]), selRows[i], selCols[j]); + } + } + break; + + case MATRIX: + for (int i = 0; i < selRows.length; i++) { + for (int j = 0; j < selCols.length; j++) { + table.setValueAt(getEditedValue(data[i][j]), selRows[i], selCols[j]); + } + } + break; + + default: + break; + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + private Object getEditedValue(String string) { + // Class klass = table.getModel().getColumnClass(col); + // System.out.println("CopyPasteSupport.CopyPasteListener.getEditedValue() "+klass); + try { + return Double.valueOf(string); + } catch (NumberFormatException e) { + return 0; + } + // Object value; + + // if (klass.isInstance(Double.class)) { + // value = Double.valueOf(string); + // } else { + // value = string; + // } + } + + enum TypeOfCopy { + CELL, ROW, COLUMN, MATRIX, ERROR + } + + private TypeOfCopy decodeTypeOfCopy(String[][] data, int[] selRows, int[] selCols) { + if (data != null) { + if (data.length == 1) { + if (data[0].length == 1) { + return TypeOfCopy.CELL; + } else if (data[0].length == selCols.length) { + return TypeOfCopy.ROW; + } else { + return TypeOfCopy.ERROR; + } + } else if (data.length == selRows.length) { + if (data[0].length == 1) { + return TypeOfCopy.COLUMN; + } else if (data[0].length == selCols.length) { + return TypeOfCopy.MATRIX; + } else { + return TypeOfCopy.ERROR; + } + } else { + return TypeOfCopy.ERROR; + } + } else { + return TypeOfCopy.ERROR; + } + } + + private String[][] stringToArray(String copiedString) { + StringTokenizer rowTokenizer = new StringTokenizer(copiedString, "\n"); + String[][] data = new String[rowTokenizer.countTokens()][]; + for (int i = 0; rowTokenizer.hasMoreTokens(); i++) { + String rowstring = rowTokenizer.nextToken(); + StringTokenizer colTokenizer = new StringTokenizer(rowstring, "\t"); + data[i] = new String[colTokenizer.countTokens()]; + for (int j = 0; colTokenizer.hasMoreTokens(); j++) { + String value = (String) colTokenizer.nextToken(); + data[i][j] = value; + } + } + return data; + } + } +} diff --git a/src/eu/engys/util/ui/DoubleListAction.java b/src/eu/engys/util/ui/DoubleListAction.java new file mode 100644 index 0000000..3189e17 --- /dev/null +++ b/src/eu/engys/util/ui/DoubleListAction.java @@ -0,0 +1,116 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import eu.engys.util.Symbols; + +public class DoubleListAction extends AbstractAction { + + private final ListFieldPanel listField; + private final ListBuilder listBuilder; + + private JDialog dialog; + private DualList dual; + + DoubleListAction(ListFieldPanel listField, ListBuilder listBuilder) { + super(Symbols.DOTS); + this.listField = listField; + this.listBuilder = listBuilder; + } + + public void actionPerformed(ActionEvent e) { + if (dialog == null) { + dialog = new JDialog(SwingUtilities.getWindowAncestor(listField), listBuilder.getTitle()); + dialog.setName("dual.list.dialog"); + dialog.setModal(true); + dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); + dialog.setSize(400, 300); + dialog.setLocationRelativeTo(listField); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.setBorder(UiUtil.getStandardBorder()); + + dual = new DualList(); + + ArrayList buttons = new ArrayList(); + JButton okButton = new JButton(new AbstractAction("OK") { + @Override + public void actionPerformed(ActionEvent e) { + listField.setValues(dual.getDestinationElements()); + dialog.setVisible(false); + } + }); + okButton.setName("OK"); + buttons.add(okButton); + + JButton cancelButton = new JButton(new AbstractAction("Cancel") { + @Override + public void actionPerformed(ActionEvent e) { + dialog.setVisible(false); + } + }); + cancelButton.setName("Cancel"); + buttons.add(cancelButton); + + JComponent buttonsPanel = UiUtil.getCommandRow(buttons); + + mainPanel.add(dual, BorderLayout.CENTER); + mainPanel.add(buttonsPanel, BorderLayout.SOUTH); + + dialog.getContentPane().add(mainPanel); + dialog.getRootPane().setDefaultButton(okButton); + } + + String[] destination = listField.getValues(); + String[] source = listBuilder.getSourceElements(); + + String[] sourceMinusAlreadyPresent = new String[source.length - destination.length]; + int j = 0; + List destinationList = Arrays.asList(destination); + for (int i = 0; i < source.length; i++) { + if (!destinationList.contains(source[i])) { + sourceMinusAlreadyPresent[j++] = source[i]; + } + } + dual.setSourceElements(sourceMinusAlreadyPresent); + dual.setDestinationElements(destination); + + dialog.setVisible(true); + } +} diff --git a/src/eu/engys/util/ui/DualList.java b/src/eu/engys/util/ui/DualList.java new file mode 100644 index 0000000..63dfe22 --- /dev/null +++ b/src/eu/engys/util/ui/DualList.java @@ -0,0 +1,258 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui; + +import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.swing.AbstractListModel; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.ListModel; + +public class DualList extends JPanel { + private JList sourceList; + private SortedListModel sourceListModel; + + private JList destList; + private SortedListModel destListModel; + + private JButton addButton; + private JButton removeButton; + + public DualList() { + layoutComponents(); + } + + private void layoutComponents() { + setLayout(new GridBagLayout()); + sourceListModel = new SortedListModel(); + sourceList = new JList<>(sourceListModel); + sourceList.setName("source.list"); + + addButton = new JButton(">>"); + addButton.setName(">>"); + addButton.addActionListener(new AddListener()); + removeButton = new JButton("<<"); + removeButton.setName("<<"); + removeButton.addActionListener(new RemoveListener()); + + destListModel = new SortedListModel(); + destList = new JList<>(destListModel); + destList.setName("dest.list"); + + JPanel leftPanel = new JPanel(new BorderLayout()); + leftPanel.add(new JLabel("Available Elements:"), BorderLayout.NORTH); + leftPanel.add(new JScrollPane(sourceList), BorderLayout.CENTER); + + JPanel rightPanel = new JPanel(new BorderLayout()); + rightPanel.add(new JLabel("Selected Elements:"), BorderLayout.NORTH); + rightPanel.add(new JScrollPane(destList), BorderLayout.CENTER); + + JPanel centerPanel = new JPanel(); + centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS)); + centerPanel.add(Box.createVerticalGlue()); + centerPanel.add(addButton); + centerPanel.add(removeButton); + centerPanel.add(Box.createVerticalGlue()); + + add(leftPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + add(centerPanel, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 4, 0, 4), 0, 0)); + add(rightPanel, new GridBagConstraints(2, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + } + + /* + * SOURCE + */ + + public void setSourceElements(Object newValue[]) { + sourceListModel.clear(); + sourceListModel.addAll(newValue); + } + + private void addSourceElements(ListModel newValue) { + int size = newValue.getSize(); + for (int i = 0; i < size; i++) { + System.out.println("DualList.addSourceElements(): " + newValue.getElementAt(i)); + sourceListModel.add(newValue.getElementAt(i)); + } + } + + @SuppressWarnings("deprecation") + private void clearSourceSelected() { + Object selected[] = sourceList.getSelectedValues(); + for (int i = selected.length - 1; i >= 0; --i) { + sourceListModel.removeElement(selected[i]); + } + sourceList.getSelectionModel().clearSelection(); + } + + /* + * DESTINATION + */ + + public void setDestinationElements(Object newValue[]) { + destListModel.clear(); + destListModel.addAll(newValue); + } + + public String[] getDestinationElements() { + String[] elements = new String[destListModel.model.size()]; + int i = 0; + for (Iterator it = destListModel.iterator(); it.hasNext();) { + elements[i++] = (String) it.next(); + } + return elements; + } + + @SuppressWarnings("deprecation") + private void clearDestinationSelected() { + Object selected[] = destList.getSelectedValues(); + for (int i = selected.length - 1; i >= 0; --i) { + destListModel.removeElement(selected[i]); + } + destList.getSelectionModel().clearSelection(); + } + + /* + * OTHER + */ + + @SuppressWarnings("deprecation") + private class AddListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + Object selected[] = sourceList.getSelectedValues(); + destListModel.addAll(selected); + clearSourceSelected(); + } + } + + @SuppressWarnings("deprecation") + private class RemoveListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + Object selected[] = destList.getSelectedValues(); + sourceListModel.addAll(selected); + clearDestinationSelected(); + } + } + + public static void main(String args[]) { + JFrame frame = new JFrame("Dual List Box Tester"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + DualList dual = new DualList(); + List model = new ArrayList<>(); + model.add("One"); + model.add("Two"); + model.add("Three"); + model.add("Four"); + model.add("Five"); + model.add("Six"); + model.add("Seven"); + model.add("Eight"); + model.add("Nine"); + model.add("Ten"); + dual.setSourceElements(model.toArray(new String[0])); + frame.add(dual, BorderLayout.CENTER); + frame.setSize(400, 300); + frame.setVisible(true); + } + + private class SortedListModel extends AbstractListModel { + SortedSet model; + + public SortedListModel() { + model = new TreeSet(); + } + + public int getSize() { + return model.size(); + } + + public Object getElementAt(int index) { + return model.toArray()[index]; + } + + public void add(Object element) { + if (model.add(element)) { + fireContentsChanged(this, 0, getSize()); + } + } + + public void addAll(Object elements[]) { + Collection c = Arrays.asList(elements); + model.addAll(c); + fireContentsChanged(this, 0, getSize()); + } + + public void clear() { + model.clear(); + fireContentsChanged(this, 0, getSize()); + } + + public boolean contains(Object element) { + return model.contains(element); + } + + public Object firstElement() { + return model.first(); + } + + public Iterator iterator() { + return model.iterator(); + } + + public Object lastElement() { + return model.last(); + } + + public boolean removeElement(Object element) { + boolean removed = model.remove(element); + if (removed) { + fireContentsChanged(this, 0, getSize()); + } + return removed; + } + } + +} diff --git a/src/eu/engys/util/ui/ExecUtil.java b/src/eu/engys/util/ui/ExecUtil.java new file mode 100644 index 0000000..bbecce6 --- /dev/null +++ b/src/eu/engys/util/ui/ExecUtil.java @@ -0,0 +1,91 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import javax.swing.SwingUtilities; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ExecUtil { + + private static final Logger logger = LoggerFactory.getLogger(ExecUtil.class); + + public static void invokeLater(Runnable runnable) { + if (SwingUtilities.isEventDispatchThread()) { + runnable.run(); + } else { + SwingUtilities.invokeLater(runnable); + } + } + + public static void invokeAndWait(Runnable runnable) { + if (SwingUtilities.isEventDispatchThread()) { + runnable.run(); + } else { + try { + SwingUtilities.invokeAndWait(runnable); + } catch (InvocationTargetException | InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void execSerial(Runnable... runnables) { + for (Runnable runnable : runnables) { + runnable.run(); + } + } + + public static void execParallelAndWait(Runnable... runnables) { + if (runnables.length > 0) { + ExecutorService service = createParallelExecutor(runnables.length); + for (Runnable runnable : runnables) { + service.submit(runnable); + } + awaitTermination(service); + } + } + + public static ExecutorService createParallelExecutor(int np) { + return Executors.newFixedThreadPool(np); + } + + public static void awaitTermination(ExecutorService service) { + service.shutdown(); + try { + service.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + } catch (InterruptedException e) { + logger.error("Thread interrupted", e); + } + } + +} diff --git a/src/eu/engys/util/ui/FileChooserUtils.java b/src/eu/engys/util/ui/FileChooserUtils.java new file mode 100644 index 0000000..2817a9e --- /dev/null +++ b/src/eu/engys/util/ui/FileChooserUtils.java @@ -0,0 +1,134 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.io.File; + +import javax.swing.JOptionPane; + +import org.apache.commons.io.FilenameUtils; + +import eu.engys.util.PrefUtil; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.filechooser.util.HelyxFileFilter; +import eu.engys.util.filechooser.util.SelectionMode; + +public class FileChooserUtils { + + public static final String PDF_EXTENSION = "pdf"; + public static final String PNG_EXTENSION = "png"; + public static final String CSV_EXTENSION = "csv"; + public static final String EXCEL_EXTENSION_OLD = "xls"; + public static final String EXCEL_EXTENSION_NEW = "xlsx"; + + public static final String DEFAULT_SSH_PORT = "22"; + + public static File getPNGFile() { + File lastDir = PrefUtil.getWorkDir(PrefUtil.LAST_OPEN_EXPORT_DIR); + + HelyxFileChooser fc = new HelyxFileChooser(lastDir.getAbsolutePath()); + fc.setSelectionMode(SelectionMode.FILES_ONLY); + HelyxFileFilter filter = new HelyxFileFilter("PNG File (*.png)", PNG_EXTENSION); + File file = null; + ReturnValue retVal = fc.showSaveAsDialog(filter); + + if (retVal.isApprove()) { + file = fc.getSelectedFile(); + String extension = FilenameUtils.getExtension(file.getAbsolutePath()); + + if (!extension.equalsIgnoreCase(PNG_EXTENSION)) { + file = new File(file.getParent(), file.getName() + "." + PNG_EXTENSION); + } + + if (file.exists()) { + int confirm = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "File already exists. Overwrite?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (confirm == JOptionPane.NO_OPTION) { + return getPNGFile(); + } + } + PrefUtil.putFile(PrefUtil.LAST_OPEN_EXPORT_DIR, file.getParentFile()); + } + return file; + } + + public static File getExcelFile() { + File lastDir = PrefUtil.getWorkDir(PrefUtil.LAST_OPEN_EXPORT_DIR); + + HelyxFileChooser fc = new HelyxFileChooser(lastDir.getAbsolutePath()); + fc.setSelectionMode(SelectionMode.FILES_ONLY); + HelyxFileFilter filter = new HelyxFileFilter("Excel File (*.xls, *.xlsx)", EXCEL_EXTENSION_OLD, EXCEL_EXTENSION_NEW); + File file = null; + ReturnValue retVal = fc.showSaveAsDialog(filter); + + if (retVal.isApprove()) { + file = fc.getSelectedFile(); + String extension = FilenameUtils.getExtension(file.getAbsolutePath()); + + if (!extension.equalsIgnoreCase(EXCEL_EXTENSION_OLD) && !extension.equalsIgnoreCase(EXCEL_EXTENSION_NEW)) { + file = new File(file.getParent(), file.getName() + "." + EXCEL_EXTENSION_OLD); + } + + if (file.exists()) { + int confirm = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "File already exists. Overwrite?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (confirm == JOptionPane.NO_OPTION) { + return getPNGFile(); + } + } + PrefUtil.putFile(PrefUtil.LAST_OPEN_EXPORT_DIR, file.getParentFile()); + } + return file; + } + + public static File getCSVFile() { + File lastDir = PrefUtil.getWorkDir(PrefUtil.LAST_OPEN_EXPORT_DIR); + + HelyxFileChooser fc = new HelyxFileChooser(lastDir.getAbsolutePath()); + fc.setSelectionMode(SelectionMode.FILES_ONLY); + HelyxFileFilter filter = new HelyxFileFilter("CSV File (*.csv)", CSV_EXTENSION); + File file = null; + ReturnValue retVal = fc.showSaveAsDialog(filter); + + if (retVal.isApprove()) { + file = fc.getSelectedFile(); + String extension = FilenameUtils.getExtension(file.getAbsolutePath()); + + if (!extension.equalsIgnoreCase(CSV_EXTENSION)) { + file = new File(file.getParent(), file.getName() + "." + CSV_EXTENSION); + } + + if (file.exists()) { + int confirm = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "File already exists. Overwrite?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (confirm == JOptionPane.NO_OPTION) { + return getPNGFile(); + } + } + PrefUtil.putFile(PrefUtil.LAST_OPEN_EXPORT_DIR, file.getParentFile()); + } + return file; + } + +} diff --git a/src/eu/engys/util/ui/FileFieldPanel.java b/src/eu/engys/util/ui/FileFieldPanel.java new file mode 100644 index 0000000..0bc2d08 --- /dev/null +++ b/src/eu/engys/util/ui/FileFieldPanel.java @@ -0,0 +1,108 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.beans.PropertyChangeListener; +import java.io.File; + +import javax.swing.JButton; +import javax.swing.JPanel; + +import eu.engys.util.filechooser.util.SelectionMode; +import eu.engys.util.ui.textfields.FileTextField; + +public class FileFieldPanel extends JPanel { + private FileTextField textField; + private JButton button; + + public FileFieldPanel(SelectionMode mode, String tooltip, String prompt, boolean selectFile) { + super(new BorderLayout(4, 4)); + setOpaque(false); + + textField = new FileTextField(); + textField.setEditable(false); + textField.setFocusable(false); + textField.setToolTipText(tooltip); + textField.setPrompt(prompt); + + button = createButtonFileChooser(selectFile, textField, mode); + add(textField, BorderLayout.CENTER); + add(button, BorderLayout.EAST); + } + + @Override + public void setName(String name) { + super.setName(name); + textField.setName(name + ".text"); + button.setName(name + ".button"); + } + + public boolean hasExistingFile() { + return textField.getText().isEmpty() || textField.hasValidFile(); + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener listener) { + if (textField != null) + textField.addPropertyChangeListener(listener); + } + + public String getFilePath() { + File file = textField.getValue(); + return file != null ? file.getPath() : ""; + } + + public void setFilePath(String path) { + textField.setValue(new File(path == null ? "" : path)); + } + + public File getFile() { + return textField.getValue(); + } + + public void setFile(File file) { + textField.setValue(file); + } + + private JButton createButtonFileChooser(boolean selectFile, FileTextField textField, SelectionMode mode) { + JButton button = new JButton(new ChooseFileAction(selectFile, textField, mode)); + Dimension prefSize = button.getPreferredSize(); + button.setPreferredSize(new Dimension(24, prefSize.height)); + return button; + } + + public FileTextField getTextField() { + return textField; + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + button.setEnabled(enabled); + } +} diff --git a/src/eu/engys/util/ui/JComboBoxWithItemsSupport.java b/src/eu/engys/util/ui/JComboBoxWithItemsSupport.java new file mode 100644 index 0000000..8609844 --- /dev/null +++ b/src/eu/engys/util/ui/JComboBoxWithItemsSupport.java @@ -0,0 +1,121 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui; + +import java.awt.Component; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.ListCellRenderer; + +public class JComboBoxWithItemsSupport extends JComboBox implements ItemListener { + + private Map itemFromKey = new HashMap(); + private List disabledIndexes = new ArrayList(); + + public JComboBoxWithItemsSupport() { + super(); + final ListCellRenderer renderer = getRenderer(); + setRenderer(new ListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, String value, int index, boolean isSelected, boolean cellHasFocus) { + Component c = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + + if (c instanceof JLabel) { + JLabel label = (JLabel) c; + String key = value; + label.setText(itemFromKey.containsKey(key) ? itemFromKey.get(key) : key); + + if (disabledIndexes.contains(index)) { + label.setFocusable(false); + label.setEnabled(false); + if (isSelected) + label.setBackground(list.getBackground()); + } else { + label.setFocusable(true); + label.setEnabled(true); + } + } + + return c; + } + }); + addItemListener(this); + } + + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getSource() instanceof JComboBox && e.getStateChange() == ItemEvent.SELECTED) { + JComboBox combo = (JComboBox) e.getSource(); + int index = combo.getSelectedIndex(); + if (disabledIndexes.contains(index)) { + combo.setSelectedIndex(-1); + } + } + } + + @Override + public void setSelectedIndex(int index) { + if (disabledIndexes.contains(index)) { + super.setSelectedIndex(-1); + } else { + super.setSelectedIndex(index); + } + } + + public boolean isDisabledAt(int index){ + return disabledIndexes.contains(index); + } + +// private void addDisabledIndex(int index) { +// disabledIndexes.add(index); +// } + + public void addDisabledItem(String item) { + int itemIndex = ((DefaultComboBoxModel) getModel()).getIndexOf(item); + disabledIndexes.add(itemIndex); + } + + public void clearDisabledIndexes() { + disabledIndexes.clear(); + } + + public void setLabels(String[] labels) { + for (int i = 0; i < getItemCount(); i++) { + itemFromKey.put(getItemAt(i), labels[i]); + } + } + +} diff --git a/src/eu/engys/util/ui/ListBuilder.java b/src/eu/engys/util/ui/ListBuilder.java new file mode 100644 index 0000000..c357c40 --- /dev/null +++ b/src/eu/engys/util/ui/ListBuilder.java @@ -0,0 +1,37 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +public interface ListBuilder { + public static int SINGLE_SELECTION = 0; + public static int MULTIPLE_SELECTION = 0; + + public int getSelectionMode(); + + public String[] getSourceElements(); + + public String getTitle(); +} diff --git a/src/eu/engys/util/ui/ListFieldPanel.java b/src/eu/engys/util/ui/ListFieldPanel.java new file mode 100644 index 0000000..a84f701 --- /dev/null +++ b/src/eu/engys/util/ui/ListFieldPanel.java @@ -0,0 +1,99 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.beans.PropertyChangeListener; + +import javax.swing.JButton; +import javax.swing.JPanel; + +import eu.engys.util.ui.textfields.StringField; + +public class ListFieldPanel extends JPanel { + private StringField textField; + private JButton button; + + public ListFieldPanel(ListBuilder listBuilder) { + super(new BorderLayout(4, 4)); + setName("list.field.panel"); + + textField = new StringField(); + textField.setName("field"); + textField.setColumns(20); + textField.setEnabled(false); + + button = createButtonDoubleList(listBuilder); + button.setName("button"); + add(textField, BorderLayout.CENTER); + add(button, BorderLayout.EAST); + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + // textField.setEnabled(enabled); + button.setEnabled(enabled); + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener listener) { + if (textField != null) + textField.addPropertyChangeListener(listener); + } + + private JButton createButtonDoubleList(ListBuilder listBuilder) { + JButton button = new JButton(new DoubleListAction(this, listBuilder)); + Dimension prefSize = button.getPreferredSize(); + button.setPreferredSize(new Dimension(24, prefSize.height)); + return button; + } + + public String[] getValues() { + String text = textField.getText().trim(); + if (text.length() == 0) + return new String[0]; + else + return text.split("\\s+"); + } + + public void setValues(String[] values) { + StringBuilder sb = new StringBuilder(); + for (String string : values) { + sb.append(string + " "); + } + textField.setValue(sb.toString()); + } + + @Override + public void setToolTipText(String text) { + super.setToolTipText(text); + button.setToolTipText(text); + textField.setToolTipText(text); + } + +} diff --git a/src/eu/engys/util/ui/NoneSelectedButtonGroup.java b/src/eu/engys/util/ui/NoneSelectedButtonGroup.java new file mode 100644 index 0000000..17da3a7 --- /dev/null +++ b/src/eu/engys/util/ui/NoneSelectedButtonGroup.java @@ -0,0 +1,40 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import javax.swing.ButtonGroup; +import javax.swing.ButtonModel; + +public class NoneSelectedButtonGroup extends ButtonGroup { + @Override + public void setSelected(ButtonModel model, boolean selected) { + if (selected) { + super.setSelected(model, selected); + } else { + clearSelection(); + } + } + } diff --git a/src/eu/engys/util/ui/RadioFieldPanel.java b/src/eu/engys/util/ui/RadioFieldPanel.java new file mode 100644 index 0000000..0634bbb --- /dev/null +++ b/src/eu/engys/util/ui/RadioFieldPanel.java @@ -0,0 +1,113 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Enumeration; + +import javax.swing.AbstractButton; +import javax.swing.ButtonGroup; +import javax.swing.ButtonModel; +import javax.swing.JPanel; +import javax.swing.JRadioButton; + +public class RadioFieldPanel extends JPanel implements ActionListener { + + public static final String PROPERTY_NAME = "value"; + private ButtonGroup bg = new ButtonGroup(); + + public RadioFieldPanel() { + super(new GridLayout(0, 1)); + setOpaque(false); + } + + public void addButton(String string) { + JRadioButton button = new JRadioButton(string); + button.setName(string); + button.setActionCommand(string); + button.addActionListener(this); + bg.add(button); + add(button); + } + + public void addButton(String string, String actionCommand) { + JRadioButton button = new JRadioButton(string); + button.setName(string); + button.setActionCommand(actionCommand); + button.addActionListener(this); + bg.add(button); + add(button); + } + + @Override + public void actionPerformed(ActionEvent e) { + firePropertyChange(PROPERTY_NAME, "", e.getActionCommand()); + } + + public String getSelectedKey() { + return bg.getSelection() != null ? bg.getSelection().getActionCommand() : null; + } + + public String getSelectedItem() { + return bg.getSelection() != null ? getButton(bg.getSelection()).getText() : null; + } + + private AbstractButton getButton(ButtonModel bm) { + for (Enumeration e = bg.getElements(); e.hasMoreElements();) { + AbstractButton b = e.nextElement(); + if (b.getModel().equals(bm)) { + return b; + } + } + return null; + } + + public void select(String actionCommand) { + for (Enumeration e = bg.getElements(); e.hasMoreElements();) { + AbstractButton b = e.nextElement(); + if (b.getActionCommand().equals(actionCommand)) { + bg.setSelected(b.getModel(), true); + return; + } + } + } + + public int getButtonCount() { + return bg.getButtonCount(); + } + + public void doClick(String actionCommand) { + for (Enumeration e = bg.getElements(); e.hasMoreElements();) { + AbstractButton b = e.nextElement(); + if (b.getActionCommand().equals(actionCommand)) { + b.doClick(); + return; + } + } + } +} diff --git a/src/eu/engys/util/ui/ResourcesUtil.java b/src/eu/engys/util/ui/ResourcesUtil.java new file mode 100644 index 0000000..c055067 --- /dev/null +++ b/src/eu/engys/util/ui/ResourcesUtil.java @@ -0,0 +1,113 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.net.URL; +import java.util.Enumeration; +import java.util.ResourceBundle; + +import javax.swing.Icon; +import javax.swing.ImageIcon; + +import org.slf4j.LoggerFactory; + +public final class ResourcesUtil { + + private static final ResourceBundle bundle = getBundle("eu/engys/resources/bundle"); + private static final ClassLoader loader = ResourcesUtil.class.getClassLoader(); + + private static final Icon EMPTY_ICON = new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB) { + { + Graphics2D g = createGraphics(); + g.setColor(Color.RED); + g.fillRect(0, 0, 16, 16); + } + }); + + public static String getString(String key) { + try { + return bundle.getString(key); + } catch (Exception e) { + LoggerFactory.getLogger(ResourcesUtil.class).warn(e.getMessage()); + return "MISSING"; + } + } + + private static ResourceBundle getBundle(String string) { + try { + return ResourceBundle.getBundle(string); + } catch (Exception e) { + return new ResourceBundle() { + + @Override + protected Object handleGetObject(String key) { + return null; + } + + @Override + public Enumeration getKeys() { + return null; + } + + }; + } + } + + public static Icon getResourceIcon(String path) { + URL resource = ResourcesUtil.class.getClassLoader().getResource(path); + if (resource == null) { + return EMPTY_ICON; + } else { + return new ImageIcon(resource); + } + } + + public static Icon getIcon(String key) { + try { + String path = bundle.getString(key); + URL res = loader.getResource(path); + return new ImageIcon(res); + } catch (Exception e) { + LoggerFactory.getLogger(ResourcesUtil.class).warn(e.getMessage()); + return EMPTY_ICON; + } + } + + public static URL getIconURL(String key) { + try { + String path = bundle.getString(key); + URL res = loader.getResource(path); + return res; + } catch (Exception e) { + LoggerFactory.getLogger(ResourcesUtil.class).warn(e.getMessage()); + return null; + } + } +} diff --git a/src/eu/engys/util/ui/ScriptEditor.java b/src/eu/engys/util/ui/ScriptEditor.java new file mode 100644 index 0000000..44097c7 --- /dev/null +++ b/src/eu/engys/util/ui/ScriptEditor.java @@ -0,0 +1,367 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dialog.ModalityType; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SwingConstants; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.DefaultEditorKit; + +import org.apache.commons.io.FileUtils; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rtextarea.RTextScrollPane; + +import eu.engys.util.IOUtils; +import eu.engys.util.PrefUtil; +import eu.engys.util.Util; +import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue; +import eu.engys.util.filechooser.HelyxFileChooser; +import eu.engys.util.filechooser.util.SelectionMode; + +public class ScriptEditor { + + public enum Syntax { + BASH, BATCH, PYTHON, JAVA, C + }; + + public static final String BAT_COMMENT = "rem "; + public static final String SHELL_COMMENT = "# "; + + private static ScriptEditor instance; + + private JDialog dialog; + private RSyntaxTextArea editor; + private DocumentListener documentListener; + + private File file; + private List defaultScript; + private boolean modified; + private JButton okButton; + + public static ScriptEditor getInstance() { + if (instance == null) + instance = new ScriptEditor(); + return instance; + } + + private ScriptEditor() { + initEditor(); + initListeners(); + } + + private void initEditor() { + this.editor = new RSyntaxTextArea(); + // End of line is changed in save method + // This is used to split text in lines + editor.getDocument().putProperty(DefaultEditorKit.EndOfLineStringProperty, IOUtils.EOL); + editor.setCodeFoldingEnabled(true); + editor.setAntiAliasingEnabled(true); + editor.setBackground(new Color(240, 240, 240)); + editor.setName("codeEditor"); + } + + private void initListeners() { + documentListener = new DocumentListener() { + + @Override + public void removeUpdate(DocumentEvent e) { + documentModified(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentModified(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentModified(); + } + }; + } + + private void documentModified() { + if (!modified) { + if (dialog != null) { + dialog.setTitle("*" + dialog.getTitle()); + this.modified = true; + } + } + } + + public void show(Syntax syntax, Path scriptPath, List defaultScript) { + String style = ""; + switch (syntax) { + case BASH: + style = SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL; + break; + case BATCH: + style = SyntaxConstants.SYNTAX_STYLE_WINDOWS_BATCH; + break; + case PYTHON: + style = SyntaxConstants.SYNTAX_STYLE_PYTHON; + break; + case C: + style = SyntaxConstants.SYNTAX_STYLE_C; + break; + case JAVA: + style = SyntaxConstants.SYNTAX_STYLE_JAVA; + break; + + default: + break; + } + editor.setSyntaxEditingStyle(style); + show(scriptPath, defaultScript); + } + + public void show(Path scriptPath, List defaultScript) { + this.defaultScript = defaultScript; + this.file = scriptPath != null ? scriptPath.toFile() : null; + this.editor.setSyntaxEditingStyle(Util.isWindowsScriptStyle() ? SyntaxConstants.SYNTAX_STYLE_WINDOWS_BATCH : SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL); + ExecUtil.invokeAndWait(new Runnable() { + + @Override + public void run() { + initDialog(); + load(); + dialog.setVisible(true); + } + }); + } + + private void initDialog() { + dialog = new JDialog(UiUtil.getActiveWindow(), ModalityType.MODELESS); + dialog.setName("script.editor.dialog"); + dialog.getContentPane().setLayout(new BorderLayout()); + dialog.getContentPane().add(createMainPanel(), BorderLayout.CENTER); + dialog.getContentPane().add(createButtonsPanel(), BorderLayout.SOUTH); + dialog.getContentPane().doLayout(); + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + closeDialog(); + } + }); + + dialog.setSize(800, 600); + dialog.setLocationRelativeTo(null); + dialog.getRootPane().setDefaultButton(okButton); + } + + private JPanel createMainPanel() { + RTextScrollPane sp = new RTextScrollPane(editor); + sp.setFoldIndicatorEnabled(true); + sp.setBorder(BorderFactory.createEmptyBorder()); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(sp); + return mainPanel; + } + + private JPanel createButtonsPanel() { + JPanel panel = new JPanel(new GridLayout(1, 2)); + JPanel leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + JButton resetButton = new JButton(new ResetAction()); + resetButton.setName("reset"); + leftPanel.add(resetButton); + JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + + okButton = new JButton(new OKAction()); + okButton.setName("OK"); + rightPanel.add(okButton); + + JButton cancelButton = new JButton(new CancelAction()); + cancelButton.setName("cancel"); + rightPanel.add(cancelButton); + + panel.add(leftPanel); + panel.add(rightPanel); + + JPanel buttonsPanel = new JPanel(new BorderLayout()); + buttonsPanel.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.NORTH); + buttonsPanel.add(panel, BorderLayout.CENTER); + + return buttonsPanel; + } + + private void closeDialog() { + dialog.setVisible(false); + dialog.dispose(); + dialog = null; + } + + private void load() { + editor.getDocument().removeDocumentListener(documentListener); + if (file != null && file.exists()) { + try { + // IOUtils.loadFromFile(editor, file, null, Charset.defaultCharset()); + editor.setText(IOUtils.readStringFromFile(file)); + editor.setCaretPosition(0); + } catch (Exception e) { + e.printStackTrace(); + } + dialog.setTitle(file.getAbsolutePath()); + } else { + editor.setText(""); + dialog.setTitle("newScript"); + } + editor.getDocument().addDocumentListener(documentListener); + this.modified = false; + } + + private void save() { + if (file != null && file.exists()) { + try { + IOUtils.writeStringToFile(file, editor.getText()); + } catch (Exception e) { + e.printStackTrace(); + } + dialog.setTitle(file.getAbsolutePath()); + } else { + saveAs(); + } + } + + private void saveAs() { + File lastDir = PrefUtil.getWorkDir(PrefUtil.WORK_DIR); + HelyxFileChooser fc = new HelyxFileChooser(lastDir.getAbsolutePath()); + fc.setParent(dialog); + fc.setSelectionMode(SelectionMode.FILES_ONLY); + ReturnValue retVal = fc.showSaveAsDialog(); + if (retVal.isApprove()) { + File file = fc.getSelectedFile(); + if (file != null) { + if (file.exists()) { + int answer = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "File already exists. Overwrite?", "File Overwrite", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (answer == JOptionPane.YES_OPTION) { + setFile(file); + save(); + } + } else { + try { + file.createNewFile(); + setFile(file); + save(); + } catch (IOException e) { + e.printStackTrace(); + } + } + PrefUtil.putFile(PrefUtil.WORK_DIR, file.getParentFile()); + } + } + } + + private void setFile(File file) { + this.file = file; + } + + private class OKAction extends AbstractAction { + public OKAction() { + super("OK"); + } + + @Override + public void actionPerformed(ActionEvent e) { + save(); + closeDialog(); + } + } + + private class CancelAction extends AbstractAction { + public CancelAction() { + super("Cancel"); + } + + @Override + public void actionPerformed(ActionEvent e) { + closeDialog(); + } + + } + + private class ResetAction extends AbstractAction { + public ResetAction() { + super("Reset"); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (file != null) { + try { + File defaultFile = File.createTempFile("xxx", null); + IOUtils.writeLinesToFile(defaultFile, getDefaultFileLinesAndOldOnesCommented()); + editor.setText(IOUtils.readStringFromFile(defaultFile)); + editor.setCaretPosition(0); + FileUtils.deleteQuietly(defaultFile); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + private List getDefaultFileLinesAndOldOnesCommented() throws IOException { + List commentedLines = getCurrentFileCommentedLines(); + + List newLines = new ArrayList<>(); + newLines.addAll(defaultScript); + newLines.add(""); + newLines.addAll(commentedLines); + return newLines; + } + + private List getCurrentFileCommentedLines() throws IOException { + String comment = Util.isWindowsScriptStyle() ? BAT_COMMENT : SHELL_COMMENT; + List commentedLines = new ArrayList<>(); + for (String line : FileUtils.readLines(file)) { + commentedLines.add(new StringBuilder(comment).append(line).toString()); + } + return commentedLines; + } + } +} diff --git a/src/eu/engys/util/ui/SelectionValueConfigurator.java b/src/eu/engys/util/ui/SelectionValueConfigurator.java new file mode 100644 index 0000000..3018f4b --- /dev/null +++ b/src/eu/engys/util/ui/SelectionValueConfigurator.java @@ -0,0 +1,32 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +public interface SelectionValueConfigurator { + public String write(String value); + + public String read(String value); +} diff --git a/src/eu/engys/util/ui/TableUtil.java b/src/eu/engys/util/ui/TableUtil.java new file mode 100644 index 0000000..885e16c --- /dev/null +++ b/src/eu/engys/util/ui/TableUtil.java @@ -0,0 +1,43 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import javax.swing.JTable; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; + +public class TableUtil { + + public static void disableSorting(JTable table) { + TableRowSorter sorter = (TableRowSorter) table.getRowSorter(); + if (sorter != null) { + for (int i = 0; i < table.getColumnCount(); i++) { + sorter.setSortable(i, false); + } + } + } + +} diff --git a/src/eu/engys/util/ui/TreeUtil.java b/src/eu/engys/util/ui/TreeUtil.java new file mode 100644 index 0000000..be8cc6f --- /dev/null +++ b/src/eu/engys/util/ui/TreeUtil.java @@ -0,0 +1,154 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.List; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.MutableTreeNode; +import javax.swing.tree.TreePath; + +public class TreeUtil { + + public static boolean areSiblings(TreePath[] selectionPath) { + if (selectionPath.length == 0) + return true; + return areSiblings(selectionPath, selectionPath[0].getParentPath()); + } + + public static boolean areSiblings(TreePath[] selectionPath, TreePath parent) { + if (selectionPath.length == 0) + return true; + for (TreePath path : selectionPath) { + if (!parent.isDescendant(path)) { + return false; + } + } + return true; + } + + public static boolean isConsistent(List selection, Class klass) { + return isConsistent(selection.toArray(), klass); + } + + public static boolean isConsistent(Object[] selection, Class klass) { + if (selection == null || selection.length == 0) + return false; + for (Object object : selection) { + if (!(klass.isInstance(object))) { + return false; + } + } + return true; + } + + public static List toUserObjects(TreePath[] selectionPath) { + List selection = new ArrayList<>(); + for (TreePath treePath : selectionPath) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath.getLastPathComponent(); + Object userObject = node.getUserObject(); + selection.add(userObject); + } + return selection; + } + + public static Object[] toUserObjectsArray(TreePath[] selectionPath) { + return toUserObjects(selectionPath).toArray(); + } + + public static TreePath[] getAConsistentSelection(TreePath[] selectionPath) { + List consistentPath = new ArrayList<>(); + Object[] selection = TreeUtil.toUserObjectsArray(selectionPath); + Class firstClass = selection[0].getClass(); + + for (int i = 0; i < selection.length; i++) { + if (firstClass.isInstance(selection[i])) { + // System.out.println("TreeUtil.getAConsistentSelection() "+firstClass+" == "+selection[i].getClass()); + consistentPath.add(selectionPath[i]); + } else { + // System.out.println("TreeUtil.getAConsistentSelection() "+firstClass+" != "+selection[i].getClass()); + + } + } + + return consistentPath.toArray(new TreePath[0]); + } + + public static DefaultMutableTreeNode getFirstLevelParent(DefaultMutableTreeNode node) { + if (node.getLevel() == 1) { + return node; + } + DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent(); + if (parent != null && parent.getLevel() == 1) + return parent; + else + return getFirstLevelParent(parent); + } + + private static TreeNodeComparator tnc = new TreeNodeComparator(); + + public static void sortTree(DefaultMutableTreeNode root) { + Enumeration e = root.depthFirstEnumeration(); + while (e.hasMoreElements()) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement(); + if (!node.isLeaf()) { + sortChildren(node); + } + } + } + + public static void sortChildren(DefaultMutableTreeNode parent) { + @SuppressWarnings("unchecked") + Enumeration e = parent.children(); + List children = Collections.list(e); + + Collections.sort(children, tnc); + parent.removeAllChildren(); + for (MutableTreeNode node : children) { + parent.add(node); + } + } + + private static class TreeNodeComparator implements Comparator { + @Override + public int compare(DefaultMutableTreeNode a, DefaultMutableTreeNode b) { + if (a.getLevel() > b.getLevel()) { + return 1; + } else if (a.getLevel() < b.getLevel()) { + return -1; + } else { + String sa = a.getUserObject().toString(); + String sb = b.getUserObject().toString(); + return sa.compareToIgnoreCase(sb); + } + } + } +} diff --git a/src/eu/engys/util/ui/UiUtil.java b/src/eu/engys/util/ui/UiUtil.java new file mode 100644 index 0000000..73acd63 --- /dev/null +++ b/src/eu/engys/util/ui/UiUtil.java @@ -0,0 +1,891 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.FontMetrics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.io.File; +import java.lang.Thread.UncaughtExceptionHandler; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JTabbedPane; +import javax.swing.JToggleButton; +import javax.swing.JToolBar; +import javax.swing.JTree; +import javax.swing.ListCellRenderer; +import javax.swing.LookAndFeel; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.TabbedPaneUI; +import javax.swing.plaf.metal.MetalLookAndFeel; +import javax.swing.plaf.metal.MetalTabbedPaneUI; +import javax.swing.plaf.synth.SynthLookAndFeel; +import javax.swing.plaf.synth.SynthTabbedPaneUI; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; + +import org.apache.commons.io.FileUtils; + +import eu.engys.util.ApplicationInfo; +import eu.engys.util.connection.SshParameters; +import eu.engys.util.connection.SshUtils; +import eu.engys.util.progress.ProgressMonitor; + +/** Static convenience methods for GUIs which eliminate code duplication. */ +public final class UiUtil { + + public static Window getActiveWindow() { + for (Window window : Window.getWindows()) { + if (window.isShowing() && window.isActive()) + return (Window) window; + } + return null; + } + + public static void debugPreferredSize(JComponent component) { + UiUtil.debugPreferredSize(component, 0, 0); + } + + public static void debugPreferredSize(JComponent component, int limitWidth, int limitHeight) { + double width = component.getPreferredSize().getWidth(); + double height = component.getPreferredSize().getHeight(); + if (component.getComponentCount() == 0) { + StringBuffer out = new StringBuffer("-> LEAF [" + component.getName() + "] - [" + component.getClass().getCanonicalName() + "]"); + if (width >= limitWidth && height >= limitHeight) { + out.append(" - W:[" + width + "] - H:[" + height + "]"); + } + System.out.println(out.toString()); + } else { + StringBuffer out = new StringBuffer("| PARENT [" + component.getName() + "] - [" + component.getClass().getCanonicalName() + "]"); + if (width >= limitWidth && height >= limitHeight) { + out.append(" - W:[" + width + "] - H:[" + height + "]"); + } + System.out.println(out.toString()); + for (Component c : component.getComponents()) { + if (c instanceof JComponent) { + debugPreferredSize((JComponent) c, limitWidth, limitHeight); + } + } + } + } + + public static void showDocumentationNotLoadedWarning(boolean emptyDocumentation) { + if (emptyDocumentation) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Missing file.", ApplicationInfo.getName() + " Documentation error", JOptionPane.ERROR_MESSAGE); + } else { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Ambiguous file name.", ApplicationInfo.getName() + " Documentation error", JOptionPane.ERROR_MESSAGE); + } + } + + public static void showEnvironmentNotLoadedWarning(String application) { + String message = String.format("%s cannot be launched because:\n\t1) %s is not installed on your system.\n\t2) The path to the executable does not exists.\n\t3) The path to the executable is broken.\nPlease, enter %s executable path under: Edit > Preferences.", application, application, application); + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), message, application + " executable error", JOptionPane.WARNING_MESSAGE); + } + + public static void showCoreEnvironmentNotLoadedWarning() { + showCoreEnvironmentNotLoadedWarning(UiUtil.getActiveWindow()); + } + + public static void showCoreEnvironmentNotLoadedWarning(Component parent) { + String token = ApplicationInfo.getName() + " Core"; + String message = String.format("%s cannot be launched because:\n\t1) %s is not installed on your system.\n\t2) The path to the executable does not exists.\n\t3) The path to the executable is broken.\nPlease, enter %s executable path under: Edit > Preferences.", token, token, token); + JOptionPane.showMessageDialog(parent, message, token + " executable error", JOptionPane.WARNING_MESSAGE); + } + + public static void showDemoMessage() { + String message = "The feature requested is not available in this demo version of " + ApplicationInfo.getName() + ".\nPlease contact " + ApplicationInfo.getVendor() + " at " + ApplicationInfo.getMail(); + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), message, "Demo", JOptionPane.INFORMATION_MESSAGE); + } + + public static void show(String title, Component panel, int w, int h) { + UiUtil.centerAndShow(defaultTestFrame(title, panel, w, h)); + } + + public static void show(String title, Component panel) { + UiUtil.centerAndShow(defaultTestFrame(title, panel)); + } + + public static JFrame defaultTestFrame(String title, Component panel, int w, int h) { + JFrame frame = defaultTestFrame(title, panel); + frame.setSize(w, h); + frame.setPreferredSize(new Dimension(w, h)); + return frame; + } + + public static JFrame defaultTestFrame(String title, Component panel) { + JFrame frame = defaultEmptyTestFrame(title); + frame.getContentPane().add(panel, BorderLayout.CENTER); + return frame; + } + + public static JFrame defaultEmptyTestFrame(String title) { + JFrame frame = new JFrame(title); + frame.getContentPane().setLayout(new BorderLayout()); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + return frame; + } + + public static void center(Window aWindow) { + Dimension screen = getScreenSize(); + Dimension window = aWindow.getSize(); + // ensure that no parts of aWindow will be off-screen + if (window.height > screen.height) { + window.height = screen.height; + } + if (window.width > screen.width) { + window.width = screen.width; + } + int xCoord = (screen.width / 2 - window.width / 2); + int yCoord = (screen.height / 2 - window.height / 2); + aWindow.setLocation(xCoord, yCoord); + } + + public static void centerAndShow(Window aWindow) { + aWindow.pack(); + /* + * If called from outside the event dispatch thread (as is the case upon startup, in the launch thread), + * then in principle this code is not thread-safe: once pack has been called, the component is realized, + * and (most) further work on the component should take place in the event-dispatch thread. + * + * In practice, it is exceedingly unlikely that this will lead to an error, since invisible components cannot receive events. + */ + center(aWindow); + aWindow.setVisible(true); + } + + public static Border getStandardBorder() { + return BorderFactory.createEmptyBorder(UiUtil.STANDARD_BORDER, UiUtil.STANDARD_BORDER, UiUtil.STANDARD_BORDER, UiUtil.STANDARD_BORDER); + } + + public static JComponent getCommandRow(JComponent... aButtons) { + List list = Arrays.asList(aButtons); + return getCommandRow(list); + } + + public static JComponent getCommandRow(java.util.List aButtons) { + equalizeSizes(aButtons); + JPanel panel = new JPanel(); + LayoutManager layout = new BoxLayout(panel, BoxLayout.X_AXIS); + panel.setLayout(layout); + panel.setOpaque(false); + panel.setBorder(BorderFactory.createEmptyBorder(UiUtil.TWO_SPACES, 0, 0, 0)); + panel.add(Box.createHorizontalGlue()); + Iterator buttonsIter = aButtons.iterator(); + while (buttonsIter.hasNext()) { + panel.add(buttonsIter.next()); + if (buttonsIter.hasNext()) { + panel.add(Box.createHorizontalStrut(UiUtil.ONE_SPACE)); + } + } + return panel; + } + + public static JComponent getCommandColumn(java.util.List aButtons) { + equalizeSizes(aButtons); + JPanel panel = new JPanel(); + LayoutManager layout = new BoxLayout(panel, BoxLayout.Y_AXIS); + panel.setLayout(layout); + panel.setOpaque(false); + panel.setBorder(BorderFactory.createEmptyBorder(0, UiUtil.TWO_SPACES, 0, 0)); + // (no for-each is used here, because of the 'not-yet-last' check) + Iterator buttonsIter = aButtons.iterator(); + while (buttonsIter.hasNext()) { + panel.add(buttonsIter.next()); + if (buttonsIter.hasNext()) { + panel.add(Box.createVerticalStrut(UiUtil.ONE_SPACE)); + } + } + panel.add(Box.createVerticalGlue()); + return panel; + } + + public static JComponent getCommandColumnToolbar(java.util.List aButtons) { + equalizeSizes(aButtons); + JToolBar panel = getToolbar("command.column.toolbar"); + LayoutManager layout = new BoxLayout(panel, BoxLayout.Y_AXIS); + panel.setLayout(layout); + panel.setOpaque(false); + panel.setFloatable(false); + panel.setBorder(BorderFactory.createEmptyBorder(0, UiUtil.TWO_SPACES, 0, 0)); + + // (no for-each is used here, because of the 'not-yet-last' check) + Iterator buttonsIter = aButtons.iterator(); + while (buttonsIter.hasNext()) { + AbstractButton next = (AbstractButton) buttonsIter.next(); + next.setAlignmentX(Component.LEFT_ALIGNMENT); + next.setHorizontalAlignment(SwingConstants.LEFT); + panel.add(next); + if (buttonsIter.hasNext()) { + panel.add(Box.createVerticalStrut(UiUtil.ONE_SPACE)); + } + } + panel.add(Box.createVerticalGlue()); + return panel; + } + + public static JMenuItem createMenuItem(Action a) { + Icon icon = (Icon) a.getValue(Action.SMALL_ICON); + String text = (String) a.getValue(Action.NAME); + String desc = (String) a.getValue(Action.SHORT_DESCRIPTION); + + JMenuItem item = new JMenuItem(a); + item.setName(text != null ? text : desc); + item.setText(text != null ? text : desc); + item.setIcon(icon); + item.setToolTipText(desc); + + return item; + } + + public static AbstractButton createButton(Action a) { + Icon icon = (Icon) a.getValue(Action.SMALL_ICON); + String text = (String) a.getValue(Action.NAME); + String desc = (String) a.getValue(Action.SHORT_DESCRIPTION); + + JButton b = new JButton(a); + b.setName(text != null ? text : desc); + b.setText(((text != null && text.equals("MISSING")) ? null : text)); + b.setIcon(icon); + b.setToolTipText(desc); + + return b; + } + + public static AbstractButton createToolBarIconButton(Action a) { + return _createToolBarButton(a, false); + } + + public static AbstractButton createToolBarButton(Action a) { + return _createToolBarButton(a, true); + } + + private static AbstractButton _createToolBarButton(Action a, boolean showLabel) { + Icon icon = (Icon) a.getValue(Action.SMALL_ICON); + String text = (String) a.getValue(Action.NAME); + String desc = (String) a.getValue(Action.SHORT_DESCRIPTION); + + JButton b = new JButton(a) { + public Insets getMargin() { + if (super.getMargin() != null) + return new Insets(super.getMargin().top, 2, super.getMargin().bottom, 2); + else + return null; + } + }; + b.setName(text != null ? text : desc); + b.setText(showLabel ? ((text != null && text.equals("MISSING")) ? null : text) : null); + b.setIcon(icon); + b.setToolTipText(desc); + // b.setEnabled(a.isEnabled()); + b.setFocusable(false); + return b; + } + + public static AbstractButton createToolBarMultiButtonBar(String name, Icon icon, String tooltip, final Action... actions) { + final JButton button = new JButton() { + public Insets getMargin() { + if (super.getMargin() != null) + return new Insets(super.getMargin().top, 2, super.getMargin().bottom, 2); + else + return null; + } + }; + button.setName(name); + button.setToolTipText(tooltip); + button.setFocusable(false); + + final JPopupMenu popup = new JPopupMenu(); + for (Action action : actions) { + JMenuItem item = new JMenuItem(action); + item.setName((String) action.getValue(Action.NAME)); + item.setToolTipText(String.valueOf(action.getValue(Action.SHORT_DESCRIPTION))); + popup.add(item); + } + + button.setAction(new ViewAction(name, icon, tooltip) { + + @Override + public void actionPerformed(ActionEvent e) { + popup.show(button, 0, button.getPreferredSize().height); + } + }); + + return button; + } + + public static ButtonBar createToolBarButtonBar(Action... actions) { + ButtonBar bar = new ButtonBar(); + for (Action action : actions) { + AbstractButton button = createButtonBarButton(action); + button.setName((String) action.getValue(Action.NAME)); + bar.add(button); + } + return bar; + } + + public static void clearToolbar(JToolBar toolbar) { + for (Component c : toolbar.getComponents()) { + if (c instanceof AbstractButton) { + ((AbstractButton) c).setSelected(false); + } else if (c instanceof JComboBox) { + ((JComboBox) c).setSelectedIndex(-1); + } + } + } + + public static ButtonBar createToolBarToggleButtonBar(Action... actions) { + ButtonGroup viewGroup = new ButtonGroup(); + ButtonBar bar = new ButtonBar(); + for (Action action : actions) { + bar.add(createButtonBarToggleButton(action, viewGroup)); + } + return bar; + } + + public static AbstractButton createToolBarToggleButton(Action a) { + return createToolBarToggleButton(a, false); + } + + public static JToggleButton createToolBarToggleButton(Action a, final boolean tooltipOver) { + Icon icon = (Icon) a.getValue(Action.SMALL_ICON); + Icon sel_icon = (Icon) a.getValue(Action.SMALL_ICON + Action.SELECTED_KEY); + String text = (String) a.getValue(Action.NAME); + + final JToggleButton b = new JToggleButton(a) { + public Insets getMargin() { + if (super.getMargin() != null) + return new Insets(super.getMargin().top, 2, super.getMargin().bottom, 2); + else + return null; + } + }; + b.getModel().addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + b.getAction().putValue(Action.SELECTED_KEY, b.getModel().isSelected()); + } + }); + b.setName(text); + b.setText((text != null && text.equals("MISSING")) ? null : text); + b.setHorizontalTextPosition(0); + b.setVerticalTextPosition(3); + b.setIcon(icon); + b.setRolloverIcon(icon); + b.setRolloverSelectedIcon(sel_icon); + b.setSelectedIcon(sel_icon); + b.setEnabled(a.isEnabled()); + b.setFocusable(false); + return b; + } + + public static AbstractButton createButtonBarButton(Action a) { + JButton b = new JButton(a) { + public Insets getMargin() { + if (super.getMargin() != null) + return new Insets(super.getMargin().top, 0, super.getMargin().bottom, 0); + else + return null; + } + }; + b.setHorizontalTextPosition(SwingConstants.RIGHT); + // b.setVerticalTextPosition(3); + b.setName((String) a.getValue(Action.NAME)); + b.setFocusable(false); + return b; + } + + public static AbstractButton createButtonBarToggleButton(Action a, ButtonGroup group) { + Icon icon = (Icon) a.getValue(Action.SMALL_ICON); + String text = (String) a.getValue(Action.SHORT_DESCRIPTION); + + JToggleButton b = new JToggleButton(a) { + public Insets getMargin() { + if (super.getMargin() != null) + return new Insets(super.getMargin().top, 0, super.getMargin().bottom, 0); + else + return null; + } + }; + b.setHorizontalTextPosition(0); + b.setVerticalTextPosition(3); + b.setText(""); + b.setIcon(icon); + b.setToolTipText(text); + b.setFocusable(false); + group.add(b); + return b; + } + + public static void updateToolBarComboButton(final JComboBox combo, final List actions) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + _updateToolBarComboButton(combo, actions); + } + }); + } + + private static void _updateToolBarComboButton(JComboBox combo, List actions) { + int selectedIndex = -1; + ActionListener[] actionListeners = combo.getActionListeners(); + for (ActionListener l : actionListeners) { + combo.removeActionListener(l); + } + ItemListener[] itemListeners = combo.getItemListeners(); + for (ItemListener l : itemListeners) { + combo.removeItemListener(l); + } + combo.removeAllItems(); + combo.setPrototypeDisplayValue(getPrototype(actions, combo.getPrototypeDisplayValue())); + for (int j = 0; j < actions.size(); j++) { + combo.addItem(actions.get(j)); + if (actions.get(j).getValue("default") != null) { + selectedIndex = j; + } + } + combo.setSelectedIndex(selectedIndex); + for (ActionListener l : actionListeners) { + combo.addActionListener(l); + } + for (ItemListener l : itemListeners) { + combo.addItemListener(l); + } + } + + public static JComboBox createToolBarComboButton(List actions, String tooltip, String prototype, boolean enabled, final boolean tooltipOver) { + int selectedIndex = -1; + final JComboBox c = new JComboBox(); + c.setPrototypeDisplayValue(getPrototype(prototype)); + for (int j = 0; j < actions.size(); j++) { + c.addItem(actions.get(j)); + if (actions.get(j).getValue("default") != null) { + selectedIndex = j; + } + } + c.setSelectedIndex(selectedIndex); + c.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + if (c.getSelectedIndex() > -1) { + c.getItemAt(c.getSelectedIndex()).actionPerformed(null); + } + } + } + }); + c.setMaximumSize(c.getPreferredSize()); + c.setEnabled(enabled); + c.setToolTipText(tooltip); + c.setRenderer(new ActionsComboBoxRenderer(c.getRenderer())); + return c; + } + + private static Action getPrototype(List actions, Action actualPrototype) { + Action proto = actualPrototype; + for (Action action : actions) { + String actionName = (String) action.getValue(Action.NAME); + String prototypeName = (String) proto.getValue(Action.NAME); + if (actionName.length() > prototypeName.length()) { + proto = action; + } + } + return proto; + } + + private static Action getPrototype(String actionName) { + return new AbstractAction(actionName) { + @Override + public void actionPerformed(ActionEvent arg0) { + } + }; + } + + private static class ActionsComboBoxRenderer extends JLabel implements ListCellRenderer { + + private ListCellRenderer renderer; + + public ActionsComboBoxRenderer(ListCellRenderer renderer) { + this.renderer = renderer; + } + + @SuppressWarnings("unchecked") + public Component getListCellRendererComponent(JList list, Action value, int index, boolean isSelected, boolean cellHasFocus) { + Component c = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + + if (c instanceof JLabel && value != null) { + String text = (String) value.getValue(Action.NAME); + Icon icon = (Icon) value.getValue(Action.SMALL_ICON); + + JLabel label = (JLabel) renderer; + label.setIcon(icon); + label.setText(text); + } + + return c; + } + + } + + public static void equalizeSizes(java.util.List aComponents) { + Dimension targetSize = new Dimension(0, 0); + for (JComponent comp : aComponents) { + Dimension compSize = comp.getPreferredSize(); + double width = Math.max(targetSize.getWidth(), compSize.getWidth()); + double height = Math.max(targetSize.getHeight(), compSize.getHeight()); + targetSize.setSize(width, height); + } + setSizes(aComponents, targetSize); + } + + private static void setSizes(java.util.List aComponents, Dimension aDimension) { + Iterator compsIter = aComponents.iterator(); + while (compsIter.hasNext()) { + JComponent comp = (JComponent) compsIter.next(); + comp.setPreferredSize((Dimension) aDimension.clone()); + comp.setMaximumSize((Dimension) aDimension.clone()); + } + } + + private static List getDescendantsOfType(Class clazz, Container container, boolean nested) { + List tList = new ArrayList(); + + for (Component component : container.getComponents()) { + if (clazz.isAssignableFrom(component.getClass())) { + tList.add(clazz.cast(component)); + } + if (nested || !clazz.isAssignableFrom(component.getClass())) { + if (component instanceof Container) { + tList.addAll(getDescendantsOfType(clazz, (Container) component, nested)); + } + } + } + + return tList; + } + + private static Map> containers = new HashMap>(); + + public static void enable(Container container) { + List enabledComponents = containers.get(container); + if (enabledComponents != null) { + for (JComponent component : enabledComponents) { + if (component instanceof AbstractButton) { + AbstractButton b = (AbstractButton) component; + if (b.getAction() != null) { + b.getAction().setEnabled(true); + } else { + component.setEnabled(true); + } + } else { + component.setEnabled(true); + } + + } + containers.remove(container); + } + } + + public static void disable(Container container) { + List components = getDescendantsOfType(JComponent.class, container, true); + List enabledComponents = new ArrayList(); + if (!containers.containsKey(container)) { + containers.put(container, enabledComponents); + for (JComponent component : components) { + if (component.isEnabled()) { + enabledComponents.add(component); + if (component instanceof AbstractButton) { + AbstractButton b = (AbstractButton) component; + if (b.getAction() != null) { + b.getAction().setEnabled(false); + } else { + component.setEnabled(false); + } + } else { + component.setEnabled(false); + } + } + } + } + } + + + public static void expandAll(JTree tree, boolean expand) { + TreeNode root = (TreeNode) tree.getModel().getRoot(); + + // Traverse tree from root + expandAll(tree, new TreePath(root), expand); + } + + public static void expandAll(JTree tree, TreePath parent, boolean expand) { + // Traverse children + TreeNode node = (TreeNode) parent.getLastPathComponent(); + if (node.getChildCount() >= 0) { + for (Enumeration e = node.children(); e.hasMoreElements();) { + TreeNode n = (TreeNode) e.nextElement(); + TreePath path = parent.pathByAddingChild(n); + expandAll(tree, path, expand); + } + } + + // Expansion or collapse must be done bottom-up + if (expand) { + tree.expandPath(parent); + } else { + tree.collapsePath(parent); + } + } + + public static Boolean testConnection(final SshParameters sshParameters, final ProgressMonitor progressMonitor) { + progressMonitor.setIndeterminate(true); + Boolean retVal = progressMonitor.start("Testing connection...", false, new Callable() { + @Override + public Boolean call() throws Exception { + boolean retVal = SshUtils.testConnection(sshParameters); + progressMonitor.end(); + return retVal; + } + }); + return retVal; + } + + public static boolean isMainScreen(GraphicsDevice currentScreen) { + GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice def = g.getDefaultScreenDevice(); + return def.equals(currentScreen); + } + + public static boolean isSecondaryScreen(GraphicsDevice currentScreen) { + return !isMainScreen(currentScreen); + } + + public static Rectangle getCurrentScreenSize(JFrame frame) { + GraphicsConfiguration config = frame.getGraphicsConfiguration(); + GraphicsDevice currentScreen = config.getDevice(); + return new Rectangle(currentScreen.getDisplayMode().getWidth(), currentScreen.getDisplayMode().getHeight()); + } + + public static JToolBar getToolbar(String name) { + JToolBar toolbar = new JToolBar(); + toolbar.setLayout(new WrappedFlowLayout(FlowLayout.LEFT, 0, 0)); + toolbar.putClientProperty("Synthetica.toolBar.buttons.paintBorder", Boolean.TRUE); + toolbar.putClientProperty("Synthetica.opaque", Boolean.FALSE); + toolbar.setName(name); + toolbar.setFloatable(false); + toolbar.setRollover(false); + toolbar.setOpaque(false); + toolbar.setBorder(BorderFactory.createEmptyBorder()); + + return toolbar; + } + + public static void setOneTabHide(final JTabbedPane tabbedPane) { + try { + LookAndFeel laf = UIManager.getLookAndFeel(); + TabbedPaneUI ui = null; + + if (laf != null && laf instanceof SynthLookAndFeel) { + ui = new SynthTabbedPaneUI() { + @Override + protected int calculateTabAreaHeight(int tabPlacement, int horizRunCount, int maxTabHeight) { + if (tabbedPane.getTabCount() > 1) { + return super.calculateTabAreaHeight(tabPlacement, horizRunCount, maxTabHeight); + } else { + return 0; + } + } + + @Override + protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) { + if (tabbedPane.getTabCount() > 1) { + return super.calculateTabWidth(tabPlacement, tabIndex, metrics); + } else { + return 0; + } + } + + }; + + } else if (laf != null && laf instanceof MetalLookAndFeel) { + ui = new MetalTabbedPaneUI() { + @Override + protected int calculateTabAreaHeight(int tabPlacement, int horizRunCount, int maxTabHeight) { + if (tabbedPane.getTabCount() > 1) { + return super.calculateTabAreaHeight(tabPlacement, horizRunCount, maxTabHeight); + } else { + return 0; + } + } + + @Override + protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) { + if (tabbedPane.getTabCount() > 1) { + return super.calculateTabWidth(tabPlacement, tabIndex, metrics); + } else { + return 0; + } + } + + }; + } + tabbedPane.setUI(ui); + } catch (Exception e) { + // e.printStackTrace(); + } + } + + public static void installExceptionHandler() { + Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + if (GraphicsEnvironment.isHeadless()) { + } else { + e.printStackTrace(); +// StringOutputStream stream = new StringOutputStream(); +// e.printStackTrace(new PrintStream(stream)); +// String msg = stream.toString(); +// System.err.println(msg); +// JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), msg, "An error occurred", JOptionPane.ERROR_MESSAGE); + } + } + }); + } + + public static void renameUIThread() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + if (SwingUtilities.isEventDispatchThread()) { + Thread.currentThread().setName("GUI Dispatch Queue"); + } + } + }); + } + + public static Dimension getScreenSize() { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] screenDevices = ge.getScreenDevices(); + // System.out.println("UiUtil.getPreferredDimension() screenDevices.length: "+screenDevices.length); + if (screenDevices.length > 1) { + int width = screenSize.width; + int height = screenSize.height; + for (int i = 0; i < screenDevices.length; i++) { + GraphicsDevice gd = screenDevices[i]; + width = Math.min(width, gd.getDisplayMode().getWidth()); + height = Math.min(height, gd.getDisplayMode().getHeight()); + } + + // System.out.println("UiUtil.getPreferredDimension() width: "+width+" height: "+height); + return new Dimension(width, height); + } else { + return screenSize; + } + } + + public static Dimension getPreferredScreenSize() { + Dimension screenSize = getScreenSize(); + int W = screenSize.width * 8 / 10; + int H = screenSize.height * 8 / 10; + + return new Dimension(W, H); + } + + public static void printLogOnDesktopFile(String log) { + printLogOnDesktopFile(log, true); + } + + public static void printLogOnDesktopFile(String log, boolean append) { + try { + File desktopFolder = Paths.get(System.getProperty("user.home"), "Desktop").toFile(); + if (desktopFolder.exists()) { + File logFile = new File(desktopFolder, "log.txt"); + if (!logFile.exists()) { + logFile.createNewFile(); + } + String date = new SimpleDateFormat("'['HH:mm:ss']'").format(new Date()); + FileUtils.writeStringToFile(logFile, date + " - " + log + "\n", append); + } + } catch (Exception e) { + + } + + } + + public static final int ONE_SPACE = 5; + public static final int TWO_SPACES = 11; + public static final int THREE_SPACES = 17; + public static final int STANDARD_BORDER = TWO_SPACES; + +} diff --git a/src/eu/engys/util/ui/ViewAction.java b/src/eu/engys/util/ui/ViewAction.java new file mode 100644 index 0000000..65362ce --- /dev/null +++ b/src/eu/engys/util/ui/ViewAction.java @@ -0,0 +1,90 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui; + +import java.awt.event.InputEvent; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.KeyStroke; + +public abstract class ViewAction extends AbstractAction { + + public ViewAction(String text, String tooltip) { + super(text, null); + putValue(SHORT_DESCRIPTION, tooltip); + } + + public ViewAction(Icon icon, String tooltip) { + super(null, icon); + putValue(SHORT_DESCRIPTION, tooltip); + } + + public ViewAction(String text, Icon icon, boolean enabled) { + super(text, icon); + setEnabled(enabled); + } + + public ViewAction(String text, Icon icon, String tooltip) { + super(text, icon); + putValue(SHORT_DESCRIPTION, tooltip); + } + + public ViewAction(String text, Icon icon, String tooltip, boolean enabled) { + super(text, icon); + putValue(SHORT_DESCRIPTION, tooltip); + setEnabled(enabled); + } + + public ViewAction(String text, Icon icon, String tooltip, int mnemonic) { + super(text, icon); + putValue(SHORT_DESCRIPTION, tooltip); + putValue(MNEMONIC_KEY, mnemonic); + putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(mnemonic, InputEvent.CTRL_DOWN_MASK)); + } + + public boolean isSelected() { + return Boolean.TRUE.equals(getValue(Action.SELECTED_KEY)); + } + + public void setSelected(boolean b) { + putValue(Action.SELECTED_KEY, Boolean.valueOf(b)); + } + + public String getText() { + return (String) getValue(NAME); + } + + public String getTooltip() { + return (String) getValue(SHORT_DESCRIPTION); + } + + public Icon getIcon() { + return (Icon) getValue(SMALL_ICON); + } +} diff --git a/src/eu/engys/util/ui/WrappedFlowLayout.java b/src/eu/engys/util/ui/WrappedFlowLayout.java new file mode 100644 index 0000000..2350477 --- /dev/null +++ b/src/eu/engys/util/ui/WrappedFlowLayout.java @@ -0,0 +1,131 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Insets; + +public class WrappedFlowLayout extends FlowLayout { + public WrappedFlowLayout() { + super(); + } + + public WrappedFlowLayout(int align) { + super(align); + } + + public WrappedFlowLayout(int align, int hgap, int vgap) { + super(align, hgap, vgap); + } + + public Dimension minimumLayoutSize(Container target) { + // Size of largest component, so we can resize it in + // either direction with something like a split-pane. + return computeMinSize(target); + } + + public Dimension preferredLayoutSize(Container target) { + return computeSize(target); + } + + private Dimension computeSize(Container target) { + synchronized (target.getTreeLock()) { + int hgap = getHgap(); + int vgap = getVgap(); + int w = target.getWidth(); + + // Let this behave like a regular FlowLayout (single row) + // if the container hasn't been assigned any size yet + if (w == 0) { + w = Integer.MAX_VALUE; + } + + Insets insets = target.getInsets(); + if (insets == null) { + insets = new Insets(0, 0, 0, 0); + } + int reqdWidth = 0; + + int maxwidth = w - (insets.left + insets.right + hgap * 2); + int n = target.getComponentCount(); + int x = 0; + int y = insets.top + vgap; // FlowLayout starts by adding vgap, + // so do that here too. + int rowHeight = 0; + + for (int i = 0; i < n; i++) { + Component c = target.getComponent(i); + if (c.isVisible()) { + Dimension d = c.getPreferredSize(); + if ((x == 0) || ((x + d.width) <= maxwidth)) { + // fits in current row. + if (x > 0) { + x += hgap; + } + x += d.width; + rowHeight = Math.max(rowHeight, d.height); + } else { + // Start of new row + x = d.width; + y += vgap + rowHeight; + rowHeight = d.height; + } + reqdWidth = Math.max(reqdWidth, x); + } + } + y += rowHeight; + y += insets.bottom; + return new Dimension(reqdWidth + insets.left + insets.right, y); + } + } + + private Dimension computeMinSize(Container target) { + synchronized (target.getTreeLock()) { + int minx = Integer.MAX_VALUE; + int miny = Integer.MIN_VALUE; + boolean found_one = false; + int n = target.getComponentCount(); + + for (int i = 0; i < n; i++) { + Component c = target.getComponent(i); + if (c.isVisible()) { + found_one = true; + Dimension d = c.getPreferredSize(); + minx = Math.min(minx, d.width); + miny = Math.min(miny, d.height); + } + } + if (found_one) { + return new Dimension(minx, miny); + } + return new Dimension(0, 0); + } + } + +} diff --git a/src/eu/engys/util/ui/builder/GroupController.java b/src/eu/engys/util/ui/builder/GroupController.java new file mode 100644 index 0000000..682020d --- /dev/null +++ b/src/eu/engys/util/ui/builder/GroupController.java @@ -0,0 +1,51 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.builder; + +import java.awt.event.ActionListener; + +import javax.swing.JComponent; + +public interface GroupController { + void addActionListener(ActionListener pop); + + String getSelectedKey(); + + void setSelectedIndex(int i); + + void setSelectedItem(String groupName); + + void setSelectedKey(String key); + + void addGroup(String groupKey, String groupName); + + void addChildController(GroupController controller); + + GroupController getChildController(String selectedKey); + + JComponent getComponent(); +} diff --git a/src/eu/engys/util/ui/builder/HideController.java b/src/eu/engys/util/ui/builder/HideController.java new file mode 100644 index 0000000..a5fbcb9 --- /dev/null +++ b/src/eu/engys/util/ui/builder/HideController.java @@ -0,0 +1,101 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.builder; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.JComponent; +import javax.swing.JLabel; + + +public class HideController implements GroupController { + private ActionListener action; + private JLabel label = new JLabel(); + private List groups = new ArrayList(); + private List keys = new ArrayList(); + private Map childControllers = new HashMap(); + + private String selectedKey = null; + + @Override + public void setSelectedIndex(int i) { + setSelectedItem(groups.get(i)); + } + + @Override + public void setSelectedItem(String item) { + selectedKey = item != null ? keys.get(groups.indexOf(item)) : null; + action.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, selectedKey)); + label.setText(item); + } + + @Override + public void setSelectedKey(String key) { + setSelectedIndex(keys.indexOf(key)); + } + + @Override + public String getSelectedKey() { + return selectedKey; + } + + public String getSelectedItem() { + return groups.get(keys.indexOf(selectedKey)); + } + + @Override + public void addChildController(GroupController controller) { + childControllers.put(keys.get(keys.size()-1), controller); + } + + @Override + public GroupController getChildController(String key) { + return childControllers.get(key); + } + + @Override + public JComponent getComponent() { + return label; + } + + @Override + public void addGroup(String groupKey, String groupName) { + groups.add(groupName); + keys.add(groupKey); + } + + @Override + public void addActionListener(ActionListener showHideAction) { + this.action = showHideAction; + } + +} diff --git a/src/eu/engys/util/ui/builder/JCheckBoxController.java b/src/eu/engys/util/ui/builder/JCheckBoxController.java new file mode 100644 index 0000000..214789f --- /dev/null +++ b/src/eu/engys/util/ui/builder/JCheckBoxController.java @@ -0,0 +1,103 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.builder; + +import java.awt.Color; +import java.awt.Font; +import java.awt.event.ActionListener; + +import javax.swing.JCheckBox; +import javax.swing.JComponent; + + +public class JCheckBoxController extends JCheckBox implements GroupController { + + private String selectedKey; + + public JCheckBoxController(String name) { + super(name); + setName(name); + setOpaque(false); + setFocusable(false); + } + + @Override + public void addActionListener(ActionListener action) { + super.addActionListener(action); + } + + @Override + public void addGroup(String groupKey, String groupName) { + this.selectedKey = groupKey; + } + + @Override + public JComponent getComponent() { + return this; + } + + @Override + public void setSelectedIndex(int i) { + super.doClick(); + } + + @Override + public void setSelectedItem(String groupName) { + super.doClick(); + } + + @Override + public void setSelectedKey(String key) { + super.doClick(); + } + + @Override + public String getSelectedKey() { + return isSelected() ? selectedKey : null; + } + + @Override + public void addChildController(GroupController controller) { + } + + @Override + public GroupController getChildController(String selectedKey) { + return null; + } + + @Override + public Font getFont() { + Font font = super.getFont(); + return font != null ? font.deriveFont(Font.BOLD) : font; + } + + @Override + public Color getForeground() { + // if (isEnabled()) return Color.BLUE; + return super.getForeground(); + } +} diff --git a/src/eu/engys/util/ui/builder/JComboBoxController.java b/src/eu/engys/util/ui/builder/JComboBoxController.java new file mode 100644 index 0000000..be9608e --- /dev/null +++ b/src/eu/engys/util/ui/builder/JComboBoxController.java @@ -0,0 +1,95 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.builder; + +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.JComponent; + +import eu.engys.util.ui.JComboBoxWithItemsSupport; + +public class JComboBoxController extends JComboBoxWithItemsSupport implements GroupController { + + private List keys = new ArrayList(); + private Map childControllers = new HashMap(); + + public JComboBoxController() { + super(); + } + + @Override + public void addActionListener(ActionListener action) { + super.addActionListener(action); + } + + @Override + public void addGroup(String groupKey, String groupName) { + if (!keys.contains(groupKey)) { + keys.add(groupKey); + super.addItem(groupName); + } + } + + @Override + public void addChildController(GroupController controller) { + childControllers.put(keys.get(keys.size()-1), controller); + } + + @Override + public GroupController getChildController(String key) { + return childControllers.get(key); + } + + @Override + public JComponent getComponent() { + return this; + } + + @Override + public void setSelectedItem(String groupName) { + super.setSelectedItem(groupName); + } + + @Override + public void setSelectedKey(String key) { + super.setSelectedIndex(keys.indexOf(key)); + } + + @Override + public String getSelectedKey() { + int index = getSelectedIndex(); + return index < 0 ? null : keys.get(index); + } + + public boolean containsKey(String key) { + return keys.contains(key); + } +} diff --git a/src/eu/engys/util/ui/builder/PanelBuilder.java b/src/eu/engys/util/ui/builder/PanelBuilder.java new file mode 100644 index 0000000..e707729 --- /dev/null +++ b/src/eu/engys/util/ui/builder/PanelBuilder.java @@ -0,0 +1,628 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui.builder; + +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import net.java.dev.designgridlayout.DesignGridLayout; +import net.java.dev.designgridlayout.INonGridRow; +import net.java.dev.designgridlayout.IRowCreator; +import net.java.dev.designgridlayout.ISpannableGridRow; +import net.java.dev.designgridlayout.RowGroup; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.util.TooltipUtils; +import eu.engys.util.ui.UiUtil; + +/** + *
+ * startChoice("Autore");
+ * startGroup("Disney");
+ *   startChoice("Citta");
+ *       startGroup("Topolinia");
+ *           startChoice("Personaggi");
+ *               startGroup("Topolino");
+ *                   newRow().grid(label("topolino")).add(label("TOPOLINO"));
+ *                   newRow().grid(label("minnie")).add(label("MINNIE"));
+ *                  newRow().grid(label("pluto")).add(label("PLUTO"));
+ *               endGroup();
+ *              startGroup("Pippo");
+ *                   newRow().grid(label("pippo")).add(label("PIPPO"));
+ *                   newRow().grid(label("orazio")).add(label("ORAZIO"));
+ *                   newRow().grid(label("clarabella")).add(label("CLARABELLA"));
+ *               endGroup();
+ *               startGroup("Commissariato");
+ *                   newRow().grid(label("basettoni")).add(label("BASETTONI"));
+ *                   newRow().grid(label("manetta")).add(label("MANETTA"));
+ *              endGroup();
+ *          endChoice();//personaggi
+ *       endGroup();//topolinia
+ *       startGroup("Paperopoli");
+ *           startChoice("Personaggi");
+ *               startGroup("Paperino");
+ *                   newRow().grid(label("paperino")).add(label("PAPERINO"));
+ *                   newRow().grid(label("paperina")).add(label("PAPERINA"));
+ *                   newRow().grid(label("qui")).add(label("QUI"));
+ *                   newRow().grid(label("quo")).add(label("QUO"));
+ *                   newRow().grid(label("qua")).add(label("QUA"));
+ *               endGroup();
+ *               startGroup("NonnaPapera");
+ *                  newRow().grid(label("nonna")).add(label("NONNA"));
+ *                   newRow().grid(label("ciccio")).add(label("CICCIO"));
+ *               endGroup();
+ *           endChoice();//personaggi
+ *       endGroup();//paperopoli
+ *   evndChoice();//citta
+ * endGroup();//disney
+ * startGroup("Marvel");
+ *   startChoice("Gotham City");
+ *       startGroup("Batman");
+ *           newRow().grid(label("batman")).add(label("BATMAN"));
+ *           newRow().grid(label("robin")).add(label("ROBIN"));
+ *           newRow().grid(label("qui")).add(label("QUI"));
+ *           newRow().grid(label("quo")).add(label("QUO"));
+ *       endGroup();
+ *       startGroup("Cattivi");
+ *           newRow().grid(label("penguin")).add(label("PENGUIN"));
+ *           newRow().grid(label("poisonivy")).add(label("POISONIVY"));
+ *       endGroup();
+ *   endChoice();//gotham city
+ * endGroup();//marvel
+ * endChoice();//autore
+ * 
+ * + */ +public class PanelBuilder { + + private static final Logger logger = LoggerFactory.getLogger(PanelBuilder.class); + + private DesignGridLayout layout; + private final JPanel parent; + private int level = 0; + private int indent = 0; + + protected Stack groups = new Stack(); + protected Stack controllers = new Stack(); + protected Stack actions = new Stack(); + + private HashMap hideables = new HashMap(); + + private String prefix = ""; + + public PanelBuilder() { + super(); + this.parent = new JPanel(); + this.parent.setOpaque(false); + this.layout = new DesignGridLayout(parent); + // layout.labelAlignment(LabelAlignment.RIGHT); + layout.withoutConsistentWidthAcrossNonGridRows(); + layout.emptyRow(); + } + + public PanelBuilder(String name) { + this(); + this.parent.setName(name); + } + + public JPanel getPanel() { + return (JPanel) parent; + } + + public PanelBuilder removeMargins() { + layout.margins(0, 0, 0, 0); + return this; + } + + public PanelBuilder margins(double top, double left, double bottom, double right) { + layout.margins(top, left, bottom, right); + return this; + } + + private IRowCreator newRow() { + // System.out.println("ChoicePanelBuilder.newRow() level: "+level+", groups: "+groups.size() + // ); + if (level == 0) + return layout.row(); + else if (level == 1) + return layout.row().group(groups.get(0).group); + else if (level == 2) + return layout.row().group(groups.get(0).group).group(groups.get(1).group); + else if (level == 3) + return layout.row().group(groups.get(0).group).group(groups.get(1).group).group(groups.get(2).group); + else if (level == 4) + return layout.row().group(groups.get(0).group).group(groups.get(1).group).group(groups.get(2).group).group(groups.get(3).group); + else if (level == 5) + return layout.row().group(groups.get(0).group).group(groups.get(1).group).group(groups.get(2).group).group(groups.get(3).group).group(groups.get(4).group); + else + throw new IllegalStateException("Level > 5"); + } + + private ISpannableGridRow newGridRow() { + return newRow().grid().indent(indent); + } + + private ISpannableGridRow newGridRow(String string, String tooltip) { + JLabel l = label(string); + l.setToolTipText(TooltipUtils.format(tooltip)); + return newRow().grid(l).indent(indent); + } + + private ISpannableGridRow newGridRow(JLabel label, String tooltip) { + label.setToolTipText(tooltip); + return newRow().grid(label).indent(indent); + } + + private INonGridRow newLeftRow() { + return newRow().left().indent(indent); + } + + public void addSeparator(JComponent c) { + newLeftRow().add(c).fill(); + } + + public void addSeparator(String string) { + addSeparator(boldlabel(string)); + } + + public void addButtons(JComponent... components) { + addLeft(components); + } + + public void addLeft(JComponent... components) { + newRow().bar().left(components); + } + + public void addRight(JComponent... components) { + newRow().bar().right(components); + } + + public void addCenter(JComponent... components) { + newRow().center().add(components); + } + + public void addFill(JComponent... components) { + newRow().center().add(components).fill(); + } + + public void addComponentToGroup(RowGroup group, JComponent c) { + layout.row().group(group).grid().add(c); + } + + public void addComponentToGroup(RowGroup group, String s, JComponent c) { + layout.row().group(group).grid(new JLabel(s)).add(c); + } + + public JComponent addComponent(JComponent c) { + newGridRow().add(c); + return c; + } + + public JComponent addComponent(JLabel label, JComponent c) { + newGridRow(label, null).add(c); + c.setName(prefix + label.getName()); + return c; + } + + public JComponent addComponent(String label, JComponent c) { + newGridRow(label, null).add(c); + c.setName(prefix + label); + return c; + } + + public JComponent addComponent(String label, JComponent c, String tooltip) { + newGridRow(label, tooltip).add(c); + c.setName(prefix + label); + c.setToolTipText(TooltipUtils.format(tooltip)); + return c; + } + + public JComponent addComponentAndSpan(String label, JComponent c) { + newGridRow(label, null).add(c).spanRow(); + c.setName(prefix + label); + return c; + } + + public JComponent addComponentAndSpan(String label, JComponent c, int span) { + newGridRow(label, null).add(c,span).spanRow(); + c.setName(prefix + label); + return c; + } + + public JComponent addSubComponent(String label, JComponent c) { + newGridRow().grid(label(label)).add(c); + return c; + } + + public JComponent[] addComponent(JComponent... c) { + newGridRow().add(c); + return c; + } + + public JComponent[] addComponent(int spanRows, JComponent... c) { + newGridRow().addMulti(spanRows, c); + return c; + } + + public JComponent[] addComponent(String label, JComponent... c) { + newGridRow(label, null).add(c); + setNames(label, c); + return c; + } + + public JComponent[] addComponent(JLabel label, JComponent... c) { + newGridRow(label, null).add(c); + setNames(prefix + label.getName()); + return c; + } + + public JComponent[] addComponent(String label, int spanCol, JComponent spanComponent, JComponent... c) { + newGridRow(label, null).add(spanComponent, 3).add(c); + setNames(label, c); + return c; + } + + public JComponent[] addComponentAndSpan(String label, JComponent... c) { + newGridRow(label, null).add(c).spanRow(); + setNames(label, c); + return c; + } + + public void addComponent(List> comps) { + ISpannableGridRow row = newGridRow(); + for (List list : comps) { + if (list.size() == 1) { + row.add(list.get(0)); + } else if (list.size() > 1) { + row.addMulti(list.toArray(new JComponent[0])); + } + } + row.spanRow(); + } + + public void addSpanRow() { + newGridRow().spanRow(); + } + + private void setNames(String label, JComponent... c) { + if (c.length == 1) { + c[0].setName(prefix + label); + } else { + for (int i = 0; i < c.length; i++) { + c[i].setName(prefix + label + "." + i); + } + } + } + + public JPanel addComponentsAsOne(String label, JComponent... c) { + PanelBuilder pb = new PanelBuilder(); + pb.addComponent(c); + setNames(label, c); + JPanel panel = pb.removeMargins().getPanel(); + addComponent(label, panel); + return panel; + } + + public void indent() { + indent++; + } + + public void outdent() { + indent--; + } + + public void clear() { + getPanel().setLayout(null); + getPanel().removeAll(); + this.layout = new DesignGridLayout(parent); + layout.withoutConsistentWidthAcrossNonGridRows(); + layout.emptyRow(); + } + + public GroupController startChoice(String choiceName, GroupController groupController) { + + ShowHideAction action = new ShowHideAction(); + + actions.push(action); + controllers.push(groupController); + + addComponent(choiceName, controllers.peek().getComponent()); + + level++; + + return groupController; + } + + public GroupController startChoice(String choiceName) { + return startChoice(choiceName, (String) null); + } + + public GroupController startChoice(String choiceName, String tooltip) { + ShowHideAction action = new ShowHideAction(); + + GroupController comboBox = comboBox(); + + actions.push(action); + controllers.push(comboBox); + + addComponent(choiceName, controllers.peek().getComponent()); + + level++; + + ((JComboBoxController) comboBox).setToolTipText(TooltipUtils.format(tooltip)); + + return comboBox; + } + + public void endChoice() { + level--; + GroupController combo = controllers.pop(); + combo.addActionListener(actions.pop()); + combo.setSelectedIndex(0); + } + + public void startHidable(String key) { + ShowHideAction action = new ShowHideAction(); + + GroupController hider = hider(); + hideables.put(key, (HideController) hider); + actions.push(action); + controllers.push(hider); + + level++; + } + + public void endHidable() { + level--; + // indent--; + GroupController check = controllers.pop(); + check.addActionListener(actions.pop()); + check.setSelectedIndex(0); + } + + public void setShowing(String hideable, String group) { + // ci sono casi in cui non ci sono delle chiavi ad es turbulence + // openings non ha timevarying + if (hideables.containsKey(hideable)) { + hideables.get(hideable).setSelectedItem(group); + } + } + + public GroupController startCheck(String checkName) { + return startCheck(checkName, (String) null); + } + + public GroupController startCheck(String checkName, String tooltip) { + ShowHideAction action = new ShowHideAction(); + + GroupController checkBox = checkBox(checkName); + + actions.push(action); + controllers.push(checkBox); + + addSeparator(controllers.peek().getComponent()); + + level++; + indent(); + startGroup(checkName); + + ((JCheckBoxController) checkBox).setToolTipText(TooltipUtils.format(tooltip)); + + return checkBox; + } + + public GroupController startCheck(String checkName, JCheckBoxController checkBox) { + return startCheck(checkName, checkBox, null); + } + + public GroupController startCheck(String checkName, JCheckBoxController checkBox, String tooltip) { + ShowHideAction action = new ShowHideAction(); + + actions.push(action); + controllers.push(checkBox); + + addSeparator(controllers.peek().getComponent()); + + level++; + indent(); + startGroup(checkName); + + checkBox.setToolTipText(TooltipUtils.format(tooltip)); + + return checkBox; + } + + public void endCheck() { + endCheck(true); + } + + public void endCheck(boolean enable) { + endGroup(); + level--; + outdent(); + GroupController check = controllers.pop(); + check.addActionListener(actions.pop()); + check.setSelectedIndex(0); + if (enable) + return; // questo significa che se voglio inizialmente deselezionato + // devo fare click due volte + check.setSelectedIndex(0); + } + + public RowGroup startGroup(String groupName) { + return startGroup(groupName, groupName); + } + + public RowGroup startGroup(String groupKey, String groupName) { + RowGroup group = new RowGroup(); + actions.peek().addItem(groupKey, group); // prima questo altrimenti + // scassa + controllers.peek().addGroup(groupKey, groupName); + groups.push(new KeydRowGroup(groupKey, group)); + + return group; + } + + public void endGroup() { + groups.pop().group.hide(); + } + + protected void checkForParent() { + GroupController controller = controllers.pop(); + if (!controllers.isEmpty()) { // sto mettendo un choice dentro un choice + GroupController parentController = controllers.pop(); + parentController.addChildController(controller); + + if (!controllers.isEmpty()) { // sto mettendo un choice dentro un choice dentro un choice + GroupController grandParentController = controllers.peek(); + grandParentController.addChildController(parentController); + } else { + + } + controllers.push(parentController); + } else { + } + controllers.push(controller); + } + + public void setEnabled(boolean enabled) { + if (enabled) + UiUtil.enable(parent); + else + UiUtil.disable(parent); + } + + private JLabel label(String string) { + return new JLabel(string); + } + + private JLabel boldlabel(String string) { + JLabel boldlabel = label(string); + boldlabel.setFont(boldlabel.getFont().deriveFont(Font.BOLD)); + return boldlabel; + } + + // private JLabel bluelabel(String string) { + // JLabel bluelabel = label(string); + // bluelabel.setForeground(Color.BLUE); + // return bluelabel; + // } + + private GroupController checkBox(String name) { + return new JCheckBoxController(name); + } + + private GroupController comboBox() { + return new JComboBoxController(); + } + + private GroupController hider() { + return new HideController(); + } + + class ShowHideAction implements ActionListener { + Map groups = new HashMap(); + String previousKey = null; + + public void addItem(String groupKey, RowGroup group) { + groups.put(groupKey, group); + } + + @Override + public void actionPerformed(ActionEvent e) { + Object source = e.getSource(); + if (source instanceof GroupController) { + GroupController controller = (GroupController) e.getSource(); + String selectedKey = controller.getSelectedKey(); + handleSelection(selectedKey); + GroupController childController = controller.getChildController(selectedKey); + if (childController != null) { + String childSelectedKey = childController.getSelectedKey(); + childController.setSelectedKey(childSelectedKey); + // GroupController grandChildController = childController.getChildController(childSelectedKey); + // if (grandChildController != null) { + // String grandChildSelectedKey = childController.getSelectedKey(); + // grandChildController.setSelectedKey(grandChildSelectedKey); + // } + } + } else { + if (previousKey != null) { + groups.get(previousKey).hide(); + previousKey = null; + } else { + String selectedKey = groups.keySet().iterator().next(); + groups.get(selectedKey).show(); + previousKey = selectedKey; + } + } + } + + private void handleSelection(String selectedKey) { + beforeSelection(selectedKey); + if (previousKey != null) + groups.get(previousKey).hide(); + if (selectedKey != null) + groups.get(selectedKey).show(); + + previousKey = selectedKey; + afterSelection(selectedKey); + } + } + + protected void beforeSelection(String selectedKey) { + + } + + protected void afterSelection(String selectedKey) { + + } + + protected class KeydRowGroup { + public String groupKey; + public RowGroup group; + + public KeydRowGroup(String groupKey, RowGroup group) { + this.group = group; + this.groupKey = groupKey; + } + } + + /* set a prefix for naming component */ + public void prefix(String name) { + this.prefix = name; + } +} diff --git a/src/eu/engys/util/ui/checkboxtree/AddCheckBoxToTree.java b/src/eu/engys/util/ui/checkboxtree/AddCheckBoxToTree.java new file mode 100644 index 0000000..3d2d757 --- /dev/null +++ b/src/eu/engys/util/ui/checkboxtree/AddCheckBoxToTree.java @@ -0,0 +1,646 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui.checkboxtree; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.PointerInfo; +import java.awt.event.MouseAdapter; +import java.beans.Transient; +import java.util.ArrayList; +import java.util.Stack; + +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; + +import eu.engys.util.ui.checkboxtree.TristateCheckBox.State; +import eu.engys.util.ui.treetable.tree.TreeTableTreeModel; + +public class AddCheckBoxToTree { + + public interface CheckBoxSelectionListener { + void selectionAdded(DefaultMutableTreeNode userObject); + + void selectionRemoved(DefaultMutableTreeNode userObject); + } + + public static CheckTreeManager toTree(JTree tree) { + return new CheckTreeManager(tree); + } + + public static class CheckTreeManager extends MouseAdapter { + + private final CheckTreeSelectionModel checkSelectionModel; + private final CheckTreeCellRenderer checkCellRenderer; + private final SelectionModelProxy selectionModel; + private final JTree tree; + + public CheckTreeManager(final JTree tree) { + this.tree = tree; + this.checkSelectionModel = new CheckTreeSelectionModel(tree.getModel()); + this.checkCellRenderer = new CheckTreeCellRenderer(tree.getCellRenderer(), checkSelectionModel); + this.selectionModel = new SelectionModelProxy(tree, checkSelectionModel); + + tree.setCellRenderer(checkCellRenderer); + tree.setSelectionModel(selectionModel); + + tree.getModel().addTreeModelListener(new CheckTreeModelListener(selectionModel)); + } + + public CheckTreeManager withListener(CheckBoxSelectionListener l) { + checkSelectionModel.setListener(l); + return this; + } + + public void selectNode(DefaultMutableTreeNode node) { + CheckBoxSelectionListener listener = checkSelectionModel.removeListener(); + if (tree.getModel() instanceof DefaultTreeModel) { + DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel(); + checkSelectionModel.addSelectionPath(new TreePath(treeModel.getPathToRoot(node))); + } else if (tree.getModel() instanceof TreeTableTreeModel) { + TreeTableTreeModel treeModel = (TreeTableTreeModel) tree.getModel(); + checkSelectionModel.addSelectionPath(new TreePath(treeModel.getPathToRoot(node))); + } + checkSelectionModel.setListener(listener); + } + + public void deselectNode(DefaultMutableTreeNode node) { + CheckBoxSelectionListener listener = checkSelectionModel.removeListener(); + if (tree.getModel() instanceof DefaultTreeModel) { + DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel(); + checkSelectionModel.removeSelectionPath(new TreePath(treeModel.getPathToRoot(node))); + } else if (tree.getModel() instanceof TreeTableTreeModel) { + TreeTableTreeModel treeModel = (TreeTableTreeModel) tree.getModel(); + checkSelectionModel.removeSelectionPath(new TreePath(treeModel.getPathToRoot(node))); + } + checkSelectionModel.setListener(listener); + } + + public void clearSelection() { + checkSelectionModel.clearSelection(); + } + } + + private static class CheckTreeModelListener implements TreeModelListener { + + private SelectionModelProxy selectionModel; + + public CheckTreeModelListener(SelectionModelProxy selectionModel) { + this.selectionModel = selectionModel; + } + + @Override + public void treeNodesChanged(TreeModelEvent e) { + } + + @Override + public void treeNodesInserted(TreeModelEvent e) { + } + + @Override + public void treeNodesRemoved(TreeModelEvent e) { + } + + @Override + public void treeStructureChanged(TreeModelEvent e) { + // System.out.println("AddCheckBoxToTree.CheckTreeModelListener.treeStructureChanged()"); + selectionModel.adjustSelection((DefaultMutableTreeNode) new TreePath(e.getPath()).getLastPathComponent()); + } + + } + + private static class SelectionModelProxy extends DefaultTreeSelectionModel { + private final int hotspot = new JCheckBox().getPreferredSize().width; + private final TreeSelectionModel delegate; + private final JTree tree; + private final CheckTreeSelectionModel checkSelectionModel; + + private SelectionModelProxy(JTree tree, CheckTreeSelectionModel checkSelectionModel) { + this.tree = tree; + this.checkSelectionModel = checkSelectionModel; + this.delegate = tree.getSelectionModel(); + } + + public void adjustSelection(DefaultMutableTreeNode node) { + if (node.isLeaf()) { + if (checkBoxIsVisible(node) && nodeToVisibleItm(node).isVisible()) { + // System.out.println("AddCheckBoxToTree.SelectionModelProxy.adjustSelection() -> "+nodeToVisibleItm(node)); + if (tree.getModel() instanceof DefaultTreeModel) { + checkSelectionModel.addSelectionPath(new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(node))); + } else { + + } + } + } else { + for (int i = 0; i < node.getChildCount(); i++) { + DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i); + adjustSelection(child); + } + } + } + + @Override + public void addSelectionPaths(TreePath[] paths) { + // System.out.println("AddCheckBoxToTree.SelectionModelProxy.addSelectionPaths()"); + Point mousePosition = tree.getMousePosition(); + if (mousePosition != null && paths != null && paths.length > 0) { + if (checkBoxIsVisible(paths[0]) && clickIsInsideCheckBox(mousePosition.x, paths[0])) { + if (isAMultipleSelection(paths[0])) { + setCheckSelectionPaths(paths[0], delegate.getSelectionPaths()); + } else { + setCheckSelectionPath(paths[0]); + } + } else { + delegate.addSelectionPaths(paths); + super.addSelectionPaths(delegate.getSelectionPaths()); + } + } else { + delegate.addSelectionPaths(paths); + super.addSelectionPaths(delegate.getSelectionPaths()); + } + } + + private boolean checkBoxIsVisible(TreePath path) { + return checkBoxIsVisible((DefaultMutableTreeNode) path.getLastPathComponent()); + } + + private boolean checkBoxIsVisible(DefaultMutableTreeNode node) { + return node.getUserObject() instanceof VisibleItem; + } + + private VisibleItem nodeToVisibleItm(DefaultMutableTreeNode node) { + return (VisibleItem) node.getUserObject(); + } + + @Override + public void setSelectionPaths(TreePath[] paths) { + Point mousePosition = getMousePosition(); + if (paths != null && paths.length > 0) { + if (mousePosition != null && checkBoxIsVisible(paths[0]) && clickIsInsideCheckBox(mousePosition.x, paths[0])) { + if (isAMultipleSelection(paths[0])) { + setCheckSelectionPaths(paths[0], delegate.getSelectionPaths()); + } else { + setCheckSelectionPath(paths[0]); + } + } else { + delegate.setSelectionPaths(paths); + super.setSelectionPaths(delegate.getSelectionPaths()); + } + } + } + + private Point getMousePosition() { + Point mousePosition = tree.getMousePosition(); + if (tree.getParent() != null && mousePosition != null) { + return mousePosition; + } else { + PointerInfo pointerInfo = MouseInfo.getPointerInfo(); + Point point = new Point(pointerInfo.getLocation()); + SwingUtilities.convertPointFromScreen(point, tree); + return point; + } + } + + private boolean isAMultipleSelection(TreePath treePath) { + TreePath[] selectionPaths = delegate.getSelectionPaths(); + if (selectionPaths != null && selectionPaths.length > 1) { + for (TreePath tp : selectionPaths) { + if (tp.equals(treePath)) + return true; + } + } + return false; + } + + public boolean clickIsInsideCheckBox(int x, TreePath path) { + return x < tree.getPathBounds(path).x + hotspot; + } + + public void setCheckSelectionPath(TreePath path) { + // System.out.println("AddCheckBoxToTree.SelectionModelProxy.setCheckSelectionPath() >>>>>>>>>>>>> "); + if (path == null) { + return; + } + + boolean selected = checkSelectionModel.isPathSelected(path, true); + + try { + if (selected) { + checkSelectionModel.removeSelectionPath(path); + } else { + checkSelectionModel.addSelectionPath(path); + } + } finally { + tree.treeDidChange(); + tree.getParent().revalidate(); + tree.getParent().repaint(); + } + } + + public void setCheckSelectionPaths(TreePath path, TreePath[] paths) { + if (paths == null || path == null) { + return; + } + + boolean selected = checkSelectionModel.isPathSelected(path, true); + + try { + if (selected) { + checkSelectionModel.removeSelectionPath(path); + for (TreePath treePath : paths) { + checkSelectionModel.removeSelectionPath(treePath); + } + } else { + checkSelectionModel.addSelectionPath(path); + for (TreePath treePath : paths) { + checkSelectionModel.addSelectionPath(treePath); + } + } + } finally { + tree.treeDidChange(); + } + } + } + + public static class CheckTreeSelectionModel extends DefaultTreeSelectionModel { + static final long serialVersionUID = 0; + private TreeModel model; + private CheckBoxSelectionListener listener; + + public CheckTreeSelectionModel(TreeModel model) { + this.model = model; + setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); + } + + public CheckBoxSelectionListener removeListener() { + CheckBoxSelectionListener l = this.listener; + this.listener = null; + return l; + } + + public void setListener(CheckBoxSelectionListener l) { + this.listener = l; + } + + @Override + public void addSelectionPath(TreePath path) { + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.addSelectionPath() "+path); + super.addSelectionPath(path); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); + if (listener != null) + listener.selectionAdded(node); + } + + @Override + public void removeSelectionPath(TreePath path) { + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.removeSelectionPath() "+path); + super.removeSelectionPath(path); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); + if (listener != null) + listener.selectionRemoved(node); + } + + // tests whether there is any unselected node in the subtree of given path (DONT_CARE) + public boolean isPartiallySelected(TreePath path) { + if (isPathSelected(path, true)) { + return false; + } + + TreePath[] selectionPaths = getSelectionPaths(); + + if (selectionPaths == null) { + return false; + } + + for (int j = 0; j < selectionPaths.length; j++) { + if (isDescendant(selectionPaths[j], path)) { + return true; + } + } + + return false; + } + + // tells whether given path is selected. + // if dig is true, then a path is assumed to be selected, if + // one of its ancestor is selected. + public boolean isPathSelected(TreePath path, boolean dig) { + if (!dig) { + return super.isPathSelected(path); + } + + while (path != null && !super.isPathSelected(path)) { + path = path.getParentPath(); + } + + return path != null; + } + + // is path1 descendant of path2 + private boolean isDescendant(TreePath path1, TreePath path2) { + return path1 != path2 && path2.isDescendant(path1); + } + + public void setSelectionPaths(TreePath[] pPaths) { + throw new UnsupportedOperationException("not implemented yet!!!"); + } + + public void addSelectionPaths(TreePath[] paths) { + + // unselect all descendants of paths[] + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + + TreePath[] selectionPaths = getSelectionPaths(); + + if (selectionPaths == null) { + break; + } + + ArrayList toBeRemoved = new ArrayList(); + + for (int j = 0; j < selectionPaths.length; j++) { + if (isDescendant(selectionPaths[j], path)) { + toBeRemoved.add(selectionPaths[j]); + } + } + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.addSelectionPaths() -> removeSelectionPaths "+toBeRemoved); + super.removeSelectionPaths((TreePath[]) toBeRemoved.toArray(new TreePath[0])); + } + + // if all siblings are selected then unselect them and select parent + // recursively + // otherwise just select that path. + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + + TreePath temp = null; + + while (areSiblingsSelected(path)) { + temp = path; + + if (path.getParentPath() == null) { + break; + } + + path = path.getParentPath(); + } + + if (temp != null) { + if (temp.getParentPath() != null) { + addSelectionPath(temp.getParentPath()); + } else { + if (!isSelectionEmpty()) { + removeSelectionPaths(getSelectionPaths()); + } + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.addSelectionPaths() -> addSelectionPaths temp: "+temp); + super.addSelectionPaths(new TreePath[] { temp }); + } + } else { + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.addSelectionPaths() -> addSelectionPaths path: "+path); + super.addSelectionPaths(new TreePath[] { path }); + } + } + } + + // tells whether all siblings of given path are selected. + private boolean areSiblingsSelected(TreePath path) { + TreePath parent = path.getParentPath(); + + if (parent == null) { + return true; + } + + Object node = path.getLastPathComponent(); + + Object parentNode = parent.getLastPathComponent(); + + int childCount = model.getChildCount(parentNode); + + for (int i = 0; i < childCount; i++) { + + Object childNode = model.getChild(parentNode, i); + + if (childNode == node) { + continue; + } + + if (!isPathSelected(parent.pathByAddingChild(childNode))) { + return false; + } + } + + return true; + } + + public void removeSelectionPaths(TreePath[] paths) { + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + if (path.getPathCount() == 1) { + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.removeSelectionPaths() -> removeSelectionPaths "+path); + super.removeSelectionPaths(new TreePath[] { path }); + } else { + toggleRemoveSelection(path); + } + } + } + + /** + * if any ancestor node of given path is selected then unselect it and selection all its descendants except given path and descendants. otherwise just unselect the given path + */ + private void toggleRemoveSelection(TreePath path) { + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.toggleRemoveSelection() path: " + path); + Stack stack = new Stack(); + TreePath parent = path.getParentPath(); + + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.toggleRemoveSelection() parent: " + parent); + + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.toggleRemoveSelection() is parent selected: " + isPathSelected(parent)); + while (parent != null && !isPathSelected(parent)) { + stack.push(parent); + parent = parent.getParentPath(); + } + if (parent != null) + stack.push(parent); + else { + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.toggleRemoveSelection() -> removeSelectionPaths path: "+path); + super.removeSelectionPaths(new TreePath[] { path }); + return; + } + + while (!stack.isEmpty()) { + TreePath temp = (TreePath) stack.pop(); + + TreePath peekPath = stack.isEmpty() ? path : (TreePath) stack.peek(); + + Object node = temp.getLastPathComponent(); + Object peekNode = peekPath.getLastPathComponent(); + int childCount = model.getChildCount(node); + + for (int i = 0; i < childCount; i++) { + Object childNode = model.getChild(node, i); + + if (childNode != peekNode) { + TreePath pathByAddingChild = temp.pathByAddingChild(childNode); + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.toggleRemoveSelection() -> addSelectionPAth pathByAddingChild: "+pathByAddingChild); + super.addSelectionPaths(new TreePath[] { pathByAddingChild }); + } + } + } + + // System.out.println("AddCheckBoxToTree.CheckTreeSelectionModel.toggleRemoveSelection() -> removeSelectionPaths parent: "+parent); + super.removeSelectionPaths(new TreePath[] { parent }); + } + + public TreeModel getModel() { + return model; + } + } + + public static class CheckTreeCellRenderer extends JPanel implements TreeCellRenderer { + + static final long serialVersionUID = 0; + + CheckTreeSelectionModel selectionModel; + private TreeCellRenderer delegate; + private TristateCheckBox checkBox; + private JCheckBox fakeBox; + + public CheckTreeCellRenderer(TreeCellRenderer delegate, CheckTreeSelectionModel selectionModel) { + this.delegate = delegate; + this.selectionModel = selectionModel; + + setLayout(new BorderLayout()); + setOpaque(false); + + checkBox = new TristateCheckBox(); + checkBox.setOpaque(false); + + fakeBox = new JCheckBox() { + protected void paintComponent(java.awt.Graphics g) { + }; + }; + fakeBox.setOpaque(false); + } + + public void setBackgroundSelectionColor(Color c) { + if (delegate instanceof DefaultTreeCellRenderer) { + ((DefaultTreeCellRenderer) delegate).setBackgroundSelectionColor(c); + } + } + + public void setBackgroundNonSelectionColor(Color c) { + if (delegate instanceof DefaultTreeCellRenderer) { + ((DefaultTreeCellRenderer) delegate).setBackgroundNonSelectionColor(c); + } + } + + public void setTextSelectionColor(Color c) { + if (delegate instanceof DefaultTreeCellRenderer) { + ((DefaultTreeCellRenderer) delegate).setTextSelectionColor(c); + } + } + + public void setTextNonSelectionColor(Color c) { + if (delegate instanceof DefaultTreeCellRenderer) { + ((DefaultTreeCellRenderer) delegate).setTextNonSelectionColor(c); + } + } + + @Override + @Transient + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.width = d.width + 20; + return d; + } + + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + Component renderer = delegate.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + + TreePath path = tree.getPathForRow(row); + + if (path != null) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); + // int level = node.getLevel(); + + if (node.getLevel() == 1) { + setFont(tree.getFont().deriveFont(Font.BOLD)); + } else { + setFont(tree.getFont().deriveFont(Font.PLAIN)); + } + + if (node.isRoot() || !(node.getUserObject() instanceof VisibleItem)) { + removeAll(); + add(renderer, BorderLayout.CENTER); + return this; + } + + if ((node.getUserObject() instanceof LoadableItem && !((LoadableItem) node.getUserObject()).isLoaded())) { + removeAll(); + add(renderer, BorderLayout.CENTER); + return this; + } + + if (selectionModel.isPathSelected(path, true)) { + checkBox.setState(State.SELECTED); + // System.out.println(">>>>>> selected: " + path); + } else { + checkBox.setState(State.NOT_SELECTED); + // System.out.println(">>>>>> not selected: " + path); + } + + if (selectionModel.isPartiallySelected(path)) { + checkBox.setState(State.DONT_CARE); + } + } + + removeAll(); + + add(checkBox, BorderLayout.WEST); + add(renderer, BorderLayout.CENTER); + + return this; + } + } +} diff --git a/src/eu/engys/util/ui/checkboxtree/FileTreeViewer.java b/src/eu/engys/util/ui/checkboxtree/FileTreeViewer.java new file mode 100644 index 0000000..4c1192f --- /dev/null +++ b/src/eu/engys/util/ui/checkboxtree/FileTreeViewer.java @@ -0,0 +1,366 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.checkboxtree; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.io.File; +import java.util.Vector; + +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.ToolTipManager; +import javax.swing.UIManager; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; + +import eu.engys.util.ui.UiUtil; + +public class FileTreeViewer extends JFrame { + + private static final long serialVersionUID = 1L; + public static final ImageIcon ICON_COMPUTER = new ImageIcon(""); + public static final ImageIcon ICON_DISK = new ImageIcon("defaults1.png"); + public static final ImageIcon ICON_FOLDER = new ImageIcon("fol_orig.png"); + public static final ImageIcon ICON_EXPANDEDFOLDER = new ImageIcon("folder_open.png"); + + protected JTree m_tree; + protected DefaultTreeModel m_model; + + protected TreePath m_clickedPath; + + public FileTreeViewer() { + super("Demo tree check box"); + setSize(400, 300); + + DefaultMutableTreeNode top = new DefaultMutableTreeNode(new IconData(ICON_COMPUTER, null, "Computer")); + + DefaultMutableTreeNode node; + File[] roots = File.listRoots(); + for (int k = 0; k < roots.length; k++) { + node = new DefaultMutableTreeNode(new IconData(ICON_DISK, null, new FileNode(roots[k]))); + top.add(node); + node.add(new DefaultMutableTreeNode(new Boolean(true))); + } + + m_model = new DefaultTreeModel(top); + + m_tree = new JTree(m_model) { + public String getToolTipText(MouseEvent ev) { + if (ev == null) + return null; + TreePath path = m_tree.getPathForLocation(ev.getX(), ev.getY()); + if (path != null) { + FileNode fnode = getFileNode(getTreeNode(path)); + if (fnode == null) + return null; + File f = fnode.getFile(); + return (f == null ? null : f.getPath()); + } + return null; + } + }; + + ToolTipManager.sharedInstance().registerComponent(m_tree); + + m_tree.putClientProperty("JTree.lineStyle", "Angled"); + + TreeCellRenderer renderer = new IconCellRenderer(); + m_tree.setCellRenderer(renderer); + + m_tree.addTreeExpansionListener(new DirExpansionListener()); + + m_tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + m_tree.setShowsRootHandles(true); + m_tree.setEditable(false); + + AddCheckBoxToTree.toTree(m_tree); + + JScrollPane s = new JScrollPane(); + s.getViewport().add(m_tree); + getContentPane().add(s, BorderLayout.CENTER); + + WindowListener wndCloser = new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }; + + addWindowListener(wndCloser); + + setVisible(true); + } + + DefaultMutableTreeNode getTreeNode(TreePath path) { + return (DefaultMutableTreeNode) (path.getLastPathComponent()); + } + + FileNode getFileNode(DefaultMutableTreeNode node) { + if (node == null) + return null; + Object obj = node.getUserObject(); + if (obj instanceof IconData) + obj = ((IconData) obj).getObject(); + if (obj instanceof FileNode) + return (FileNode) obj; + else + return null; + } + + // Make sure expansion is threaded and updating the tree model + // only occurs within the event dispatching thread. + class DirExpansionListener implements TreeExpansionListener { + public void treeExpanded(TreeExpansionEvent event) { + final DefaultMutableTreeNode node = getTreeNode(event.getPath()); + final FileNode fnode = getFileNode(node); + + Thread runner = new Thread() { + public void run() { + if (fnode != null && fnode.expand(node)) { + Runnable runnable = new Runnable() { + public void run() { + m_model.reload(node); + } + }; + SwingUtilities.invokeLater(runnable); + } + } + }; + runner.start(); + } + + public void treeCollapsed(TreeExpansionEvent event) { + } + } + +} + +class IconCellRenderer extends JLabel implements TreeCellRenderer { + protected Color m_textSelectionColor; + protected Color m_textNonSelectionColor; + protected Color m_bkSelectionColor; + protected Color m_bkNonSelectionColor; + protected Color m_borderSelectionColor; + + protected boolean m_selected; + + public IconCellRenderer() { + super(); + m_textSelectionColor = UIManager.getColor("Tree.selectionForeground"); + m_textNonSelectionColor = UIManager.getColor("Tree.textForeground"); + m_bkSelectionColor = UIManager.getColor("Tree.selectionBackground"); + m_bkNonSelectionColor = UIManager.getColor("Tree.textBackground"); + m_borderSelectionColor = UIManager.getColor("Tree.selectionBorderColor"); + setOpaque(false); + } + + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) + + { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object obj = node.getUserObject(); + setText(obj.toString()); + + if (obj instanceof Boolean) + setText("Retrieving data..."); + + if (obj instanceof IconData) { + IconData idata = (IconData) obj; + if (expanded) + setIcon(idata.getExpandedIcon()); + else + setIcon(idata.getIcon()); + } else + setIcon(null); + + setFont(tree.getFont()); + setForeground(sel ? m_textSelectionColor : m_textNonSelectionColor); + setBackground(sel ? m_bkSelectionColor : m_bkNonSelectionColor); + m_selected = sel; + return this; + } + + public void paintComponent(Graphics g) { + Color bColor = getBackground(); + Icon icon = getIcon(); + + g.setColor(bColor); + int offset = 0; + if (icon != null && getText() != null) + offset = (icon.getIconWidth() + getIconTextGap()); + g.fillRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1); + + if (m_selected) { + g.setColor(m_borderSelectionColor); + g.drawRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1); + } + + super.paintComponent(g); + } +} + +class IconData { + protected Icon m_icon; + protected Icon m_expandedIcon; + protected Object m_data; + + public IconData(Icon icon, Object data) { + m_icon = icon; + m_expandedIcon = null; + m_data = data; + } + + public IconData(Icon icon, Icon expandedIcon, Object data) { + m_icon = icon; + m_expandedIcon = expandedIcon; + m_data = data; + } + + public Icon getIcon() { + return m_icon; + } + + public Icon getExpandedIcon() { + return m_expandedIcon != null ? m_expandedIcon : m_icon; + } + + public Object getObject() { + return m_data; + } + + public String toString() { + return m_data.toString(); + } +} + +class FileNode { + protected File m_file; + + public FileNode(File file) { + m_file = file; + } + + public File getFile() { + return m_file; + } + + public String toString() { + return m_file.getName().length() > 0 ? m_file.getName() : m_file.getPath(); + } + + public boolean expand(DefaultMutableTreeNode parent) { + DefaultMutableTreeNode flag = (DefaultMutableTreeNode) parent.getFirstChild(); + if (flag == null) // No flag + return false; + Object obj = flag.getUserObject(); + if (!(obj instanceof Boolean)) + return false; // Already expanded + + parent.removeAllChildren(); // Remove Flag + + File[] files = listFiles(); + if (files == null) + return true; + + Vector v = new Vector(); + + for (int k = 0; k < files.length; k++) { + File f = files[k]; + if (!(f.isDirectory())) + continue; + + FileNode newNode = new FileNode(f); + + boolean isAdded = false; + for (int i = 0; i < v.size(); i++) { + FileNode nd = (FileNode) v.elementAt(i); + if (newNode.compareTo(nd) < 0) { + v.insertElementAt(newNode, i); + isAdded = true; + break; + } + } + if (!isAdded) + v.addElement(newNode); + } + + for (int i = 0; i < v.size(); i++) { + FileNode nd = (FileNode) v.elementAt(i); + IconData idata = new IconData(FileTreeViewer.ICON_FOLDER, FileTreeViewer.ICON_EXPANDEDFOLDER, nd); + DefaultMutableTreeNode node = new DefaultMutableTreeNode(idata); + parent.add(node); + + if (nd.hasSubDirs()) + node.add(new DefaultMutableTreeNode(new Boolean(true))); + } + + return true; + } + + public boolean hasSubDirs() { + File[] files = listFiles(); + if (files == null) + return false; + for (int k = 0; k < files.length; k++) { + if (files[k].isDirectory()) + return true; + } + return false; + } + + public int compareTo(FileNode toCompare) { + return m_file.getName().compareToIgnoreCase(toCompare.m_file.getName()); + } + + protected File[] listFiles() { + if (!m_file.isDirectory()) + return null; + try { + return m_file.listFiles(); + } catch (Exception ex) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Error reading directory " + m_file.getAbsolutePath(), "Warning", JOptionPane.WARNING_MESSAGE); + return null; + } + } +} diff --git a/src/eu/engys/util/ui/checkboxtree/LoadableItem.java b/src/eu/engys/util/ui/checkboxtree/LoadableItem.java new file mode 100644 index 0000000..6d2d88f --- /dev/null +++ b/src/eu/engys/util/ui/checkboxtree/LoadableItem.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.checkboxtree; + +public interface LoadableItem { + + void setVisible(boolean b); + boolean isVisible(); + String getName(); + boolean isLoaded(); + void setLoaded(boolean b); +} diff --git a/src/eu/engys/util/ui/checkboxtree/RootVisibleItem.java b/src/eu/engys/util/ui/checkboxtree/RootVisibleItem.java new file mode 100644 index 0000000..505f40f --- /dev/null +++ b/src/eu/engys/util/ui/checkboxtree/RootVisibleItem.java @@ -0,0 +1,58 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.checkboxtree; + +public class RootVisibleItem implements VisibleItem { + + private final String name; + private boolean visible; + + public RootVisibleItem(String name) { + this.name = name; + } + + @Override + public void setVisible(boolean b) { + this.visible = b; + } + + @Override + public boolean isVisible() { + return visible; + } + + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } + +} diff --git a/src/eu/engys/util/ui/checkboxtree/RootVisibleLoadableItem.java b/src/eu/engys/util/ui/checkboxtree/RootVisibleLoadableItem.java new file mode 100644 index 0000000..5e185fd --- /dev/null +++ b/src/eu/engys/util/ui/checkboxtree/RootVisibleLoadableItem.java @@ -0,0 +1,46 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.checkboxtree; + +public class RootVisibleLoadableItem extends RootVisibleItem implements LoadableItem { + + private boolean loaded; + + public RootVisibleLoadableItem(String name) { + super(name); + } + + @Override + public void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + @Override + public boolean isLoaded() { + return loaded; + } +} diff --git a/src/eu/engys/util/ui/checkboxtree/RootVisibleLoadableTreeNode.java b/src/eu/engys/util/ui/checkboxtree/RootVisibleLoadableTreeNode.java new file mode 100644 index 0000000..f902785 --- /dev/null +++ b/src/eu/engys/util/ui/checkboxtree/RootVisibleLoadableTreeNode.java @@ -0,0 +1,62 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.checkboxtree; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeNode; + +public class RootVisibleLoadableTreeNode extends DefaultMutableTreeNode { + + public RootVisibleLoadableTreeNode(String name) { + super(new RootVisibleLoadableItem(name)); + } + + private void checkForChanges() { + if (getChildCount() > 0) { + TreeNode child = getChildAt(0); + if (child instanceof DefaultMutableTreeNode) { + DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) child; + Object obj = dmtn.getUserObject(); + if (obj instanceof LoadableItem) { + LoadableItem li = (LoadableItem) obj; + getVisibleLoadableUserObject().setLoaded(li.isLoaded()); + } + } + } + } + + public RootVisibleLoadableItem getVisibleLoadableUserObject() { + return (RootVisibleLoadableItem) userObject; + } + + @Override + public Object getUserObject() { + checkForChanges(); + return super.getUserObject(); + } + +} diff --git a/src/eu/engys/util/ui/checkboxtree/TristateCheckBox.java b/src/eu/engys/util/ui/checkboxtree/TristateCheckBox.java new file mode 100644 index 0000000..db1197a --- /dev/null +++ b/src/eu/engys/util/ui/checkboxtree/TristateCheckBox.java @@ -0,0 +1,295 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.checkboxtree; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import javax.swing.AbstractAction; +import javax.swing.ActionMap; +import javax.swing.ButtonGroup; +import javax.swing.ButtonModel; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JCheckBox; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.ActionMapUIResource; + +public class TristateCheckBox extends JCheckBox { + static final long serialVersionUID = 0; + + private static final Icon EYE_ICON = new ImageIcon(TristateCheckBox.class.getClassLoader().getResource("eu/engys/resources/images/eye16.png")); + private static final Icon EYE_NO_ICON = new ImageIcon(TristateCheckBox.class.getClassLoader().getResource("eu/engys/resources/images/eye_no16.png")); + + public enum State { NOT_SELECTED, SELECTED, DONT_CARE }; + + private final TristateDecorator model; + + public TristateCheckBox(String text, Icon icon, State initial) { + super(text, icon); +// setIcon(EYE_NO_ICON); +// setSelectedIcon(EYE_ICON); +// setPressedIcon(EYE_ICON); +// setRolloverIcon(EYE_ICON); +// setRolloverSelectedIcon(EYE_NO_ICON); + + // Add a listener for when the mouse is pressed + super.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + grabFocus(); + model.nextState(); + } + }); + + // Reset the keyboard action map + ActionMap map = new ActionMapUIResource(); + map.put("pressed", new AbstractAction() { + + private static final long serialVersionUID = 1L; + + public void actionPerformed(ActionEvent e) { + grabFocus(); + model.nextState(); + } + }); + + map.put("released", null); + + SwingUtilities.replaceUIActionMap(this, map); + + // set the model to the adapted model + model = new TristateDecorator(getModel()); + setModel(model); + setState(initial); + } + + // Constractor types: + public TristateCheckBox(String text, State initial) { + this(text, null, initial); + } + + public TristateCheckBox(String text) { + this(text, State.DONT_CARE); + } + + public TristateCheckBox() { + this(null); + } + + /** No one may add mouse listeners, not even Swing! */ + public void addMouseListener(MouseListener l) { + } + + /** + * Set the new state to either SELECTED, NOT_SELECTED or DONT_CARE. If state + * == null, it is treated as DONT_CARE. + */ + public void setState(State state) { + model.setState(state); + } + + /** + * Return the current state, which is determined by the selection status of + * the model. + */ + public State getState() { + return model.getState(); + } + + public void setSelected(boolean b) { + if (b) { + setState(State.SELECTED); + } else { + setState(State.NOT_SELECTED); + } + } + + /** + * Exactly which Design Pattern is this? Is it an Adapter, a Proxy or a + * Decorator? In this case, my vote lies with the Decorator, because we are + * extending functionality and "decorating" the original model with a more + * powerful model. + */ + private class TristateDecorator implements ButtonModel { + private final ButtonModel other; + + private TristateDecorator(ButtonModel other) { + this.other = other; + } + + private void setState(State state) { + if (state == State.NOT_SELECTED) { + other.setArmed(false); + setPressed(false); + setSelected(false); + } else if (state == State.SELECTED) { + other.setArmed(false); + setPressed(false); + setSelected(true); + } else { // either "null" or DONT_CARE + other.setArmed(true); + setPressed(true); + setSelected(false); + } + } + + /** + * The current state is embedded in the selection / armed state of the + * model. + * + * We return the SELECTED state when the checkbox is selected but not + * armed, DONT_CARE state when the checkbox is selected and armed (grey) + * and NOT_SELECTED when the checkbox is deselected. + */ + private State getState() { + if (isSelected() && !isArmed()) { + // normal black tick + return State.SELECTED; + } else if (isSelected() && isArmed()) { + // don't care grey tick + return State.DONT_CARE; + } else { + // normal deselected + return State.NOT_SELECTED; + } + } + + /** We rotate between NOT_SELECTED, SELECTED and DONT_CARE. */ + private void nextState() { + State current = getState(); + if (current == State.NOT_SELECTED) { + setState(State.SELECTED); + } else if (current == State.SELECTED) { + setState(State.DONT_CARE); + } else if (current == State.DONT_CARE) { + setState(State.NOT_SELECTED); + } + } + + /** Filter: No one may change the armed status except us. */ + public void setArmed(boolean b) { + } + + /** + * We disable focusing on the component when it is not enabled. + */ + public void setEnabled(boolean b) { + setFocusable(b); + other.setEnabled(b); + } + + /** + * All these methods simply delegate to the "other" model that is being + * decorated. + */ + public boolean isArmed() { + return other.isArmed(); + } + + public boolean isSelected() { + return other.isSelected(); + } + + public boolean isEnabled() { + return other.isEnabled(); + } + + public boolean isPressed() { + return other.isPressed(); + } + + public boolean isRollover() { + return other.isRollover(); + } + + public int getMnemonic() { + return other.getMnemonic(); + } + + public String getActionCommand() { + return other.getActionCommand(); + } + + public Object[] getSelectedObjects() { + return other.getSelectedObjects(); + } + + public void setSelected(boolean b) { + other.setSelected(b); + } + + public void setPressed(boolean b) { + other.setPressed(b); + } + + public void setRollover(boolean b) { + other.setRollover(b); + } + + public void setMnemonic(int key) { + other.setMnemonic(key); + } + + public void setActionCommand(String s) { + other.setActionCommand(s); + } + + public void setGroup(ButtonGroup group) { + other.setGroup(group); + } + + public void addActionListener(ActionListener l) { + other.addActionListener(l); + } + + public void removeActionListener(ActionListener l) { + other.removeActionListener(l); + } + + public void addItemListener(ItemListener l) { + other.addItemListener(l); + } + + public void removeItemListener(ItemListener l) { + other.removeItemListener(l); + } + + public void addChangeListener(ChangeListener l) { + other.addChangeListener(l); + } + + public void removeChangeListener(ChangeListener l) { + other.removeChangeListener(l); + } + + } +} diff --git a/src/eu/engys/util/ui/checkboxtree/VisibleItem.java b/src/eu/engys/util/ui/checkboxtree/VisibleItem.java new file mode 100644 index 0000000..346de42 --- /dev/null +++ b/src/eu/engys/util/ui/checkboxtree/VisibleItem.java @@ -0,0 +1,35 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui.checkboxtree; + +public interface VisibleItem { + + void setVisible(boolean b); + + boolean isVisible(); + + String getName(); +} diff --git a/src/eu/engys/util/ui/groupcolumnheader/ColumnGroup.java b/src/eu/engys/util/ui/groupcolumnheader/ColumnGroup.java new file mode 100644 index 0000000..a593645 --- /dev/null +++ b/src/eu/engys/util/ui/groupcolumnheader/ColumnGroup.java @@ -0,0 +1,143 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.groupcolumnheader; + +import java.awt.Component; +import java.awt.Dimension; +import java.util.Iterator; +import java.util.Vector; + +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.UIManager; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; + +public class ColumnGroup { + + protected TableCellRenderer renderer; + protected Vector v; + protected String text; + protected int margin = 0; + + public ColumnGroup(String text) { + this(null, text); + } + + public ColumnGroup(TableCellRenderer renderer, String text) { + if (renderer == null) { + this.renderer = new DefaultTableCellRenderer() { + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JTableHeader header = table.getTableHeader(); + if (header != null) { + setForeground(header.getForeground()); + setBackground(header.getBackground()); + setFont(header.getFont()); + } + setHorizontalAlignment(JLabel.CENTER); + setText((value == null) ? "" : value.toString()); + setBorder(UIManager.getBorder("TableHeader.cellBorder")); + return this; + } + }; + } else { + this.renderer = renderer; + } + this.text = text; + v = new Vector<>(); + } + + public void add(Object obj) { + if (obj == null) { + return; + } + v.addElement(obj); + } + + @SuppressWarnings("unchecked") + public Vector getColumnGroups(TableColumn c, Vector g) { + g.addElement(this); + if (v.contains(c)) + return g; + Iterator iter = v.iterator(); + while (iter.hasNext()) { + Object obj = iter.next(); + if (obj instanceof ColumnGroup) { + Vector groups = (Vector) ((ColumnGroup) obj).getColumnGroups(c, (Vector) g.clone()); + if (groups != null) + return groups; + } + } + return null; + } + + public TableCellRenderer getHeaderRenderer() { + return renderer; + } + + public void setHeaderRenderer(TableCellRenderer renderer) { + if (renderer != null) { + this.renderer = renderer; + } + } + + public Object getHeaderValue() { + return text; + } + + public Dimension getSize(JTable table) { + Component comp = renderer.getTableCellRendererComponent(table, getHeaderValue(), false, false, -1, -1); + int height = comp.getPreferredSize().height; + int width = 0; + Iterator iter = v.iterator(); + while (iter.hasNext()) { + Object obj = iter.next(); + if (obj instanceof TableColumn) { + TableColumn aColumn = (TableColumn) obj; + width += aColumn.getWidth(); + } else { + width += ((ColumnGroup) obj).getSize(table).width; + } + } + return new Dimension(width, height); + } + + public void setColumnMargin(int margin) { + this.margin = margin; + Iterator iter = v.iterator(); + while (iter.hasNext()) { + Object obj = iter.next(); + if (obj instanceof ColumnGroup) { + ((ColumnGroup) obj).setColumnMargin(margin); + } + } + } +} diff --git a/src/eu/engys/util/ui/groupcolumnheader/GroupableTableColumnModel.java b/src/eu/engys/util/ui/groupcolumnheader/GroupableTableColumnModel.java new file mode 100644 index 0000000..4ce29b7 --- /dev/null +++ b/src/eu/engys/util/ui/groupcolumnheader/GroupableTableColumnModel.java @@ -0,0 +1,68 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.groupcolumnheader; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Vector; + +import javax.swing.table.DefaultTableColumnModel; +import javax.swing.table.TableColumn; + +public class GroupableTableColumnModel extends DefaultTableColumnModel { + + protected ArrayList columnGroups = new ArrayList<>(); + + public void addColumnGroup(ColumnGroup columnGroup) { + columnGroups.add(columnGroup); + } + + public Iterator columnGroupIterator() { + return columnGroups.iterator(); + } + + public ColumnGroup getColumnGroup(int index) { + if (index >= 0 && index < columnGroups.size()) { + return (ColumnGroup) columnGroups.get(index); + } + return null; + } + + public Iterator getColumnGroups(TableColumn col) { + if (columnGroups.isEmpty()) + return null; + Iterator iter = columnGroups.iterator(); + while (iter.hasNext()) { + ColumnGroup cGroup = iter.next(); + Vector v_ret = cGroup.getColumnGroups(col, new Vector<>()); + if (v_ret != null) { + return v_ret.iterator(); + } + } + return null; + } +} diff --git a/src/eu/engys/util/ui/groupcolumnheader/GroupableTableHeader.java b/src/eu/engys/util/ui/groupcolumnheader/GroupableTableHeader.java new file mode 100644 index 0000000..3c2a2ee --- /dev/null +++ b/src/eu/engys/util/ui/groupcolumnheader/GroupableTableHeader.java @@ -0,0 +1,50 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.groupcolumnheader; + +import java.util.Iterator; + +import javax.swing.table.JTableHeader; + +public class GroupableTableHeader extends JTableHeader { + + public GroupableTableHeader(GroupableTableColumnModel model) { + super(model); + setUI(new GroupableTableHeaderUI()); + setReorderingAllowed(false); + } + + public void setColumnMargin() { + int columnMargin = getColumnModel().getColumnMargin(); + Iterator iter = ((GroupableTableColumnModel) columnModel).columnGroupIterator(); + while (iter.hasNext()) { + ColumnGroup cGroup = (ColumnGroup) iter.next(); + cGroup.setColumnMargin(columnMargin); + } + } + +} diff --git a/src/eu/engys/util/ui/groupcolumnheader/GroupableTableHeaderUI.java b/src/eu/engys/util/ui/groupcolumnheader/GroupableTableHeaderUI.java new file mode 100644 index 0000000..a835efc --- /dev/null +++ b/src/eu/engys/util/ui/groupcolumnheader/GroupableTableHeaderUI.java @@ -0,0 +1,157 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.groupcolumnheader; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; + +import javax.swing.JComponent; +import javax.swing.plaf.basic.BasicTableHeaderUI; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; + +public class GroupableTableHeaderUI extends BasicTableHeaderUI { + + protected Vector paintedGroups = new Vector(); + + @Override + public void paint(Graphics g, JComponent c) { + Rectangle clipBounds = g.getClipBounds(); + GroupableTableColumnModel cm = (GroupableTableColumnModel) header.getColumnModel(); + if (cm == null) + return; + ((GroupableTableHeader) header).setColumnMargin(); + int column = 0; + Dimension size = header.getSize(); + Rectangle cellRect = new Rectangle(0, 0, size.width, size.height); + Hashtable h = new Hashtable(); + + Enumeration columns = cm.getColumns(); + while (columns.hasMoreElements()) { + cellRect.height = size.height; + cellRect.y = 0; + TableColumn aColumn = (TableColumn) columns.nextElement(); + Iterator colGrpIter = cm.getColumnGroups(aColumn); + if (colGrpIter != null) { + int groupHeight = 0; + while (colGrpIter.hasNext()) { + ColumnGroup cGroup = (ColumnGroup) colGrpIter.next(); + Rectangle groupRect = (Rectangle) h.get(cGroup); + if (groupRect == null) { + groupRect = new Rectangle(cellRect); + Dimension d = cGroup.getSize(header.getTable()); + groupRect.width = d.width; + groupRect.height = d.height; + h.put(cGroup, groupRect); + } + if (!paintedGroups.contains(cGroup)) { + paintCell(g, groupRect, cGroup); + paintedGroups.add(cGroup); + } + groupHeight += groupRect.height; + cellRect.height = size.height - groupHeight; + cellRect.y = groupHeight; + } + } + cellRect.width = aColumn.getWidth(); + if (cellRect.intersects(clipBounds)) { + paintCell(g, cellRect, column); + } + cellRect.x += cellRect.width; + column++; + } + paintedGroups.clear(); + } + + private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) { + TableColumn aColumn = header.getColumnModel().getColumn(columnIndex); + TableCellRenderer renderer = aColumn.getHeaderRenderer(); + if (renderer == null) { + renderer = header.getDefaultRenderer(); + } + Component component = renderer.getTableCellRendererComponent(header.getTable(), aColumn.getHeaderValue(), false, false, -1, columnIndex); + rendererPane.add(component); + rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); + } + + private void paintCell(Graphics g, Rectangle cellRect, ColumnGroup cGroup) { + TableCellRenderer renderer = cGroup.getHeaderRenderer(); + Component component = renderer.getTableCellRendererComponent(header.getTable(), cGroup.getHeaderValue(), false, false, -1, -1); + rendererPane.add(component); + rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); + } + + private int getHeaderHeight() { + int height = 0; + GroupableTableColumnModel columnModel = (GroupableTableColumnModel) header.getColumnModel(); + for (int column = 0; column < columnModel.getColumnCount(); column++) { + TableColumn aColumn = columnModel.getColumn(column); + TableCellRenderer renderer = aColumn.getHeaderRenderer(); + if (renderer == null) { + renderer = header.getDefaultRenderer(); + } + Component comp = renderer.getTableCellRendererComponent(header.getTable(), aColumn.getHeaderValue(), false, false, -1, column); + int cHeight = comp.getPreferredSize().height; + Iterator iter = columnModel.getColumnGroups(aColumn); + if (iter != null) { + while (iter.hasNext()) { + ColumnGroup cGroup = (ColumnGroup) iter.next(); + cHeight += cGroup.getSize(header.getTable()).height; + } + } + height = Math.max(height, cHeight); + } + return height; + } + + private Dimension createHeaderSize(long width) { + TableColumnModel columnModel = header.getColumnModel(); + width += columnModel.getColumnMargin() * columnModel.getColumnCount(); + if (width > Integer.MAX_VALUE) { + width = Integer.MAX_VALUE; + } + return new Dimension((int) width, getHeaderHeight()); + } + + @Override + public Dimension getPreferredSize(JComponent c) { + long width = 0; + Enumeration columns = header.getColumnModel().getColumns(); + while (columns.hasMoreElements()) { + TableColumn aColumn = (TableColumn) columns.nextElement(); + width = width + aColumn.getPreferredWidth(); + } + return createHeaderSize(width); + } +} diff --git a/src/eu/engys/util/ui/stepcomponent/FlatButtonUI.java b/src/eu/engys/util/ui/stepcomponent/FlatButtonUI.java new file mode 100644 index 0000000..3b8a311 --- /dev/null +++ b/src/eu/engys/util/ui/stepcomponent/FlatButtonUI.java @@ -0,0 +1,173 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.stepcomponent; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.RenderingHints; + +import javax.swing.AbstractButton; +import javax.swing.ButtonModel; +import javax.swing.JComponent; +import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicToggleButtonUI; + +import sun.swing.SwingUtilities2; + +public class FlatButtonUI extends BasicToggleButtonUI { + + Color bgColor = new Color(200, 220, 240);// = Color.LIGHT_GRAY;//new Color(200, 220, 240); + Color selColor = new Color(66, 100, 150);// = Color.GRAY;//new Color(66, 100, 150); + + Color fgColor = Color.BLACK; + Color selFgColor = Color.WHITE; + Color borderColor = Color.WHITE; + + protected void installDefaults(AbstractButton b) { + String str = getPropertyPrefix(); + LookAndFeel.installColorsAndFont(b, str + "background", str + "foreground", str + "font"); +// bgColor = b.getBackground(); +// selColor = bgColor.darker(); + } + + public void paint(Graphics g, JComponent c) { + AbstractButton b = (AbstractButton) c; + + ButtonModel model = b.getModel(); + + Dimension size = b.getSize(); + FontMetrics fm = g.getFontMetrics(); + + //Insets i = c.getInsets(); + + Rectangle viewRect = new Rectangle(size); + +// viewRect.x += i.left; +// viewRect.y += i.top; +// viewRect.width -= (i.right + viewRect.x); +// viewRect.height -= (i.bottom + viewRect.y); + + Rectangle iconRect = new Rectangle(); + Rectangle textRect = new Rectangle(); + + Font f = c.getFont(); + g.setFont(f); + + // layout the text and icon + String text = SwingUtilities.layoutCompoundLabel(c, fm, b.getText(), b.getIcon(), b.getVerticalAlignment(), b.getHorizontalAlignment(), b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect, iconRect, textRect, b.getText() == null ? 0 : b.getIconTextGap()); + + if (model.isArmed() && model.isPressed() || model.isSelected()) { + paintButton(g,b,viewRect, selColor); + } else if (model.isRollover()) { + paintButton(g,b,viewRect, Color.ORANGE); + } else if (!b.isEnabled()) { + paintButton(g,b,viewRect, Color.LIGHT_GRAY); + } else { + paintButton(g,b,viewRect, bgColor); + } + + // Paint the Icon +// if(b.getIcon() != null) { +// paintIcon(g, b, iconRect); +// } + + // Draw the Text + if(text != null && !text.equals("")) { + paintText(g, b, textRect, text); + } + +// // draw the dashed focus line. +// if (b.isFocusPainted() && b.hasFocus()) { +// paintFocus(g, b, viewRect, textRect, iconRect); +// } + } + + protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { + ButtonModel model = b.getModel(); + FontMetrics fm = SwingUtilities2.getFontMetrics(b, g); + int mnemonicIndex = b.getDisplayedMnemonicIndex(); + + /* Draw the Text */ + if(model.isEnabled()) { + /*** paint the text normally */ + g.setColor(model.isSelected()? selFgColor : fgColor); + SwingUtilities2.drawStringUnderlineCharAt(b, g,text, mnemonicIndex, textRect.x + getTextShiftOffset(), textRect.y + fm.getAscent() + getTextShiftOffset()); + } + else { + /*** paint the text disabled ***/ + g.setColor(b.getBackground().brighter()); + SwingUtilities2.drawStringUnderlineCharAt(b, g,text, mnemonicIndex, textRect.x, textRect.y + fm.getAscent()); + g.setColor(b.getBackground().darker()); + SwingUtilities2.drawStringUnderlineCharAt(b, g,text, mnemonicIndex, textRect.x - 1, textRect.y + fm.getAscent() - 1); + } + } + + private void paintButton(Graphics g, AbstractButton b, Rectangle viewRect, Color color) { + Polygon poly = new Polygon(); + + int BoRDo = 2; + int BRD = BoRDo/2; + int DRIFT = 10; + + poly.addPoint(viewRect.x + BRD, viewRect.y + BRD); + + if (b.isSelected()) { + poly.addPoint(viewRect.x + viewRect.width - DRIFT - 2*BRD, viewRect.y + BRD); + poly.addPoint(viewRect.x + viewRect.width - 2*BRD, viewRect.y + viewRect.height/2); + poly.addPoint(viewRect.x + viewRect.width - DRIFT - 2*BRD, viewRect.y + viewRect.height - 2*BRD); + } else { + poly.addPoint(viewRect.x + viewRect.width - DRIFT - 2*BRD, viewRect.y + BRD); + poly.addPoint(viewRect.x + viewRect.width - DRIFT - 2*BRD, viewRect.y + viewRect.height - 2*BRD); + } + + poly.addPoint(viewRect.x + BRD, viewRect.y + viewRect.height - 2*BRD); + + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + if (b.isSelected()) { + g2.setColor(color); + g2.fillPolygon(poly); + } + + g.setColor(borderColor); + g2.setStroke(new BasicStroke(BoRDo)); + g.drawPolygon(poly); + + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + + protected void paintIcon(Graphics g, AbstractButton b, Rectangle iconRect) {} + } diff --git a/src/eu/engys/util/ui/stepcomponent/MultiLineLabel.java b/src/eu/engys/util/ui/stepcomponent/MultiLineLabel.java new file mode 100644 index 0000000..de74b08 --- /dev/null +++ b/src/eu/engys/util/ui/stepcomponent/MultiLineLabel.java @@ -0,0 +1,698 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.stepcomponent; + +/* + * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved. + * + * http://izpack.org/ + * http://izpack.codehaus.org/ + * + * Copyright 1997,2002 Elmar Grom + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Toolkit; +import java.util.Map; +import java.util.Vector; + +import javax.swing.JComponent; + +/*---------------------------------------------------------------------------*/ +/** + *
+ * MultiLineLabel may be used in place of javax.swing.JLabel.
+ *
+ * This class implements a component that is capable of displaying multiple + * lines of text. Line breaks are inserted automatically whenever a line of text + * extends beyond the predefined maximum line length. Line breaks will only be + * inserted between words, except where a single word is longer than the maximum + * line length. Line breaks may be forced at any location in the text by + * inserting a newline (\n). White space that is not valuable (i.e. is placed at + * the beginning of a new line or at the very beginning or end of the text) is + * removed.
+ *
+ * Note: you can set the maximum width of the label either through one of + * the constructors or you can call setMaxWidth() explicitly. If + * this is not set, MultiLineLabel will derive its width from the + * parent component. + * + * @author Elmar Grom + * @version 1.0 / 04-13-02 + */ +/*---------------------------------------------------------------------------* + * Reviving some old code here that was written before there was swing. + * The original was written to work with awt. I had to do some masaging to + * make it a JComponent and I hope it behaves like a reasonably good mannered + * swing component. + *---------------------------------------------------------------------------*/ +public class MultiLineLabel extends JComponent { + + /** + * + */ + private static final long serialVersionUID = 4051045255031894837L; + + public static final int LEFT = 0; // alignment constants + + public static final int CENTER = 1; + + public static final int RIGHT = 2; + + public static final int DEFAULT_MARGIN = 10; + + public static final int DEFAULT_ALIGN = LEFT; + + public static final int LEAST_ALLOWED = 200; // default setting for + + // maxAllowed + + private static final int FOUND = 0; // constants for string search. + + private static final int NOT_FOUND = 1; + + private static final int NOT_DONE = 0; + + private static final int DONE = 1; + + private static final char[] WHITE_SPACE = { ' ', '\n', '\t' }; + + private static final char[] SPACES = { ' ', '\t' }; + + private static final char NEW_LINE = '\n'; + + protected Vector line = new Vector();// text lines to + // display + + protected String labelText; // text lines to display + + protected int numLines; // the number of lines + + protected int marginHeight; // top and bottom margins + + protected int marginWidth; // left and right margins + + protected int lineHeight; // total height of the font + + protected int lineAscent; // font height above the baseline + + protected int lineDescent; // font hight below the baseline + + protected int[] lineWidth; // width of each line + + protected int maxWidth; // width of the widest line + + private int maxAllowed = LEAST_ALLOWED; // max width allowed to use + + private boolean maxAllowedSet = false; // signals if the max allowed width + + // has been explicitly set + + protected int alignment = LEFT; // default text alignment + + /*-------------------------------------------------------------------*/ + /** + * Constructor + * + * @param text + * the text to be displayed + * @param horMargin + * the horizontal margin for the label + * @param vertMargin + * the vertical margin for the label + * @param maxWidth + * the maximum allowed width of the text + * @param justify + * the text alignment for the label + */ + /*-------------------------------------------------------------------* + * + *-------------------------------------------------------------------*/ + public MultiLineLabel(String text, int horMargin, int vertMargin, int maxWidth, int justify) { + this.labelText = text; + this.marginWidth = horMargin; + this.marginHeight = vertMargin; + this.maxAllowed = maxWidth; + this.maxAllowedSet = true; + this.alignment = justify; + } + + /*-------------------------------------------------------------------*/ + /** + * Constructor using default max-width and alignment. + * + * @param label + * the text to be displayed + * @param marginWidth + * the horizontal margin for the label + * @param marginHeight + * the vertical margin for the label + */ + /*-------------------------------------------------------------------* + * + *-------------------------------------------------------------------*/ + public MultiLineLabel(String label, int marginWidth, int marginHeight) { + this.labelText = label; + this.marginWidth = marginWidth; + this.marginHeight = marginHeight; + } + + /*-------------------------------------------------------------------*/ + /** + * Constructor using default max-width, and margin. + * + * @param label + * the text to be displayed + * @param alignment + * the text alignment for the label + */ + /*-------------------------------------------------------------------* + * + *-------------------------------------------------------------------*/ + public MultiLineLabel(String label, int alignment) { + this.labelText = label; + this.alignment = alignment; + } + + /*-------------------------------------------------------------------*/ + /** + * Constructor using default max-width, alignment, and margin. + * + * @param label + * the text to be displayed + */ + /*-------------------------------------------------------------------* + * + *-------------------------------------------------------------------*/ + public MultiLineLabel(String label) { + this.labelText = label; + } + + /*-------------------------------------------------------------------*/ + /** + * This method searches the target string for occurences of any of the + * characters in the source string. The return value is the position of the + * first hit. Based on the mode parameter the hit position is either the + * position where any of the source characters first was found or the first + * position where none of the source characters where found. + * + * @param target + * the text to be searched + * @param start + * the start position for the search + * @param source + * the list of characters to be searched for + * @param mode + * the search mode FOUND = reports first found NOT_FOUND = + * reports first not found + * @return position of the first occurence + */ + /*-------------------------------------------------------------------* + * + *-------------------------------------------------------------------*/ + int getPosition(String target, int start, char[] source, int mode) { + int status; + int position; + int scan; + int targetEnd; + int sourceLength; + char temp; + + targetEnd = (target.length() - 1); + sourceLength = source.length; + position = start; + + if (mode == FOUND) { + status = NOT_DONE; + while (status != DONE) { + position++; + if (!(position < targetEnd)) // end of string reached, the + // next + { // statement would cause a runtime error + return (targetEnd); + } + temp = target.charAt(position); + for (scan = 0; scan < sourceLength; scan++) // walk through the + // source + { // string and compare each char + if (source[scan] == temp) { + status = DONE; + } + } + } + return (position); + } else if (mode == NOT_FOUND) { + status = NOT_DONE; + while (status != DONE) { + position++; + if (!(position < targetEnd)) // end of string reached, the + // next + { // statement would cause a runtime error + return (targetEnd); + } + temp = target.charAt(position); + status = DONE; + for (scan = 0; scan < sourceLength; scan++) // walk through the + // source + { // string and compare each char + if (source[scan] == temp) { + status = NOT_DONE; + } + } + } + return (position); + } + return (0); + } + + /*-------------------------------------------------------------------*/ + /** + * This method scans the input string until the max allowed width is + * reached. The return value indicates the position just before this + * happens. + * + * @param word + * word to break + * @return position character position just before the string is too long + */ + /*-------------------------------------------------------------------* + * + *-------------------------------------------------------------------*/ + int breakWord(String word, FontMetrics fm) { + int width; + int currentPos; + int endPos; + + width = 0; + currentPos = 0; + endPos = word.length() - 1; + + // make sure we don't end up with a negative position + if (endPos <= 0) { + return (currentPos); + } + // seek the position where the word first is longer than allowed + while ((width < maxAllowed) && (currentPos < endPos)) { + currentPos++; + width = fm.stringWidth(labelText.substring(0, currentPos)); + } + // adjust to get the chatacter just before (this should make it a bit + // shorter than allowed!) + if (currentPos != endPos) { + currentPos--; + } + return (currentPos); + } + + /*-------------------------------------------------------------------*/ + /** + * This method breaks the label text up into multiple lines of text. Line + * breaks are established based on the maximum available space. A new line + * is started whenever a line break is encountered, even if the permissible + * length is not yet reached. Words are broken only if a single word happens + * to be longer than one line. + */ + /*-------------------------------------------------------------------*/ + private void divideLabel() { + int width; + int startPos; + int currentPos; + int lastPos; + int endPos; + + line.clear(); + FontMetrics fm = this.getFontMetrics(this.getFont()); + + startPos = 0; + currentPos = startPos; + lastPos = currentPos; + endPos = (labelText.length() - 1); + + while (currentPos < endPos) { + width = 0; + // ---------------------------------------------------------------- + // find the first substring that occupies more than the granted + // space. + // Break at the end of the string or a line break + // ---------------------------------------------------------------- + while ((width < maxAllowed) && (currentPos < endPos) && (labelText.charAt(currentPos) != NEW_LINE)) { + lastPos = currentPos; + currentPos = getPosition(labelText, currentPos, WHITE_SPACE, FOUND); + width = fm.stringWidth(labelText.substring(startPos, currentPos)); + } + // ---------------------------------------------------------------- + // if we have a line break we want to copy everything up to + // currentPos + // ---------------------------------------------------------------- + if (labelText.charAt(currentPos) == NEW_LINE) { + lastPos = currentPos; + } + // ---------------------------------------------------------------- + // if we are at the end of the string we want to copy everything up + // to + // the last character. Since there seems to be a problem to get the + // last + // character if the substring definition ends at the very last + // character + // we have to call a different substring function than normal. + // ---------------------------------------------------------------- + if (currentPos == endPos && width <= maxAllowed) { + lastPos = currentPos; + String s = labelText.substring(startPos); + line.addElement(s); + } + // ---------------------------------------------------------------- + // in all other cases copy the substring that we have found to fit + // and + // add it as a new line of text to the line vector. + // ---------------------------------------------------------------- + else { + // ------------------------------------------------------------ + // make sure it's not a single word. If so we must break it at + // the + // proper location. + // ------------------------------------------------------------ + if (lastPos == startPos) { + lastPos = startPos + breakWord(labelText.substring(startPos, currentPos), fm); + } + String s = labelText.substring(startPos, lastPos); + line.addElement(s); + } + + // ---------------------------------------------------------------- + // seek for the end of the white space to cut out any unnecessary + // spaces + // and tabs and set the new start condition. + // ---------------------------------------------------------------- + startPos = getPosition(labelText, lastPos, SPACES, NOT_FOUND); + currentPos = startPos; + } + + numLines = line.size(); + lineWidth = new int[numLines]; + } + + /*-------------------------------------------------------------------*/ + /** + * This method finds the font size, each line width and the widest line. + */ + /*-------------------------------------------------------------------*/ + protected void measure() { + if (!maxAllowedSet) { + maxAllowed = getParent().getSize().width; + } + + // return if width is too small + if (maxAllowed < (20)) { + return; + } + + FontMetrics fm = this.getFontMetrics(this.getFont()); + + // return if no font metrics available + if (fm == null) { + return; + } + + divideLabel(); + + this.lineHeight = fm.getHeight(); + this.lineDescent = fm.getDescent(); + this.maxWidth = 0; + + for (int i = 0; i < numLines; i++) { + this.lineWidth[i] = fm.stringWidth(this.line.elementAt(i)); + if (this.lineWidth[i] > this.maxWidth) { + this.maxWidth = this.lineWidth[i]; + } + } + } + + /*-------------------------------------------------------------------*/ + /** + * This method draws the label. + * + * @param graphics + * the device context + */ + /*-------------------------------------------------------------------*/ + public void paintComponent(Graphics graphics) { + int x; + int y; + + measure(); + Dimension d = this.getSize(); + + y = lineAscent + (d.height - (numLines * lineHeight)) / 2; + + Toolkit tk = Toolkit.getDefaultToolkit(); + Map desktopHints = (Map)(tk.getDesktopProperty("awt.font.desktophints")); + Graphics2D g2d = (Graphics2D)graphics; + + if(desktopHints != null) { + g2d.addRenderingHints(desktopHints); + } + for (int i = 0; i < numLines; i++) { + y += lineHeight; + switch (alignment) { + case LEFT: + x = marginWidth; + break; + case CENTER: + x = (d.width - lineWidth[i]) / 2; + break; + case RIGHT: + x = d.width - marginWidth - lineWidth[i]; + break; + default: + x = (d.width - lineWidth[i]) / 2; + } + graphics.drawString(line.elementAt(i), x, y-lineDescent); + //graphics.drawRect(x, y-lineHeight, d.width, lineHeight); + } + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to set the label text + * + * @param labelText + * the text to be displayed + */ + /*-------------------------------------------------------------------*/ + public void setText(String labelText) { + this.labelText = labelText; + repaint(); + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to set the font that should be used to draw the + * label + * + * @param font + * font to be used within the label + */ + /*-------------------------------------------------------------------*/ + public void setFont(Font font) { + super.setFont(font); + repaint(); + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to set the color in which the text should be + * drawn + * + * @param color + * the text color + */ + /*-------------------------------------------------------------------*/ + public void setColor(Color color) { + super.setForeground(color); + repaint(); + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to set the text alignment for the label + * + * @param alignment + * the alignment, possible values are LEFT, CENTER, RIGHT + */ + /*-------------------------------------------------------------------*/ + public void setJustify(int alignment) { + this.alignment = alignment; + repaint(); + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to set the max allowed line width + * + * @param width + * the max allowed line width in pixels + */ + /*-------------------------------------------------------------------*/ + public void setMaxWidth(int width) { + this.maxAllowed = width; + this.maxAllowedSet = true; + repaint(); + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to set the horizontal margin + * + * @param margin + * the margin to the left and to the right of the label + */ + /*-------------------------------------------------------------------*/ + public void setMarginWidth(int margin) { + this.marginWidth = margin; + repaint(); + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to set the vertical margin for the label + * + * @param margin + * the margin on the top and bottom of the label + */ + /*-------------------------------------------------------------------*/ + public void setMarginHeight(int margin) { + this.marginHeight = margin; + repaint(); + } + + /*-------------------------------------------------------------------*/ + /** + * Moves and resizes this component. The new location of the top-left corner + * is specified by x and y, and the new size is + * specified by width and height. + * + * @param x + * The new x-coordinate of this component. + * @param y + * The new y-coordinate of this component. + * @param width + * The new width of this component. + * @param height + * The new height of this component. + */ + /*-------------------------------------------------------------------*/ + public void setBounds(int x, int y, int width, int height) { + super.setBounds(x, y, width, height); + this.maxAllowed = width; + this.maxAllowedSet = true; + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to retrieve the text alignment for the label + * + * @return alignment the text alignment currently in use for the label + */ + /*-------------------------------------------------------------------*/ + public int getAlignment() { + return (this.alignment); + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to retrieve the horizontal margin for the label + * + * @return marginWidth the margin currently in use to the left and right of + * the label + */ + /*-------------------------------------------------------------------*/ + public int getMarginWidth() { + return (this.marginWidth); + } + + /*-------------------------------------------------------------------*/ + /** + * This method may be used to retrieve the vertical margin for the label + * + * @return marginHeight the margin currently in use on the top and bottom of + * the label + */ + /*-------------------------------------------------------------------*/ + public int getMarginHeight() { + return (this.marginHeight); + } + + /*-------------------------------------------------------------------*/ + /** + * This method is typically used by the layout manager, it reports the + * necessary space to display the label comfortably. + */ + /*-------------------------------------------------------------------*/ + public Dimension getPreferredSize() { + measure(); + return (new Dimension(maxAllowed, (numLines * (lineHeight + lineAscent + lineDescent)) + (2 * marginHeight))); + } + + /*-------------------------------------------------------------------*/ + /** + * This method is typically used by the layout manager, it reports the + * absolute minimum space required to display the entire label. + */ + /*-------------------------------------------------------------------*/ + public Dimension getMinimumSize() { + measure(); + return (new Dimension(maxAllowed, (numLines * (lineHeight + lineAscent + lineDescent)) + (2 * marginHeight))); + } + + /*-------------------------------------------------------------------*/ + /** + * This method is called by the system after this object is first created. + */ + /*-------------------------------------------------------------------*/ + public void addNotify() { + super.addNotify(); // invoke the superclass + } +} +/*---------------------------------------------------------------------------*/ diff --git a/src/eu/engys/util/ui/stepcomponent/RichJLabel.java b/src/eu/engys/util/ui/stepcomponent/RichJLabel.java new file mode 100644 index 0000000..c357d1d --- /dev/null +++ b/src/eu/engys/util/ui/stepcomponent/RichJLabel.java @@ -0,0 +1,142 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.stepcomponent; + +/* +Swing Hacks Tips and Tools for Killer GUIs +By Joshua Marinacci, Chris Adamson +First Edition June 2005 +Series: Hacks +ISBN: 0-596-00907-0 +Pages: 542 +website: http://www.oreilly.com/catalog/swinghks/ + */ +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.font.LineMetrics; + +import javax.swing.JFrame; +import javax.swing.JLabel; + +public class RichJLabel extends JLabel { + + private int tracking; + + public RichJLabel(String text, int tracking) { + super(text); + this.tracking = tracking; + } + + private int left_x, left_y, right_x, right_y; + + private Color left_color, right_color; + + public void setLeftShadow(int x, int y, Color color) { + left_x = x; + left_y = y; + left_color = color; + } + + public void setRightShadow(int x, int y, Color color) { + right_x = x; + right_y = y; + right_color = color; + } + + public Dimension getPreferredSize() { + String text = getText(); + FontMetrics fm = this.getFontMetrics(getFont()); + + int w = fm.stringWidth(text); + w += (text.length() - 1) * tracking; + w += left_x + right_x; + + int h = fm.getHeight(); + h += left_y + right_y; + + return new Dimension(w, h); + } + + public void paintComponent(Graphics g) { + ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + char[] chars = getText().toCharArray(); + + FontMetrics fm = this.getFontMetrics(getFont()); + int h = fm.getAscent(); + LineMetrics lm = fm.getLineMetrics(getText(), g); + g.setFont(getFont()); + + int x = 0; + + for (int i = 0; i < chars.length; i++) { + char ch = chars[i]; + int w = fm.charWidth(ch) + tracking; + + g.setColor(getLeft_color()); + g.drawString("" + chars[i], x - left_x, h - left_y); + + g.setColor(getRight_color()); + g.drawString("" + chars[i], x + right_x, h + right_y); + + g.setColor(getForeground()); + g.drawString("" + chars[i], x, h); + + x += w; + } + + } + + public Color getLeft_color() { + return left_color; + } + + public Color getRight_color() { + return right_color; + } + + public static void main(String[] args) { + RichJLabel label = new RichJLabel("www.java2s.com", 0); + label.setLeftShadow(1, 1, Color.white); + label.setRightShadow(1, 1, Color.white); + label.setForeground(Color.blue); + label.setFont(label.getFont().deriveFont(140f)); + + JFrame frame = new JFrame("RichJLabel hack"); + frame.getContentPane().add(label); + frame.pack(); + frame.setVisible(true); + } + + public static void p(String str) { + System.out.println(str); + } +} diff --git a/src/eu/engys/util/ui/stepcomponent/StepButton.java b/src/eu/engys/util/ui/stepcomponent/StepButton.java new file mode 100644 index 0000000..216e742 --- /dev/null +++ b/src/eu/engys/util/ui/stepcomponent/StepButton.java @@ -0,0 +1,160 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.stepcomponent; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JComponent; +import javax.swing.JToggleButton; +import javax.swing.border.Border; + +class StepButton extends JToggleButton { + + private final int drift; + private final int borderWidth; + private final int buttonHeight; + private final boolean first; + private final boolean last; + + private JComponent title; + private JComponent description; + + private boolean changeForeground() { + return model.isArmed() && model.isPressed() || model.isSelected(); + } + + public StepButton(String title, String text, int drift, int borderWidth, int buttonHeight) { + this(title, text, drift, borderWidth, buttonHeight, false, false); + } + + public StepButton(String title, String text, int drift, int borderWidth, int buttonHeight, boolean first, boolean last) { + super(); + this.drift = drift; + this.borderWidth = borderWidth; + this.buttonHeight = buttonHeight; + this.first = first; + this.last = last; + setName(title); + + configureTitle(title); + if (text != null) + configureDescription(text); + setActionCommand(title); + configureButton(); + } + + public void configureButton() { + setLayout(new GridBagLayout()); + setRolloverEnabled(true); + Insets in = new Insets(0, first? getDrift() : 2*getDrift() , 0, first? getDrift() : getDrift()); + + if (description != null) { + add(title, new GridBagConstraints(0,0, 1,1, 1.0, 1.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.HORIZONTAL, in, 0,0)); + add(description, new GridBagConstraints(0,1, 1,1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, in, 0,0)); + } else { + add(title, new GridBagConstraints(0,0, 1,1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, in, 0,0)); + } + } + + private void configureDescription(String text) { + description = new MultiLineLabel(text) { + public Color getForeground() { + return changeForeground()? Color.WHITE : Color.BLACK; + } + }; + } + + private void configureTitle(String text) { +// title = new RichJLabel(text, 0) { +// public Color getForeground() { +// return changeForeground()? Color.WHITE : Color.BLACK; +// }; +// +// @Override +// public Color getLeft_color() { +// return changeForeground()? Color.DARK_GRAY : super.getLeft_color(); +// } +// +// @Override +// public Color getRight_color() { +// return changeForeground()? Color.BLACK : super.getRight_color(); +// } +// }; +// title.setLeftShadow(1, 1, Color.white); +// title.setRightShadow(1, 1, Color.lightGray); +// +// title.setForeground(Color.blue); +// title.setFont(title.getFont().deriveFont(20f)); + title = new MultiLineLabel(text, MultiLineLabel.CENTER) { + public Color getForeground() { + return changeForeground()? Color.WHITE : Color.BLACK; + } + }; + //title.setFont(getFont().deriveFont(getFont().getSize2D()+4)); + //title.setBorder(BorderFactory.createLineBorder(Color.RED)); + } + + public void updateUI() { + setUI(new StepButtonUI()); + } + + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + return new Dimension(d.width, buttonHeight); + } + + public boolean isFirst() { + return first; + } + + public boolean isLast() { + return last; + } + + public int getDrift() { + return drift; + } + + public int getBorderWidth() { + return borderWidth; + } + + @Override + public void setBorder(Border border) { + throw new IllegalStateException("Don't use this method"); + } + + @Override + public Border getBorder() { + return null; + } +} diff --git a/src/eu/engys/util/ui/stepcomponent/StepButtonUI.java b/src/eu/engys/util/ui/stepcomponent/StepButtonUI.java new file mode 100644 index 0000000..a0d8764 --- /dev/null +++ b/src/eu/engys/util/ui/stepcomponent/StepButtonUI.java @@ -0,0 +1,156 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.stepcomponent; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.RenderingHints; + +import javax.swing.AbstractButton; +import javax.swing.ButtonModel; +import javax.swing.JComponent; +import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicToggleButtonUI; + +public class StepButtonUI extends BasicToggleButtonUI { + + Color bgColor = new Color(200, 220, 240); + Color selColor = new Color(66, 100, 150); + + Color fgColor = Color.BLACK; + Color selFgColor = Color.WHITE; + + protected void installDefaults(AbstractButton b) { + String str = getPropertyPrefix(); + LookAndFeel.installColorsAndFont(b, str + "background", str + "foreground", str + "font"); + } + + public void paint(Graphics g, JComponent c) { + StepButton b = (StepButton) c; + boolean isFirst = b.isFirst(); + boolean isLast = b.isLast(); + + ButtonModel model = b.getModel(); + + Dimension size = b.getSize(); + FontMetrics fm = g.getFontMetrics(); + + //Insets i = c.getInsets(); + + Rectangle viewRect = new Rectangle(size); + +// viewRect.x += i.left; +// viewRect.y += i.top; +// viewRect.width -= (i.right + viewRect.x); +// viewRect.height -= (i.bottom + viewRect.y); + + Rectangle iconRect = new Rectangle(); + Rectangle textRect = new Rectangle(); + + Font f = c.getFont(); + g.setFont(f); + + // layout the text and icon + String text = SwingUtilities.layoutCompoundLabel(c, fm, b.getText(), b.getIcon(), b.getVerticalAlignment(), b.getHorizontalAlignment(), b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect, iconRect, textRect, b.getText() == null ? 0 : b.getIconTextGap()); + + if (model.isArmed() && model.isPressed() || model.isSelected()) { + paintButton(g,b,viewRect, selColor, isFirst, isLast); + } else if (model.isRollover()) { + paintButton(g,b,viewRect, Color.ORANGE, isFirst, isLast); + } else if (!b.isEnabled()) { + paintButton(g,b,viewRect, Color.LIGHT_GRAY, isFirst, isLast); + } else { + paintButton(g,b,viewRect, bgColor, isFirst, isLast); + } + + // Paint the Icon +// if(b.getIcon() != null) { +// paintIcon(g, b, iconRect); +// } + + // Draw the Text + if(text != null && !text.equals("")) { + paintText(g, b, textRect, text); + } + +// // draw the dashed focus line. +// if (b.isFocusPainted() && b.hasFocus()) { +// paintFocus(g, b, viewRect, textRect, iconRect); +// } + } + + protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {} + + private void paintButton(Graphics g, StepButton b, Rectangle viewRect, Color color, boolean isFirst, boolean isLast) { + Polygon poly = new Polygon(); + + int BoRDo = b.getBorderWidth(); + int BRD = BoRDo/2; + int DRIFT = b.getDrift(); + +// if (isFirst) +// poly.addPoint(viewRect.x + BRD + DRIFT, viewRect.y + BRD); +// else + poly.addPoint(viewRect.x + BRD, viewRect.y + BRD); + + if (isLast) { + poly.addPoint(viewRect.x + viewRect.width - 2*BRD, viewRect.y + BRD); + poly.addPoint(viewRect.x + viewRect.width - 2*BRD, viewRect.y + viewRect.height - 2*BRD); + } else { + poly.addPoint(viewRect.x + viewRect.width - DRIFT - 2*BRD, viewRect.y + BRD); + poly.addPoint(viewRect.x + viewRect.width - 2*BRD, viewRect.y + viewRect.height/2); + poly.addPoint(viewRect.x + viewRect.width - DRIFT - 2*BRD, viewRect.y + viewRect.height - 2*BRD); + } + +// if (isFirst) +// poly.addPoint(viewRect.x + BRD + DRIFT, viewRect.y + viewRect.height - BRD); +// else + poly.addPoint(viewRect.x + BRD, viewRect.y + viewRect.height - 2*BRD); + + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(color); + g2.fillPolygon(poly); + + g.setColor(Color.WHITE); + g2.setStroke(new BasicStroke(BoRDo)); + g.drawPolygon(poly); + + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + + protected void paintIcon(Graphics g, AbstractButton b, Rectangle iconRect) {} + } diff --git a/src/eu/engys/util/ui/stepcomponent/StepComponent.java b/src/eu/engys/util/ui/stepcomponent/StepComponent.java new file mode 100644 index 0000000..5784243 --- /dev/null +++ b/src/eu/engys/util/ui/stepcomponent/StepComponent.java @@ -0,0 +1,141 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.stepcomponent; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +import javax.swing.ButtonGroup; +import javax.swing.DefaultSingleSelectionModel; +import javax.swing.JPanel; + +public class StepComponent extends JPanel { + + private static final int HEIGHT = 30; + private static final int DRIFT = 30; + private static final int BRD = 4; + + private final ButtonGroup bg = new ButtonGroup(); + private final ArrayList buttons = new ArrayList(); + + private int drift = DRIFT; + private int borderWidth = BRD; + private int buttonHeight = HEIGHT; + + private DefaultSingleSelectionModel selectionModel; + private SelectionActionListener selectionListener = new SelectionActionListener(); + + public StepComponent() { + this(DRIFT, BRD, HEIGHT); + } + + public StepComponent(int drift, int borderWidth, int height) { +// super(new FlowLayout(FlowLayout.CENTER, -2*drift, 0)); + super(new StepComponentLayout(drift)); + this.drift = drift; + this.borderWidth = borderWidth; + this.buttonHeight = height; + setOpaque(false); + this.selectionModel = new DefaultSingleSelectionModel(); + } + + public void addStep(String title, String text) { + addButton(new StepButton(title, text, drift, borderWidth, buttonHeight)); + } + + public void addFirst(String title, String text) { + addButton(new StepButton(title, text, drift, borderWidth, buttonHeight, true, false)); + } + + public void addLast(String title, String text) { + addButton(new StepButton(title, text, drift, borderWidth, buttonHeight, false, true)); + } + + private void addButton(StepButton button) { + bg.add(button); + buttons.add(button); + add(button); + button.addActionListener(selectionListener); + } + + public String getSelectedStep() { + int index = selectionModel.getSelectedIndex(); + if (index < 0) return null; + return buttons.get(index).getActionCommand(); + } + + public void setSelectedStep(String actionCommand) { + for(int i=0; i 0) { + ncols = (ncomponents + nrows - 1) / nrows; + } else { + nrows = (ncomponents + ncols - 1) / ncols; + } + int w = 0; + int h = 0; + for (int i = 0 ; i < ncomponents ; i++) { + Component comp = parent.getComponent(i); + Dimension d = comp.getPreferredSize(); + if (w < d.width) { + w = d.width; + } + if (h < d.height) { + h = d.height; + } + } + return new Dimension(insets.left + insets.right + ncols*w + (ncols)*hgap, + insets.top + insets.bottom + nrows*h + (nrows-1)*vgap); + } + } + + public Dimension minimumLayoutSize(Container parent) { +// synchronized (parent.getTreeLock()) { +// Insets insets = parent.getInsets(); +// int ncomponents = parent.getComponentCount(); +// int nrows = rows; +// int ncols = cols; +// +// if (nrows > 0) { +// ncols = (ncomponents + nrows - 1) / nrows; +// } else { +// nrows = (ncomponents + ncols - 1) / ncols; +// } +// int w = 0; +// int h = 0; +// for (int i = 0 ; i < ncomponents ; i++) { +// Component comp = parent.getComponent(i); +// Dimension d = comp.getMinimumSize(); +// if (w < d.width) { +// w = d.width; +// } +// if (h < d.height) { +// h = d.height; +// } +// } +// return new Dimension(insets.left + insets.right + ncols*w + (ncols)*hgap, +// insets.top + insets.bottom + nrows*h + (nrows-1)*vgap); +// } + return new Dimension(); + } + + public void layoutContainer(Container parent) { + synchronized (parent.getTreeLock()) { + Insets insets = parent.getInsets(); + int ncomponents = parent.getComponentCount(); + int nrows = rows; + int ncols = cols; + boolean ltr = parent.getComponentOrientation().isLeftToRight(); + + if (ncomponents == 0) { + return; + } + if (nrows > 0) { + ncols = (ncomponents + nrows - 1) / nrows; + } else { + nrows = (ncomponents + ncols - 1) / ncols; + } + + int w = parent.getWidth() - (insets.left + insets.right); + int h = parent.getHeight() - (insets.top + insets.bottom); + w = (w - (ncols) * hgap) / ncols; + h = (h - (nrows) * vgap) / nrows; + + if (ltr) { + for (int c = 0, x = insets.left ; c < ncols ; c++, x += w + hgap) { + for (int r = 0, y = insets.top ; r < nrows ; r++, y += h + vgap) { + int i = r * ncols + c; + if (i < ncomponents) { + if (i == 0) {//first + parent.getComponent(i).setBounds(x, y, w+hgap, h); + x += hgap; +// } else if (i == ncomponents-1) {//last +// parent.getComponent(i).setBounds(x, y, w+hgap, h); + } else { + parent.getComponent(i).setBounds(x, y, w, h); + } + } + } + } + } else { + for (int c = 0, x = parent.getWidth() - insets.right - w; c < ncols ; c++, x -= w + hgap) { + for (int r = 0, y = insets.top ; r < nrows ; r++, y += h + vgap) { + int i = r * ncols + c; + if (i < ncomponents) { + parent.getComponent(i).setBounds(x, y, w, h); + } + } + } + } + } + } + + /** + * Returns the string representation of this grid layout's values. + * @return a string representation of this grid layout + */ + public String toString() { + return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + + ",rows=" + rows + ",cols=" + cols + "]"; + } +} diff --git a/src/eu/engys/util/ui/textfields/AdaptativeFormat.java b/src/eu/engys/util/ui/textfields/AdaptativeFormat.java new file mode 100644 index 0000000..85fdc27 --- /dev/null +++ b/src/eu/engys/util/ui/textfields/AdaptativeFormat.java @@ -0,0 +1,67 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields; + +import java.text.FieldPosition; +import java.text.NumberFormat; +import java.text.ParsePosition; + +public class AdaptativeFormat extends NumberFormat { + + private NumberFormat f1; + private NumberFormat f2; + + private double lowThreshold; + private double highThreshold; + + public AdaptativeFormat(NumberFormat f1, NumberFormat f2, int decimalPlaces) { + this.f1 = f1; + this.f2 = f2; + + this.lowThreshold = Math.pow(10, -decimalPlaces); + this.highThreshold = Math.pow(10, decimalPlaces); + } + + @Override + public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) { + return useFirstFormat(number) ? f1.format(number, toAppendTo, pos) : f2.format(number, toAppendTo, pos); + } + + @Override + public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) { + return useFirstFormat(number) ? f1.format(number, toAppendTo, pos) : f2.format(number, toAppendTo, pos); + } + + @Override + public Number parse(String source, ParsePosition parsePosition) { + return f1.parse(source.replace('e', 'E'), parsePosition); + } + + private boolean useFirstFormat(double number) { + return number == 0 || (Math.abs(number) > lowThreshold && Math.abs(number) < highThreshold); + } +} diff --git a/src/eu/engys/util/ui/textfields/DoubleField.java b/src/eu/engys/util/ui/textfields/DoubleField.java new file mode 100644 index 0000000..2f44638 --- /dev/null +++ b/src/eu/engys/util/ui/textfields/DoubleField.java @@ -0,0 +1,245 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields; + +import java.awt.Font; +import java.awt.Insets; +import java.beans.Transient; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +import javax.swing.text.DefaultFormatterFactory; +import javax.swing.text.NumberFormatter; + +import eu.engys.util.ui.textfields.verifiers.DoubleVerifier; + +/** + * Provides a JFormattedTextField that accepts only doubles. Allows for the setting of the number + * of decimal places displayed, and min/max values allowed. + * + * See also + * https://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html + * http://stackoverflow.com/a/12978182 + * http://www.javalobby.org/java/forums/t20551.html + * + */ +public class DoubleField extends PromptTextField { + + private static final DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(Locale.US); + + public static final int DEFAULT_PLACES = 10; + + private double minValue = -Double.MAX_VALUE; + private double maxValue = Double.MAX_VALUE; + + private DefaultFormatterFactory factory; + private DoubleVerifier verifier; + + private Font normalFont; + private Font nonuniformFont; + + private Double defaultValue; + + public DoubleField(Insets insets) { + super(insets); + } + + public DoubleField() { + this(-Double.MAX_VALUE, Double.MAX_VALUE, Double.valueOf(0), DEFAULT_PLACES); + } + + public DoubleField(int places) { + this(-Double.MAX_VALUE, Double.MAX_VALUE, Double.valueOf(0), places); + } + + public DoubleField(double min, double max) throws IllegalArgumentException { + this(min, max, Double.valueOf(0), DEFAULT_PLACES); + } + + public DoubleField(double min, double max, Double value) throws IllegalArgumentException { + this(min, max, value, DEFAULT_PLACES); + } + + public DoubleField(double min, double max, Double value, int places) throws IllegalArgumentException { + this.defaultValue = value; + this.minValue = min; + this.maxValue = max; + this.verifier = new DoubleVerifier(this, min, max); + + setValue(value); + setInputVerifier(verifier); + + NumberFormatter def = new NullableNumberFormatter(); + def.setValueClass(Double.class); + def.setMinimum(minValue); + def.setMaximum(maxValue); + + NumberFormatter displayFormatter = new NullableNumberFormatter(getFormatForDISPLAY(places)); + displayFormatter.setValueClass(Double.class); + displayFormatter.setMinimum(minValue); + displayFormatter.setMaximum(maxValue); + + NumberFormatter editFormatter = new NullableNumberFormatter(getFormatForEDIT(places)); + editFormatter.setValueClass(Double.class); + editFormatter.setMinimum(minValue); + editFormatter.setMaximum(maxValue); + + this.factory = new DefaultFormatterFactory(def, displayFormatter, editFormatter); + setFormatterFactory(factory); + + this.normalFont = super.getFont(); + this.nonuniformFont = super.getFont().deriveFont(Font.ITALIC); + + setColumns(NUMBER_FIELD_COLUMNS); + } + + public static AdaptativeFormat getFormatForDISPLAY(int places) { + return new AdaptativeFormat(new DoubleDisplayFormat(places), new DoubleScientificFormat(places), places); + } + + private static AdaptativeFormat getFormatForEDIT(int places) { + return new AdaptativeFormat(new DoubleEditFormat(places), new DoubleScientificFormat(places), places); + } + + @Override + @Transient + public Font getFont() { + if (nonuniformFont != null && getText().equals(DoubleVerifier.NONUNIFORM)) + return nonuniformFont; + else if (normalFont != null) + return normalFont; + + return super.getFont(); + } + + @Override + protected void invalidEdit() { + } + + /* + * If you write by hand something like 1.2E+06 the formatter does not like it. It requires no + sign + */ + @Override + public String getText() { + return super.getText().replace('e', 'E').replace("E+", "E"); + } + + /* + * If you prompt something like 1.2E+06 the formatter does not like it. It requires no + sign + */ + @Override + protected String getFixedinputString(String content) { + return content.replace('e', 'E').replace("E+", "E"); + } + + public void setDoubleValue(double value) { + super.setValue(Double.valueOf(value)); + } + + public double getDoubleValue() { + Object value = super.getValue(); + if (value != null && value instanceof Double) { + return ((Double) value).doubleValue(); + } + return Double.NaN; + } + + public Double getDefaultValue() { + return defaultValue; + } + + public double getMinValue() { + return minValue; + } + + public double getMaxValue() { + return maxValue; + } + + public void setMinValue(double minValue) { + this.minValue = minValue; + verifier.setMinValue(minValue); + } + + public void setMaxValue(double maxValue) { + this.maxValue = maxValue; + verifier.setMaxValue(maxValue); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[" +(getName() != null ? getName() : "noname" ) + "] value: " + String.valueOf(getDoubleValue()); + } + + public static double[] toArray(DoubleField[] field) { + double[] value = new double[field.length]; + for (int i = 0; i < value.length; i++) { + value[i] = field[i].getDoubleValue(); + } + return value; + } + + public static class DoubleDisplayFormat extends DecimalFormat { + public DoubleDisplayFormat(int places) { + super(); + setDecimalFormatSymbols(decimalFormatSymbols); + setMinimumIntegerDigits(1); + setMaximumIntegerDigits(Integer.MAX_VALUE); + setMinimumFractionDigits(1); + setMaximumFractionDigits(places); + setParseIntegerOnly(false); + setGroupingUsed(true); + } + } + + public static class DoubleEditFormat extends DecimalFormat { + public DoubleEditFormat(int places) { + super(); + setDecimalFormatSymbols(decimalFormatSymbols); + setMinimumIntegerDigits(1); + setMaximumIntegerDigits(Integer.MAX_VALUE); + setMinimumFractionDigits(0); + setMaximumFractionDigits(places); + setParseIntegerOnly(false); + setGroupingUsed(false); + } + } + + public static class DoubleScientificFormat extends DecimalFormat { + public DoubleScientificFormat(int places) { + super("#.#E0##"); + setDecimalFormatSymbols(decimalFormatSymbols); + setMinimumIntegerDigits(1); + setMaximumIntegerDigits(1); + setMinimumFractionDigits(0); + setMaximumFractionDigits(places); + setParseIntegerOnly(false); + setGroupingUsed(false); + } + } +} diff --git a/src/eu/engys/util/ui/textfields/FileTextField.java b/src/eu/engys/util/ui/textfields/FileTextField.java new file mode 100644 index 0000000..4ddba9f --- /dev/null +++ b/src/eu/engys/util/ui/textfields/FileTextField.java @@ -0,0 +1,80 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields; + +import java.io.File; +import java.text.ParseException; + +import javax.swing.text.DefaultFormatter; +import javax.swing.text.DefaultFormatterFactory; + +import eu.engys.util.ui.textfields.verifiers.FileVerifier; + +public class FileTextField extends PromptTextField { + + public FileTextField() { + super(); + setFormatterFactory(new DefaultFormatterFactory(new FileFormatter())); + setInputVerifier(new FileVerifier(this)); + setColumns(STRING_FIELD_COLUMNS); + } + + @Override + public File getValue() { + return (File) super.getValue(); + } + + public void setValue(File file) { + super.setValue(file); + ((FileVerifier) getInputVerifier()).verify(this); + } + + public boolean hasValidFile() { + return ((FileVerifier) getInputVerifier()).verify(this); + } + + private static class FileFormatter extends DefaultFormatter { + public FileFormatter() { + super(); + setValueClass(File.class); + } + + @Override + public Object stringToValue(String string) throws ParseException { + return string.isEmpty() ? null : new File(string); + } + + @Override + public String valueToString(Object value) throws ParseException { + if (value == null) { + return ""; + } + return File.class.cast(value).getPath(); + } + } + +} diff --git a/src/eu/engys/util/ui/textfields/IntegerField.java b/src/eu/engys/util/ui/textfields/IntegerField.java new file mode 100644 index 0000000..21e0e2c --- /dev/null +++ b/src/eu/engys/util/ui/textfields/IntegerField.java @@ -0,0 +1,153 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields; + +import java.awt.Insets; +import java.io.Serializable; +import java.text.DecimalFormat; + +import javax.swing.text.DefaultFormatterFactory; +import javax.swing.text.NumberFormatter; + +import eu.engys.util.ui.textfields.verifiers.IntegerVerifier; +/** + * Provides a JFormattedTextField that accepts only integers. + * Allows for the setting of the min/max values allowed. + * + * See also + * https://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html + * http://stackoverflow.com/a/12978182 + * + */ +public class IntegerField extends PromptTextField implements Serializable { + + private int minValue = -Integer.MAX_VALUE; + private int maxValue = Integer.MAX_VALUE; + + private DefaultFormatterFactory dff; + private IntegerVerifier verifier; + + public IntegerField(Insets insets) { + super(insets); + } + + public IntegerField() { + this(-Integer.MAX_VALUE, Integer.MAX_VALUE, 0, false); + } + + public IntegerField(int min, int max) throws IllegalArgumentException { + this(min, max, 0 < min ? min : 0, false); + } + + public IntegerField(int min, int max, int value) throws IllegalArgumentException { + this(min, max, value, false); + } + + public IntegerField(int min, int max, int value, boolean checkEmptyValue) throws IllegalArgumentException { + this.minValue = min; + this.maxValue = max; + this.verifier = new IntegerVerifier(this, min, max, checkEmptyValue); + + setValue(new Integer(value)); + setInputVerifier(verifier); + setColumns(NUMBER_FIELD_COLUMNS); + + NumberFormatter def = new NullableNumberFormatter(); + def.setValueClass(Integer.class); + def.setMinimum(minValue); + def.setMaximum(maxValue); + + NumberFormatter disp = new NullableNumberFormatter(new IntegerDisplayFormat()); + disp.setValueClass(Integer.class); + disp.setMinimum(minValue); + disp.setMaximum(maxValue); + + NumberFormatter ed = new NullableNumberFormatter(new IntegerEditFormat()); + ed.setValueClass(Integer.class); + ed.setMinimum(minValue); + ed.setMaximum(maxValue); + + dff = new DefaultFormatterFactory(def, disp, ed); + setFormatterFactory(dff); + } + + public void setIntValue(int value) { + super.setValue(Integer.valueOf(value)); + } + + public int getIntValue() { + Object value = super.getValue(); + if (value != null && value instanceof Integer) { + return ((Integer) super.getValue()).intValue(); + } + return 0; + } + + public double getMinValue() { + return minValue; + } + + public double getMaxValue() { + return maxValue; + } + + public void setMinValue(int minValue) { + this.minValue = minValue; + verifier.setMinValue(minValue); + } + + public void setMaxValue(int maxValue) { + this.maxValue = maxValue; + verifier.setMaxValue(maxValue); + } + + public static class IntegerDisplayFormat extends DecimalFormat { + public IntegerDisplayFormat() { + super(); + setMinimumIntegerDigits(1); + setMaximumIntegerDigits(Integer.MAX_VALUE); + setMinimumFractionDigits(0); + setMaximumFractionDigits(0); + setParseIntegerOnly(true); + setGroupingUsed(true); + + } + } + + public static class IntegerEditFormat extends DecimalFormat { + public IntegerEditFormat() { + super(); + setMinimumIntegerDigits(0); + setMaximumIntegerDigits(Integer.MAX_VALUE); + setMinimumFractionDigits(0); + setMaximumFractionDigits(0); + setParseIntegerOnly(true); + setGroupingUsed(false); + + } + } +} diff --git a/src/eu/engys/util/ui/textfields/NullableNumberFormatter.java b/src/eu/engys/util/ui/textfields/NullableNumberFormatter.java new file mode 100644 index 0000000..8533f5f --- /dev/null +++ b/src/eu/engys/util/ui/textfields/NullableNumberFormatter.java @@ -0,0 +1,61 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields; + +import java.text.NumberFormat; +import java.text.ParseException; + +import javax.swing.text.NumberFormatter; + +import eu.engys.util.ui.textfields.verifiers.DoubleVerifier; + +public class NullableNumberFormatter extends NumberFormatter { + + public NullableNumberFormatter() { + super(); + } + + public NullableNumberFormatter(NumberFormat format) { + super(format); + } + + public Object stringToValue(String string) throws ParseException { + if (string == null || string.length() == 0) { + return null; + } + if (string.equals(DoubleVerifier.NONUNIFORM)) { + return Double.POSITIVE_INFINITY;//super.stringToValue("Infinity"); + } + return super.stringToValue(string); + } + + public String valueToString(Object value) throws ParseException { + if ( value == null ) return ""; + if ( value instanceof Double && Double.isInfinite((Double) value)) return DoubleVerifier.NONUNIFORM; + return super.valueToString(value); + } +} diff --git a/src/eu/engys/util/ui/textfields/PromptTextField.java b/src/eu/engys/util/ui/textfields/PromptTextField.java new file mode 100644 index 0000000..6cbeca1 --- /dev/null +++ b/src/eu/engys/util/ui/textfields/PromptTextField.java @@ -0,0 +1,156 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ +package eu.engys.util.ui.textfields; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.RenderingHints; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.text.ParseException; + +import javax.swing.JFormattedTextField; +import javax.swing.KeyStroke; +import javax.swing.UIManager; +import javax.swing.text.DefaultFormatterFactory; + +import eu.engys.util.ui.ExecUtil; + +/** + * PropmptTextField add the ability to display a message on the + * text field when not focused and a value is not set. + * + * Auto-select the text when focused + * See + * + */ +public class PromptTextField extends JFormattedTextField { + + public static final Color HIGHLIGHT_FG = new Color(65, 90, 110); + public static final Color HIGHLIGHT_BG = new Color(130, 180, 220, 128); + private static final Color DEFAULT_FG = UIManager.getColor("TextField.foreground"); + private static final Color DEFAULT_BG = UIManager.getColor("TextField.background"); + private static final Color INVALID_COLOR = Color.PINK; + + public static final int NUMBER_FIELD_COLUMNS = 4; + public static final int STRING_FIELD_COLUMNS = 10; + + private String prompt = ""; + + public PromptTextField() { + super(); + } + + public PromptTextField(Insets insets) { + this(); + setMargin(insets); + } + + public void setPrompt(String prompt) { + this.prompt = prompt; + } + + public void setValidColors() { + setBackground(DEFAULT_BG); + setForeground(DEFAULT_FG); + } + + public void setInvalidColors() { + setBackground(INVALID_COLOR); + setForeground(DEFAULT_FG); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + + if (!hasFocus() && getText().isEmpty() && !prompt.isEmpty()) { + Graphics2D g2 = (Graphics2D) g; + + Object aa = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setColor(Color.GRAY.brighter()); + g2.drawString(prompt, 4, getFontMetrics(getFont()).getHeight()); + + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aa); + } + } + + @Override + protected void processFocusEvent(final FocusEvent e) { + super.processFocusEvent(e); + + if (e.isTemporary()) { + return; + } + + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + if (e.getID() == FocusEvent.FOCUS_GAINED) { + selectAll(); + } else { + getCaret().setDot(getCaretPosition()); + } + } + }); + } + + @Override + public boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { + return super.processKeyBinding(ks, e, condition, pressed); + } + + @Override + public void replaceSelection(String content) { + String s = content; + AbstractFormatterFactory formatterFactory = getFormatterFactory(); + if (formatterFactory != null && formatterFactory instanceof DefaultFormatterFactory) { + DefaultFormatterFactory factory = (DefaultFormatterFactory) formatterFactory; + AbstractFormatter displayFormat = factory.getDisplayFormatter(); + AbstractFormatter editFormat = factory.getEditFormatter(); + if (displayFormat != null && editFormat != null) { + try { + Object value = displayFormat.stringToValue(getFixedinputString(content)); + s = editFormat.valueToString(value); + } catch (ParseException e) { + } + } + } else { + } + super.replaceSelection(s); + } + + /* + * The string may need a fix. See DoubleField + */ + protected String getFixedinputString(String content) { + String s = content; + return s; + } +} diff --git a/src/eu/engys/util/ui/textfields/SpinnerField.java b/src/eu/engys/util/ui/textfields/SpinnerField.java new file mode 100644 index 0000000..33c21ff --- /dev/null +++ b/src/eu/engys/util/ui/textfields/SpinnerField.java @@ -0,0 +1,86 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields; + +import java.io.Serializable; + +import javax.swing.JFormattedTextField; +import javax.swing.JSpinner; +import javax.swing.SpinnerNumberModel; +import javax.swing.text.DefaultFormatterFactory; +import javax.swing.text.NumberFormatter; + +public class SpinnerField extends JSpinner implements Serializable { + + + public SpinnerField() { + this(-Integer.MAX_VALUE, Integer.MAX_VALUE, 0); + } + + public SpinnerField(int min, int max) throws IllegalArgumentException { + this(min, max, 0 < min ? min : 0); + } + + public SpinnerField(int min, int max, int value) throws IllegalArgumentException { + super(new SpinnerNumberModel(value, min, max, 1)); + + JFormattedTextField textField = ((JSpinner.DefaultEditor)getEditor()).getTextField(); + + NumberFormatter def = new NullableNumberFormatter(); + def.setValueClass(Integer.class); + def.setMinimum(min); + def.setMaximum(max); + + NumberFormatter disp = new NullableNumberFormatter(new IntegerField.IntegerDisplayFormat()); + disp.setValueClass(Integer.class); + disp.setMinimum(min); + disp.setMaximum(max); + + NumberFormatter ed = new NullableNumberFormatter(new IntegerField.IntegerEditFormat()); + ed.setValueClass(Integer.class); + ed.setMinimum(min); + ed.setMaximum(max); + + DefaultFormatterFactory dff = new DefaultFormatterFactory(def, disp, ed); + textField.setFormatterFactory(dff); + + textField.setColumns(4); + } + + public void setIntValue(int value) { + super.setValue(Integer.valueOf(value)); + } + + public int getIntValue() { + Object value = super.getValue(); + if (value != null && value instanceof Integer) { + return ((Integer) super.getValue()).intValue(); + } + return 0; + } + +} diff --git a/src/eu/engys/util/ui/textfields/StringField.java b/src/eu/engys/util/ui/textfields/StringField.java new file mode 100644 index 0000000..25b3ce9 --- /dev/null +++ b/src/eu/engys/util/ui/textfields/StringField.java @@ -0,0 +1,94 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields; + +import java.text.ParseException; + +import javax.swing.text.DefaultFormatterFactory; + +import eu.engys.util.ui.textfields.verifiers.StringVerifier; +/** + * Provides a JFormattedTextField that accepts only Strings. + */ +public class StringField extends PromptTextField { + + public StringField() { + this(""); + } + + public StringField(boolean checkEmptyStrings, boolean checkForbidden) { + this("", checkEmptyStrings, checkForbidden); + } + + public StringField(String text, boolean checkEmptyStrings, boolean checkForbidden) { + this(text, -1, checkEmptyStrings, checkForbidden); + } + + public StringField(String text) { + this(text, -1, true, true); + } + + public StringField(int columns) { + this("", columns, true, true); + } + + public StringField(String text, int columns, boolean checkEmptyStrings, boolean checkForbidden) { + super(); + setFormatterFactory(new DefaultFormatterFactory(new StringFormatter())); + setText(text); + setInputVerifier(new StringVerifier(this)); + setColumns(columns != -1 ? columns : STRING_FIELD_COLUMNS); + setToVerifier(checkEmptyStrings, checkForbidden); + } + + public void setStringValue(String value) { + super.setValue(value); + } + + public String getStringValue() { + return (String) super.getValue(); + } + + public void setToVerifier(boolean checkEmptyStrings, boolean checkForbidden) { + ((StringVerifier) getInputVerifier()).setCheckEmptyStrings(checkEmptyStrings); + ((StringVerifier) getInputVerifier()).setCheckForbidden(checkForbidden); + } + + class StringFormatter extends AbstractFormatter { + @Override + public Object stringToValue(String text) throws ParseException { + return text; + } + + @Override + public String valueToString(Object value) throws ParseException { + return value != null ? value.toString() : ""; + } + } + +} + diff --git a/src/eu/engys/util/ui/textfields/verifiers/AbstractVerifier.java b/src/eu/engys/util/ui/textfields/verifiers/AbstractVerifier.java new file mode 100644 index 0000000..9a2909b --- /dev/null +++ b/src/eu/engys/util/ui/textfields/verifiers/AbstractVerifier.java @@ -0,0 +1,158 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields.verifiers; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.text.ParseException; + +import javax.swing.BorderFactory; +import javax.swing.InputVerifier; +import javax.swing.JComponent; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JPopupMenu; +import javax.swing.JTextField; + +import eu.engys.util.ui.textfields.PromptTextField; + +/** + * See Building a Swing Validation Package with InputVerifier + * http://www.javalobby.org/java/forums/t20551.html + * + */ +public abstract class AbstractVerifier extends InputVerifier implements KeyListener { + + protected static final Color BG_COLOR = new Color(243, 255, 159); + + private final JPopupMenu popup = new JPopupMenu(); + + private JLabel messageLabel = new JLabel(); + private ValidationStatusListener listener; + private PromptTextField jcomponent; + + public AbstractVerifier(PromptTextField c) { + this.jcomponent = c; + initComponents(); + c.addKeyListener(this); + } + + private void initComponents() { + popup.setLayout(new FlowLayout()); + popup.setBorder(BorderFactory.createEmptyBorder()); + popup.setBackground(BG_COLOR); + popup.add(messageLabel); + } + + protected abstract boolean validationCriteria(JComponent jc); + + public boolean verify(JComponent jc) { + if (!validationCriteria(jc)) { + + if (listener != null) + listener.validateFailed(); + + invalid(); + return false; + } + + valid(); + + if (jcomponent instanceof JFormattedTextField) { + try { + ((JFormattedTextField) jcomponent).commitEdit(); + } catch (ParseException e) { + } + } + + if (listener != null) + listener.validatePassed(); + + return true; + } + + private void invalid() { + if (jcomponent.isShowing()) { + jcomponent.setInvalidColors(); + + popup.setSize(0, 0); + Point point = jcomponent.getLocation(); + Dimension cDim = jcomponent.getSize(); + popup.pack(); + popup.show(jcomponent, point.x - (int) cDim.getWidth() / 2, point.y + (int) cDim.getHeight() / 2); + jcomponent.requestFocus(); + } else { + // Moved to another tab (or similar) + // valid(); + jcomponent.setInvalidColors(); + } + } + + private void valid() { + jcomponent.setValidColors(); + popup.setVisible(false); + } + + public void setMessage(String text) { + messageLabel.setText(text); + } + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + popup.setVisible(false); + JTextField source = (JTextField) e.getSource(); + if (e.getKeyChar() == KeyEvent.VK_ENTER) { + verify(source); // ignore return value + source.selectAll(); + } else if (e.getKeyChar() == KeyEvent.VK_ESCAPE) { + verify(source); // ignore return value + source.selectAll(); + } + } + + public void setValidationStatusListener(ValidationStatusListener listener) { + this.listener = listener; + } + + public interface ValidationStatusListener { + void validateFailed(); // Called when a component has failed validation. + + void validatePassed(); // Called when a component has passed validation. + } +} diff --git a/src/eu/engys/util/ui/textfields/verifiers/DoubleVerifier.java b/src/eu/engys/util/ui/textfields/verifiers/DoubleVerifier.java new file mode 100644 index 0000000..a38cf7c --- /dev/null +++ b/src/eu/engys/util/ui/textfields/verifiers/DoubleVerifier.java @@ -0,0 +1,74 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields.verifiers; + +import javax.swing.JComponent; +import javax.swing.text.JTextComponent; + +import eu.engys.util.ui.textfields.DoubleField; + +public class DoubleVerifier extends AbstractVerifier { + public static final String NONUNIFORM = "Nonuniform"; + + protected double minValue = -Double.MAX_VALUE; + protected double maxValue = Double.MAX_VALUE; + + public DoubleVerifier(DoubleField c, double min, double max) { + super(c); + this.minValue = min; + this.maxValue = max; + } + + @Override + protected boolean validationCriteria(JComponent jc) { + try { + String text = ((JTextComponent) jc).getText(); + if (text == null || text.isEmpty()) return true; + + if (text.equals(NONUNIFORM)) return true; + + double val = Double.parseDouble(text); + if (val < minValue || val > maxValue) { + setMessage("Value outside range ["+minValue+", "+maxValue+"]"); + return false; + } + } catch (Exception e) { + setMessage("Invalid number format"); + return false; + } + return true; + } + + public void setMinValue(double value) { + this.minValue = value; + } + + public void setMaxValue(double value) { + this.maxValue = value; + } + +} diff --git a/src/eu/engys/util/ui/textfields/verifiers/FileVerifier.java b/src/eu/engys/util/ui/textfields/verifiers/FileVerifier.java new file mode 100644 index 0000000..8994f85 --- /dev/null +++ b/src/eu/engys/util/ui/textfields/verifiers/FileVerifier.java @@ -0,0 +1,57 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields.verifiers; + +import java.io.File; + +import javax.swing.JComponent; +import javax.swing.JTextField; + +import eu.engys.util.ui.textfields.PromptTextField; + +public class FileVerifier extends AbstractVerifier { + + public FileVerifier(PromptTextField c) { + super(c); + } + + @Override + protected boolean validationCriteria(JComponent jc) { + try { + String text = ((JTextField) jc).getText(); + if (!text.isEmpty() && !new File(text).exists()) { + setMessage("File does not exist"); + return false; + } + + } catch (Exception e) { + setMessage("Error parsing string"); + return false; + } + return true; + } +} diff --git a/src/eu/engys/util/ui/textfields/verifiers/IntegerVerifier.java b/src/eu/engys/util/ui/textfields/verifiers/IntegerVerifier.java new file mode 100644 index 0000000..37a24a6 --- /dev/null +++ b/src/eu/engys/util/ui/textfields/verifiers/IntegerVerifier.java @@ -0,0 +1,82 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields.verifiers; + +import javax.swing.JComponent; +import javax.swing.JTextField; + +import eu.engys.util.ui.textfields.IntegerField; + +public class IntegerVerifier extends AbstractVerifier { + + private boolean checkEmptyStrings = true; + + protected int minValue = -Integer.MAX_VALUE; + protected int maxValue = Integer.MAX_VALUE; + + public IntegerVerifier(IntegerField c, int min, int max, boolean checkEmptyStrings) { + super(c); + this.checkEmptyStrings = checkEmptyStrings; + this.minValue = min; + this.maxValue = max; + } + + @Override + protected boolean validationCriteria(JComponent jc) { + try { + String text = ((JTextField) jc).getText(); + if (text == null || text.isEmpty()) { + if (checkEmptyStrings) { + setMessage("Empty value"); + return false; + } + return true; + } + + double d = Double.parseDouble(text); + if (d < minValue || d > maxValue) { + setMessage("Value outside range [" + minValue + ", " + maxValue + "]"); + return false; + } + + Integer.parseInt(text); + } catch (Exception e) { + setMessage("Invalid number format"); + return false; + } + return true; + } + + public void setMinValue(int minValue) { + this.minValue = minValue; + } + + public void setMaxValue(int maxValue) { + this.maxValue = maxValue; + } + +} diff --git a/src/eu/engys/util/ui/textfields/verifiers/StringVerifier.java b/src/eu/engys/util/ui/textfields/verifiers/StringVerifier.java new file mode 100644 index 0000000..8a7f849 --- /dev/null +++ b/src/eu/engys/util/ui/textfields/verifiers/StringVerifier.java @@ -0,0 +1,76 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.textfields.verifiers; + +import javax.swing.JComponent; +import javax.swing.JTextField; + +import eu.engys.util.Util; +import eu.engys.util.ui.textfields.PromptTextField; + +public class StringVerifier extends AbstractVerifier { + + private boolean checkEmptyStrings = true; + private boolean checkForbidden = true; + + public StringVerifier(PromptTextField c) { + super(c); + } + + @Override + protected boolean validationCriteria(JComponent jc) { + try { + String text = ((JTextField) jc).getText(); + + if ( checkEmptyStrings && (text == null || text.isEmpty())){ + setMessage("Empty name"); + return false; + } + + if (checkForbidden) { + for (char ch : text.toCharArray()) { + if (Util.isForbidden(ch)) { + setMessage("Illegal charachter: " + ch); + return false; + } + } + } + } catch (Exception e) { + setMessage("Error parsing string"); + return false; + } + return true; + } + + public void setCheckEmptyStrings(boolean b) { + this.checkEmptyStrings = b; + } + + public void setCheckForbidden(boolean checkForbidden) { + this.checkForbidden = checkForbidden; + } +} diff --git a/src/eu/engys/util/ui/treetable/AbstractTreeTableModel.java b/src/eu/engys/util/ui/treetable/AbstractTreeTableModel.java new file mode 100644 index 0000000..1ae1680 --- /dev/null +++ b/src/eu/engys/util/ui/treetable/AbstractTreeTableModel.java @@ -0,0 +1,129 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.treetable; + +import javax.swing.event.EventListenerList; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreePath; + +public abstract class AbstractTreeTableModel implements TreeTableModel { + protected Object root; + protected EventListenerList listenerList = new EventListenerList(); + + public AbstractTreeTableModel(Object root) { + this.root = root; + } + + public Object getRoot() { + return root; + } + + public boolean isLeaf(Object node) { + return getChildCount(node) == 0; + } + + public void valueForPathChanged(TreePath path, Object newValue) { + } + + public int getIndexOfChild(Object parent, Object child) { + for (int i = 0; i < getChildCount(parent); i++) { + if (getChild(parent, i).equals(child)) { + return i; + } + } + return -1; + } + + public void addTreeModelListener(TreeModelListener l) { + listenerList.add(TreeModelListener.class, l); + } + + public void removeTreeModelListener(TreeModelListener l) { + listenerList.remove(TreeModelListener.class, l); + } + + protected void fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children) { + Object[] listeners = listenerList.getListenerList(); + TreeModelEvent e = null; + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == TreeModelListener.class) { + if (e == null) + e = new TreeModelEvent(source, path, childIndices, children); + ((TreeModelListener) listeners[i + 1]).treeNodesChanged(e); + } + } + } + + protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) { + Object[] listeners = listenerList.getListenerList(); + TreeModelEvent e = null; + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == TreeModelListener.class) { + if (e == null) + e = new TreeModelEvent(source, path, childIndices, children); + ((TreeModelListener) listeners[i + 1]).treeNodesInserted(e); + } + } + } + + protected void fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children) { + Object[] listeners = listenerList.getListenerList(); + TreeModelEvent e = null; + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == TreeModelListener.class) { + if (e == null) + e = new TreeModelEvent(source, path, childIndices, children); + ((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e); + } + } + } + + protected void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children) { + Object[] listeners = listenerList.getListenerList(); + TreeModelEvent e = null; + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == TreeModelListener.class) { + if (e == null) + e = new TreeModelEvent(source, path, childIndices, children); + ((TreeModelListener) listeners[i + 1]).treeStructureChanged(e); + } + } + } + + public Class getColumnClass(int column) { + return Object.class; + } + + public boolean isCellEditable(Object node, int column) { + return getColumnClass(column) == TreeTableModel.class; + } + + public void setValueAt(Object aValue, Object node, int column) { + } + +} diff --git a/src/eu/engys/util/ui/treetable/JTreeTable.java b/src/eu/engys/util/ui/treetable/JTreeTable.java new file mode 100644 index 0000000..3f52545 --- /dev/null +++ b/src/eu/engys/util/ui/treetable/JTreeTable.java @@ -0,0 +1,196 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.treetable; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.util.EventObject; + +import javax.swing.JTable; +import javax.swing.JTree; +import javax.swing.table.TableRowSorter; + +import eu.engys.util.ui.TableUtil; +import eu.engys.util.ui.treetable.tree.JTreeTableCellRenderer; +import eu.engys.util.ui.treetable.tree.ListToTreeSelectionModelWrapper; +import eu.engys.util.ui.treetable.tree.TreeTableCellRenderer; + +public class JTreeTable extends JTable { + + private TreeTableCellRenderer tree; + + private boolean treeEditable = true; + private boolean showsIcons = false; + + private TableRowSorter sorter; + private TableFilter filter; + + public JTreeTable(TreeTableModel treeTableModel) { + super(); + + this.tree = new TreeTableCellRenderer(this, treeTableModel); + + TreeTableModelAdapter dataModel = new TreeTableModelAdapter(treeTableModel, tree); + super.setModel(dataModel); + + this.sorter = new TableRowSorter(dataModel); + setRowSorter(sorter); + + TableUtil.disableSorting(this); + + this.filter = new TableFilter(""); + sorter.setRowFilter(filter); + + ListToTreeSelectionModelWrapper selectionWrapper = new ListToTreeSelectionModelWrapper(tree); + tree.setSelectionModel(selectionWrapper); + setSelectionModel(selectionWrapper.getListSelectionModel()); + + setDefaultRenderer(TreeTableModel.class, tree); + setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor(this)); + + setShowGrid(false); + + setIntercellSpacing(new Dimension(0, 0)); + + if (tree.getRowHeight() < 1) { + setRowHeight(20); + } + + } + + public void setSearchableColumns(int... searchableColumns) { + filter.setColumnsWhereToSearch(searchableColumns); + } + + public void filter(final String filterText) { + filter.setFilterText(filterText); + sorter.sort(); + } + + public void removeRow(int row) { + ((TreeTableModelAdapter) getModel()).removeRow(row); + } + + public Object[] getNodes(int[] index) { + Object[] nodes = new Object[index.length]; + for (int i = 0; i < index.length; i++) { + nodes[i] = ((TreeTableModelAdapter) getModel()).nodeForRow(index[i]); + } + return nodes; + } + + public Object getNode(int index) { + return ((TreeTableModelAdapter) getModel()).nodeForRow(index); + } + + public void updateUI() { + super.updateUI(); + if (tree != null) { + tree.updateUI(); + } + } + + public int getEditingRow() { + return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1 : editingRow; + } + + private int realEditingRow() { + return editingRow; + } + + public void sizeColumnsToFit(int resizingColumn) { + super.sizeColumnsToFit(resizingColumn); + if (getEditingColumn() != -1 && getColumnClass(editingColumn) == TreeTableModel.class) { + Rectangle cellRect = getCellRect(realEditingRow(), getEditingColumn(), false); + Component component = getEditorComponent(); + component.setBounds(cellRect); + component.validate(); + } + } + + public void setRowHeight(int rowHeight) { + super.setRowHeight(rowHeight); + if (tree != null && tree.getRowHeight() != rowHeight) { + tree.setRowHeight(getRowHeight()); + } + } + + public JTree getTree() { + return tree; + } + + public void setTreeRenderer(JTreeTableCellRenderer renderer) { + tree.setCellRenderer(renderer); + } + + public boolean editCellAt(int row, int column, EventObject e) { + boolean retValue = super.editCellAt(row, column, e); + if (retValue && getColumnClass(column) == TreeTableModel.class) { + repaint(getCellRect(row, column, false)); + } + return retValue; + } + + public void expandAll() { + for (int i = 0; i < tree.getRowCount(); i++) { + tree.expandRow(i); + } + } + + public void collapseAll() { + tree.collapsePath(tree.getPathForRow(0)); + } + + public boolean getTreeEditable() { + return treeEditable; + } + + public void setTreeEditable(boolean editable) { + this.treeEditable = editable; + } + + public boolean getShowsIcons() { + return showsIcons; + } + + public void setShowsIcons(boolean showsIcons) { + this.showsIcons = showsIcons; + } + + public void setRootVisible(boolean visible) { + tree.setRootVisible(visible); + } + + public boolean getShowsRootHandles() { + return tree.getShowsRootHandles(); + } + + public void setShowsRootHandles(boolean newValue) { + tree.setShowsRootHandles(newValue); + } +} diff --git a/src/eu/engys/util/ui/treetable/TableFilter.java b/src/eu/engys/util/ui/treetable/TableFilter.java new file mode 100644 index 0000000..e106f6d --- /dev/null +++ b/src/eu/engys/util/ui/treetable/TableFilter.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui.treetable; + +import javax.swing.RowFilter; +import javax.swing.table.TableModel; + +import org.apache.commons.lang.ArrayUtils; + +public class TableFilter extends RowFilter { + + private String filterText; + private int[] columnsWhereToSearch; + + public TableFilter(String initialFilter) { + this.filterText = initialFilter; + } + + public void setFilterText(String filterText) { + this.filterText = filterText; + } + + public void setColumnsWhereToSearch(int... columnsWhereToSearch) { + this.columnsWhereToSearch = columnsWhereToSearch; + } + + @Override + public boolean include(RowFilter.Entry entry) { + if (columnsWhereToSearch == null || columnsWhereToSearch.length == 0) { + return true; + } + + String regexpFilter = filterText.replace(".", "\\.").replace("*", ".*").replace("?", ".?").replace("+", ".+").concat(".*"); + + int numberOfTableColumns = entry.getValueCount(); + for (int i = 0; i < numberOfTableColumns; i++) { + if (ArrayUtils.contains(columnsWhereToSearch, i)) { + if (entry.getStringValue(i).matches(regexpFilter)) { + return true; + } + } + } + return false; + + } + +} diff --git a/src/eu/engys/util/ui/treetable/TreeTableCellEditor.java b/src/eu/engys/util/ui/treetable/TreeTableCellEditor.java new file mode 100644 index 0000000..078485c --- /dev/null +++ b/src/eu/engys/util/ui/treetable/TreeTableCellEditor.java @@ -0,0 +1,107 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui.treetable; + +import java.awt.Component; +import java.awt.Rectangle; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.util.EventObject; + +import javax.swing.DefaultCellEditor; +import javax.swing.Icon; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeCellRenderer; + +public class TreeTableCellEditor extends DefaultCellEditor { + + private final JTreeTable jTreeTable; + + public TreeTableCellEditor(JTreeTable jTreeTable) { + super(new TreeTableTextField()); + this.jTreeTable = jTreeTable; + } + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int r, int c) { + Component component = super.getTableCellEditorComponent(table, value, isSelected, r, c); + JTree t = this.jTreeTable.getTree(); + boolean rv = t.isRootVisible(); + int offsetRow = rv ? r : r - 1; + Rectangle bounds = t.getRowBounds(offsetRow); + int offset = bounds.x; + TreeCellRenderer tcr = t.getCellRenderer(); + if (tcr instanceof DefaultTreeCellRenderer) { + Object node = t.getPathForRow(offsetRow).getLastPathComponent(); + Icon icon; + if (t.getModel().isLeaf(node)) + icon = ((DefaultTreeCellRenderer) tcr).getLeafIcon(); + else if (this.jTreeTable.getTree().isExpanded(offsetRow)) + icon = ((DefaultTreeCellRenderer) tcr).getOpenIcon(); + else + icon = ((DefaultTreeCellRenderer) tcr).getClosedIcon(); + if (icon != null) { + offset += ((DefaultTreeCellRenderer) tcr).getIconTextGap() + icon.getIconWidth(); + } + } + ((TreeTableTextField) getComponent()).offset = offset; + return component; + } + + public boolean isCellEditable(EventObject e) { + if (e instanceof MouseEvent) { + MouseEvent me = (MouseEvent) e; + if (me.getModifiers() == 0 || me.getModifiers() == InputEvent.BUTTON1_MASK) { + for (int counter = jTreeTable.getColumnCount() - 1; counter >= 0; counter--) { + if (jTreeTable.getColumnClass(counter) == TreeTableModel.class) { + MouseEvent newME = new MouseEvent(jTreeTable.getTree(), me.getID(), me.getWhen(), me.getModifiers(), me.getX() - jTreeTable.getCellRect(0, counter, true).x, me.getY(), me.getClickCount(), me.isPopupTrigger()); + this.jTreeTable.getTree().dispatchEvent(newME); + break; + } + } + } + if (me.getClickCount() >= 3) { + return this.jTreeTable.getTreeEditable(); + } + return false; + } + if (e == null) { + return this.jTreeTable.getTreeEditable(); + } + return false; + } + + public static class TreeTableTextField extends JTextField { + public int offset; + + public void setBounds(int x, int y, int w, int h) { + int newX = Math.max(x, offset); + super.setBounds(newX, y, w - (newX - x), h); + } + } +} diff --git a/src/eu/engys/util/ui/treetable/TreeTableModel.java b/src/eu/engys/util/ui/treetable/TreeTableModel.java new file mode 100644 index 0000000..483f9a6 --- /dev/null +++ b/src/eu/engys/util/ui/treetable/TreeTableModel.java @@ -0,0 +1,46 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.treetable; + +import javax.swing.tree.TreeModel; + +public interface TreeTableModel extends TreeModel { + + public int getColumnCount(); + + public String getColumnName(int column); + + public Class getColumnClass(int column); + + public Object getValueAt(Object node, int column); + + public boolean isCellEditable(Object node, int column); + + public void setValueAt(Object aValue, Object node, int column); + + public void remove(Object node); +} diff --git a/src/eu/engys/util/ui/treetable/TreeTableModelAdapter.java b/src/eu/engys/util/ui/treetable/TreeTableModelAdapter.java new file mode 100644 index 0000000..e227730 --- /dev/null +++ b/src/eu/engys/util/ui/treetable/TreeTableModelAdapter.java @@ -0,0 +1,120 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.treetable; + +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.tree.TreePath; + +public class TreeTableModelAdapter extends AbstractTableModel { + JTree tree; + TreeTableModel treeTableModel; + + public TreeTableModelAdapter(TreeTableModel treeTableModel, JTree tree) { + this.tree = tree; + this.treeTableModel = treeTableModel; + + tree.addTreeExpansionListener(new TreeExpansionListener() { + public void treeExpanded(TreeExpansionEvent event) { + fireTableDataChanged(); + } + + public void treeCollapsed(TreeExpansionEvent event) { + fireTableDataChanged(); + } + }); + + treeTableModel.addTreeModelListener(new TreeModelListener() { + public void treeNodesChanged(TreeModelEvent e) { + delayedFireTableDataChanged(); + } + + public void treeNodesInserted(TreeModelEvent e) { + delayedFireTableDataChanged(); + } + + public void treeNodesRemoved(TreeModelEvent e) { + delayedFireTableDataChanged(); + } + + public void treeStructureChanged(TreeModelEvent e) { + delayedFireTableDataChanged(); + } + }); + } + + public int getColumnCount() { + return treeTableModel.getColumnCount(); + } + + public String getColumnName(int column) { + return treeTableModel.getColumnName(column); + } + + public Class getColumnClass(int column) { + return treeTableModel.getColumnClass(column); + } + + public int getRowCount() { + return tree.getRowCount(); + } + + public Object nodeForRow(int row) { + TreePath treePath = tree.getPathForRow(row); + return treePath == null ? null : treePath.getLastPathComponent(); + } + + public Object getValueAt(int row, int column) { + return treeTableModel.getValueAt(nodeForRow(row), column); + } + + public boolean isCellEditable(int row, int column) { + return treeTableModel.isCellEditable(nodeForRow(row), column); + } + + public void setValueAt(Object value, int row, int column) { + treeTableModel.setValueAt(value, nodeForRow(row), column); + fireTableCellUpdated(row, column); + } + + public void removeRow(int row) { + treeTableModel.remove(nodeForRow(row)); + } + + protected void delayedFireTableDataChanged() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + fireTableDataChanged(); + } + }); + } +} diff --git a/src/eu/engys/util/ui/treetable/tree/JTreeTableCellRenderer.java b/src/eu/engys/util/ui/treetable/tree/JTreeTableCellRenderer.java new file mode 100644 index 0000000..7f6024e --- /dev/null +++ b/src/eu/engys/util/ui/treetable/tree/JTreeTableCellRenderer.java @@ -0,0 +1,82 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui.treetable.tree; + +import java.awt.Component; + +import javax.swing.Icon; +import javax.swing.JTree; +import javax.swing.tree.DefaultTreeCellRenderer; + +import eu.engys.util.ui.treetable.JTreeTable; + +public class JTreeTableCellRenderer extends DefaultTreeCellRenderer { + + private final boolean showsIcons; + + public JTreeTableCellRenderer(JTreeTable jTreeTable) { + super(); + this.showsIcons = jTreeTable.getShowsIcons(); + + setTextSelectionColor(jTreeTable.getSelectionForeground()); + setTextNonSelectionColor(jTreeTable.getForeground()); + setBackgroundSelectionColor(jTreeTable.getSelectionBackground()); + setBackgroundNonSelectionColor(jTreeTable.getBackground()); + } + + public Icon getClosedIcon() { + return (showsIcons ? super.getClosedIcon() : null); + } + + public Icon getDefaultClosedIcon() { + return (showsIcons ? super.getDefaultClosedIcon() : null); + } + + public Icon getDefaultLeafIcon() { + return (showsIcons ? super.getDefaultLeafIcon() : null); + } + + public Icon getDefaultOpenIcon() { + return (showsIcons ? super.getDefaultOpenIcon() : null); + } + + public Icon getLeafIcon() { + return (showsIcons ? super.getLeafIcon() : null); + } + + public Icon getOpenIcon() { + return (showsIcons ? super.getOpenIcon() : null); + } + + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, false, expanded, leaf, row, hasFocus); + if (row == 0) { + setIcon(super.getDefaultOpenIcon()); + } + return this; + } +} diff --git a/src/eu/engys/util/ui/treetable/tree/ListToTreeSelectionModelWrapper.java b/src/eu/engys/util/ui/treetable/tree/ListToTreeSelectionModelWrapper.java new file mode 100644 index 0000000..6ba9c8b --- /dev/null +++ b/src/eu/engys/util/ui/treetable/tree/ListToTreeSelectionModelWrapper.java @@ -0,0 +1,95 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui.treetable.tree; + +import javax.swing.JTree; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreePath; + +public class ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel { + + private boolean updatingListSelectionModel; + private JTree tree; + + public ListToTreeSelectionModelWrapper(JTree tree) { + super(); + this.tree = tree; + getListSelectionModel().addListSelectionListener(createListSelectionListener()); + } + + public ListSelectionModel getListSelectionModel() { + return listSelectionModel; + } + + public void resetRowSelection() { + if (!updatingListSelectionModel) { + updatingListSelectionModel = true; + try { + super.resetRowSelection(); + } finally { + updatingListSelectionModel = false; + } + } + } + + protected ListSelectionListener createListSelectionListener() { + return new ListSelectionHandler(); + } + + protected void updateSelectedPathsFromSelectedRows() { + if (!updatingListSelectionModel) { + updatingListSelectionModel = true; + try { + int min = listSelectionModel.getMinSelectionIndex(); + int max = listSelectionModel.getMaxSelectionIndex(); + + clearSelection(); + if (min != -1 && max != -1) { + for (int counter = min; counter <= max; counter++) { + if (listSelectionModel.isSelectedIndex(counter)) { + TreePath selPath = tree.getPathForRow(counter); + + if (selPath != null) { + addSelectionPath(selPath); + } + } + } + } + } finally { + updatingListSelectionModel = false; + } + } + } + + class ListSelectionHandler implements ListSelectionListener { + public void valueChanged(ListSelectionEvent e) { + updateSelectedPathsFromSelectedRows(); + } + } +} diff --git a/src/eu/engys/util/ui/treetable/tree/TreeTableCellRenderer.java b/src/eu/engys/util/ui/treetable/tree/TreeTableCellRenderer.java new file mode 100644 index 0000000..ee5b26f --- /dev/null +++ b/src/eu/engys/util/ui/treetable/tree/TreeTableCellRenderer.java @@ -0,0 +1,95 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.util.ui.treetable.tree; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Graphics; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.JTree; +import javax.swing.border.Border; +import javax.swing.table.TableCellRenderer; +import javax.swing.tree.TreeModel; + +import eu.engys.util.ui.checkboxtree.AddCheckBoxToTree.CheckTreeCellRenderer; +import eu.engys.util.ui.treetable.JTreeTable; + +public class TreeTableCellRenderer extends JTree implements TableCellRenderer { + + private final JTreeTable jTreeTable; + private int visibleRow; + private TableCellRenderer tableDefaultRenderer; + + public TreeTableCellRenderer(JTreeTable jTreeTable, TreeModel model) { + super(model); + this.jTreeTable = jTreeTable; + this.tableDefaultRenderer = jTreeTable.getDefaultRenderer(Object.class); + setCellRenderer(new JTreeTableCellRenderer(jTreeTable)); + } + + public void setBounds(int x, int y, int w, int h) { + if (x < 0) return; + super.setBounds(x + 10, 0, w, this.jTreeTable.getHeight()); + } + + public void paint(Graphics g) { + g.translate(0, -visibleRow * getRowHeight() - 3); + super.paint(g); + } + + @Override + public Container getParent() { + return jTreeTable; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + visibleRow = table.convertRowIndexToModel(row); + + JComponent c = (JComponent) tableDefaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + + Color background = c.getBackground(); + Color foreground = c.getForeground(); + Border border = c.getBorder(); + + setBackground(background); + setForeground(foreground); + setBorder(border); + + if (getCellRenderer() instanceof CheckTreeCellRenderer) { + ((CheckTreeCellRenderer) getCellRenderer()).setBackgroundSelectionColor(background); + ((CheckTreeCellRenderer) getCellRenderer()).setBackgroundNonSelectionColor(background); + } else { + ((JLabel) getCellRenderer()).setBackground(background); + ((JLabel) getCellRenderer()).setForeground(foreground); + } + + return this; + } +} diff --git a/src/eu/engys/util/ui/treetable/tree/TreeTableTreeModel.java b/src/eu/engys/util/ui/treetable/tree/TreeTableTreeModel.java new file mode 100644 index 0000000..d6bd14f --- /dev/null +++ b/src/eu/engys/util/ui/treetable/tree/TreeTableTreeModel.java @@ -0,0 +1,121 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.treetable.tree; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; + +public class TreeTableTreeModel implements TreeModel { + + private TreeTableTreeNode root; + + private List listeners = new ArrayList(); + + public TreeTableTreeModel(TreeTableTreeNode root) { + this.root = root; + } + + @Override + public Object getRoot() { + return root; + } + + @Override + public Object getChild(Object parent, int index) { + return ((TreeTableTreeNode) parent).getChild(index); + } + + @Override + public int getChildCount(Object parent) { + return ((TreeTableTreeNode) parent).getChildCount(); + } + + @Override + public boolean isLeaf(Object node) { + if (node == null) { + return true; + } + return ((TreeTableTreeNode) node).isLeaf(); + } + + @Override + public void valueForPathChanged(TreePath path, Object newValue) { + throw new UnsupportedOperationException(); + } + + @Override + public int getIndexOfChild(Object parent, Object child) { + return ((TreeTableTreeNode) parent).getIndexOfChild((TreeTableTreeNode) child); + } + + @Override + public void addTreeModelListener(TreeModelListener l) { + listeners.add(l); + } + + @Override + public void removeTreeModelListener(TreeModelListener l) { + listeners.remove(l); + } + + public void fireTreeStructureChanged() { + TreeModelEvent e = new TreeModelEvent(getRoot(), new Object[] { getRoot() }, null, null); + for (Iterator iter = listeners.iterator(); iter.hasNext();) { + TreeModelListener l = iter.next(); + l.treeStructureChanged(e); + } + } + + public TreeNode[] getPathToRoot(TreeNode aNode) { + return getPathToRoot(aNode, 0); + } + + private TreeNode[] getPathToRoot(TreeNode aNode, int depth) { + TreeNode[] retNodes; + if (aNode == null) { + if (depth == 0) + return null; + else + retNodes = new TreeNode[depth]; + } else { + depth++; + if (aNode == root) + retNodes = new TreeNode[depth]; + else + retNodes = getPathToRoot(aNode.getParent(), depth); + retNodes[retNodes.length - depth] = aNode; + } + return retNodes; + } +} diff --git a/src/eu/engys/util/ui/treetable/tree/TreeTableTreeNode.java b/src/eu/engys/util/ui/treetable/tree/TreeTableTreeNode.java new file mode 100644 index 0000000..c0dad7c --- /dev/null +++ b/src/eu/engys/util/ui/treetable/tree/TreeTableTreeNode.java @@ -0,0 +1,39 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.util.ui.treetable.tree; + +public interface TreeTableTreeNode { + + public int getChildCount(); + + public TreeTableTreeNode getChild(int index); + + public boolean isLeaf(); + + public int getIndexOfChild(TreeTableTreeNode child); + +} diff --git a/src/eu/engys/vtk/ActorsMap.java b/src/eu/engys/vtk/ActorsMap.java new file mode 100644 index 0000000..ee0138a --- /dev/null +++ b/src/eu/engys/vtk/ActorsMap.java @@ -0,0 +1,87 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.view3D.Actor; + +public class ActorsMap { + + private final Map delegate = new LinkedHashMap<>(); + + public ActorsMap() { + } + + public ActorsMap(Map map) { + this.delegate.putAll(map); + } + + public void put(Surface key, Actor value) { + delegate.put(key, value); + } + + public Actor get(Surface key) { + return delegate.get(key); + } + + public Actor remove(Surface key) { + return delegate.remove(key); + } + + public boolean contains(Surface surface) { + return delegate.containsKey(surface); + } + + public Collection values() { + return delegate.values(); + } + + public Set keys() { + return delegate.keySet(); + } + + public void clear() { + delegate.clear(); + } + + public boolean isEmpty() { + return delegate.isEmpty(); + } + + public boolean containsActor(Actor actor) { + return delegate.containsValue(actor); + } + + public Map getDelegate() { + return delegate; + } + +} diff --git a/src/eu/engys/vtk/CellZoneActor.java b/src/eu/engys/vtk/CellZoneActor.java new file mode 100644 index 0000000..198b057 --- /dev/null +++ b/src/eu/engys/vtk/CellZoneActor.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import vtk.vtkPolyData; +import vtk.vtkUnstructuredGrid; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.facezones.FaceZone; +import eu.engys.util.ui.checkboxtree.VisibleItem; +import eu.engys.vtk.actors.DefaultActor; + +public class CellZoneActor extends DefaultActor { + + private VisibleItem zone; + + public CellZoneActor(CellZone zone, vtkUnstructuredGrid dataset) { + super(zone.getName()); + this.zone = zone; + newActor(dataset, true); + } + + public CellZoneActor(FaceZone zone, vtkPolyData dataset) { + super(zone.getName()); + this.zone = zone; + newActor(dataset, true); + } + + @Override + public VisibleItem getVisibleItem() { + return zone; + } +} diff --git a/src/eu/engys/vtk/GeometryContext.java b/src/eu/engys/vtk/GeometryContext.java new file mode 100644 index 0000000..997a3ed --- /dev/null +++ b/src/eu/engys/vtk/GeometryContext.java @@ -0,0 +1,81 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.util.LinkedHashMap; +import java.util.Map; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Context; +import eu.engys.gui.view3D.Representation; + +public class GeometryContext extends Context { + + private ActorsMap actorsMap; + private Map actorsVisibility; + + // private Map actorsProperty; + + public GeometryContext(Representation representation, Map actorsMap) { + super(representation); + this.actorsMap = new ActorsMap(actorsMap); + this.actorsVisibility = initActorsVisibility(actorsMap); + // this.actorsProperty = initActorsProperty(actorsMap); + } + + @Override + public boolean isEmpty() { + return actorsMap.isEmpty(); + } + + public void clear() { + actorsMap.clear(); + actorsVisibility.clear(); + } + + private Map initActorsVisibility(Map actorsMap) { + Map map = new LinkedHashMap<>(); + for (Surface surface : actorsMap.keySet()) { + Actor actor = actorsMap.get(surface); + map.put(surface, actor.getVisibility()); + } + return map; + } + + public ActorsMap getActorsMap() { + return actorsMap; + } + + public Map getActorsVisibility() { + return actorsVisibility; + } + + @Override + public String toString() { + return "GeometryContext [ repres = " + getRepresentation() + ", actors are " + actorsMap.getDelegate().size() + "]"; + } +} diff --git a/src/eu/engys/vtk/HelyxView3DEventListener.java b/src/eu/engys/vtk/HelyxView3DEventListener.java new file mode 100644 index 0000000..471ece6 --- /dev/null +++ b/src/eu/engys/vtk/HelyxView3DEventListener.java @@ -0,0 +1,121 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import java.awt.Color; + +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.vecmath.Point3d; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.events.EventManager.Event; +import eu.engys.gui.events.view3D.AxisEvent; +import eu.engys.gui.events.view3D.BoxEvent; +import eu.engys.gui.events.view3D.LayersCoverageEvent; +import eu.engys.gui.events.view3D.MeshQualityEvent; +import eu.engys.gui.events.view3D.PlaneEvent; +import eu.engys.gui.events.view3D.PointEvent; +import eu.engys.gui.events.view3D.SelectionEvent; +import eu.engys.gui.events.view3D.VolumeReportEvent; +import eu.engys.gui.events.view3D.VolumeReportVisibilityEvent; +import eu.engys.gui.events.view3D.VolumeReportVisibilityEvent.Kind; +import eu.engys.gui.view3D.CanvasPanel; +import eu.engys.gui.view3D.LayerInfo; +import eu.engys.gui.view3D.QualityInfo; +import eu.engys.gui.view3D.Selection; +import eu.engys.gui.view3D.View3DEventListener; +import eu.engys.util.ui.textfields.DoubleField; + +public class HelyxView3DEventListener implements View3DEventListener { + + private CanvasPanel view3D; + + public HelyxView3DEventListener(CanvasPanel view3DPanel) { + this.view3D = view3DPanel; + } + + @Override + public void eventTriggered(Object obj, final Event event) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (event instanceof PointEvent) { + DoubleField[] point = ((PointEvent) event).getPoint(); + String key = ((PointEvent) event).getKey(); + EventActionType action = ((PointEvent) event).getAction(); + Color color = ((PointEvent) event).getColor(); + view3D.showPoint(point, key, action, color); + } else if (event instanceof AxisEvent) { + AxisEvent e = (AxisEvent) event; + DoubleField[] origin = e.getAxisInfo().getCenter(); + DoubleField[] normal = e.getAxisInfo().getAxis(); + EventActionType action = e.getAxisInfo().getAction(); + view3D.showAxis(origin, normal, action); + } else if (event instanceof PlaneEvent) { + DoubleField[] origin = ((PlaneEvent) event).getOrigin(); + DoubleField[] normal = ((PlaneEvent) event).getNormal(); + EventActionType action = ((PlaneEvent) event).getAction(); + boolean interactive = ((PlaneEvent) event).isInteractive(); + if (interactive) { + view3D.showPlane(origin, normal, action); + } else { + view3D.showPlaneDisplay(origin, normal, action); + } + } else if (event instanceof BoxEvent) { + DoubleField[] min = ((BoxEvent) event).getMin(); + DoubleField[] max = ((BoxEvent) event).getMax(); + EventActionType action = ((BoxEvent) event).getAction(); + view3D.showBox(min, max, action); + } else if (event instanceof SelectionEvent) { + Selection selection = ((SelectionEvent) event).getSelection(); + EventActionType action = ((SelectionEvent) event).getAction(); + view3D.activateSelection(selection, action); + } else if (event instanceof MeshQualityEvent) { + QualityInfo qualityInfo = ((MeshQualityEvent) event).getQualityInfo(); + EventActionType action = ((MeshQualityEvent) event).getAction(); + view3D.showQualityFields(qualityInfo, action); + } else if (event instanceof LayersCoverageEvent) { + EventActionType action = ((LayersCoverageEvent) event).getAction(); + JPanel colorBar = ((LayersCoverageEvent) event).getColorBar(); + LayerInfo layerInfo = ((LayersCoverageEvent) event).getLayerInfo(); + view3D.showLayersCoverage(layerInfo, colorBar, action); + } else if (event instanceof VolumeReportEvent) { + String varName = VolumeReportEvent.class.cast(event).getVarName(); + Point3d min = VolumeReportEvent.class.cast(event).getMinAtLocation(); + Point3d max = VolumeReportEvent.class.cast(event).getMaxAtLocation(); + view3D.updateMinAndMaxForFields(varName, min, max); + } else if (event instanceof VolumeReportVisibilityEvent) { + String key = VolumeReportVisibilityEvent.class.cast(event).getKey(); + boolean visible = VolumeReportVisibilityEvent.class.cast(event).isVisible(); + Kind kind = VolumeReportVisibilityEvent.class.cast(event).getKind(); + view3D.showMinMaxFieldPoints(key, kind, visible); + } + } + }); + } +} diff --git a/src/eu/engys/vtk/InteractorStyle.java b/src/eu/engys/vtk/InteractorStyle.java new file mode 100644 index 0000000..f5dbea6 --- /dev/null +++ b/src/eu/engys/vtk/InteractorStyle.java @@ -0,0 +1,105 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import vtk.vtkInteractorStyleTrackballCamera; + +public class InteractorStyle extends vtkInteractorStyleTrackballCamera { + + public InteractorStyle() { + super(); + AddObserver("MouseMoveEvent", this, "OnMouseMove"); + AddObserver("LeftButtonPressEvent", this, "leftButtonPressed"); + AddObserver("MiddleButtonPressEvent", this, "middleButtonPressed"); + AddObserver("RightButtonPressEvent", this, "rightButtonPressed"); + AddObserver("LeftButtonReleaseEvent", this, "leftButtonReleased"); + AddObserver("MiddleButtonReleaseEvent", this, "middleButtonReleased"); + AddObserver("RightButtonReleaseEvent", this, "rightButtonReleased"); + } + + public void leftButtonPressed() { + System.out.println("InteractorStyle.leftButtonPressed()"); +// buttonDown(getLastPos(), 0); + } + + public void middleButtonPressed() { + System.out.println("InteractorStyle.middleButtonPressed()"); +// buttonDown(getLastPos(), 1); + } + + public void rightButtonPressed() { + System.out.println("InteractorStyle.rightButtonPressed()"); +// buttonDown(getLastPos(), 2); + } + + public void leftButtonReleased() { + System.out.println("InteractorStyle.leftButtonReleased()"); +// buttonUp(getLastPos(), 0); + } + + public void middleButtonReleased() { + System.out.println("InteractorStyle.middleButtonReleased()"); +// buttonUp(getLastPos(), 1); + } + + public void rightButtonReleased() { + System.out.println("InteractorStyle.rightButtonReleased()"); +// buttonUp(getLastPos(), 2); + } + + public void OnMouseMove() { + System.out.println("InteractorStyle.OnMouseMove() " + GetState()); +// int x = GetInteractor().GetEventPosition()[0]; +// int y = GetInteractor().GetEventPosition()[1]; +// switch(GetState()) +// { +// case 1: // '\001' +// postText(INTERACTOR_ACTION_ROTATE); +// Rotate(); +// InvokeEvent("InteractionEvent"); +// break; +// +// case 2: // '\002' +// postText(INTERACTOR_ACTION_PAN); +// Pan(); +// InvokeEvent("InteractionEvent"); +// break; +// +// case 4: // '\004' +// postText(INTERACTOR_ACTION_ZOOM); +// Dolly(); +// InvokeEvent("InteractionEvent"); +// break; +// +// case 3: // '\003' +// postText(INTERACTOR_ACTION_ROLL); +// Spin(); +// InvokeEvent("InteractionEvent"); +// break; +// } + } + +} diff --git a/src/eu/engys/vtk/MeshContext.java b/src/eu/engys/vtk/MeshContext.java new file mode 100644 index 0000000..6188b68 --- /dev/null +++ b/src/eu/engys/vtk/MeshContext.java @@ -0,0 +1,111 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.util.LinkedHashMap; +import java.util.Map; + +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Context; +import eu.engys.gui.view3D.Representation; + +public class MeshContext extends Context { + + private boolean allowSelection; + + private Map patches; + private Map patchesVisibility; + + private Map cellzones; + private Map zonesVisibility; + + public MeshContext(Representation representation, boolean allowSelection, Map cellzones, Map patches) { + super(representation); + this.allowSelection = allowSelection; + + this.patches = new LinkedHashMap<>(patches); + this.patchesVisibility = initPatchesVisibility(patches); + + this.cellzones = new LinkedHashMap<>(cellzones); + this.zonesVisibility = initZonesVisibility(cellzones); + } + + public void clear() { + patches.clear(); + patchesVisibility.clear(); + zonesVisibility.clear(); + cellzones.clear(); + } + + private Map initPatchesVisibility(Map patches) { + Map map = new LinkedHashMap<>(); + for (String name : patches.keySet()) { + Actor actor = patches.get(name); + map.put(name, actor.getVisibility()); + } + return map; + } + + private Map initZonesVisibility(Map cellzones) { + Map map = new LinkedHashMap<>(); + for (String name : cellzones.keySet()) { + Actor actor = cellzones.get(name); + map.put(name, actor.getVisibility()); + } + return map; + } + + @Override + public boolean isEmpty() { + return patches.isEmpty(); + } + + public boolean isAllowSelection(){ + return allowSelection; + } + + public Map getPatches() { + return patches; + } + + public Map getPatchesVisibility() { + return patchesVisibility; + } + + public Map getCellzones() { + return cellzones; + } + + public Map getZonesVisibility() { + return zonesVisibility; + } + + @Override + public String toString() { + return "MeshContext [ repres = " + representation + ", zones are " + cellzones.keySet().size() + ", patches are " + patches.keySet().size() + "]"; + } + +} diff --git a/src/eu/engys/vtk/PatchActor.java b/src/eu/engys/vtk/PatchActor.java new file mode 100644 index 0000000..39fc430 --- /dev/null +++ b/src/eu/engys/vtk/PatchActor.java @@ -0,0 +1,45 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.util.ui.checkboxtree.VisibleItem; +import eu.engys.vtk.actors.DefaultActor; + +public class PatchActor extends DefaultActor { + private Patch patch; + + public PatchActor(Patch patch) { + super(patch.getName()); + this.patch = patch; + newActor(patch.getDataSet(), true); + } + + @Override + public VisibleItem getVisibleItem() { + return patch; + } +} diff --git a/src/eu/engys/vtk/ReaderProgress.java b/src/eu/engys/vtk/ReaderProgress.java new file mode 100644 index 0000000..39961d5 --- /dev/null +++ b/src/eu/engys/vtk/ReaderProgress.java @@ -0,0 +1,44 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import vtk.vtkAlgorithm; +import eu.engys.util.progress.ProgressMonitor; + +public class ReaderProgress { + private vtkAlgorithm reader; + private ProgressMonitor monitor; + + public ReaderProgress(vtkAlgorithm reader, ProgressMonitor monitor) { + this.reader = reader; + this.monitor = monitor; + } + + public void progress() { + monitor.setCurrent(null, (int) (100*reader.GetProgress())); + } +} diff --git a/src/eu/engys/vtk/RenderPanelAdapter.java b/src/eu/engys/vtk/RenderPanelAdapter.java new file mode 100644 index 0000000..8ad8fce --- /dev/null +++ b/src/eu/engys/vtk/RenderPanelAdapter.java @@ -0,0 +1,179 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.awt.Color; +import java.awt.event.KeyListener; + +import vtk.vtkAssembly; +import vtk.vtkImageData; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.CameraManager.Position; +import eu.engys.gui.view3D.Interactor; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.gui.view3D.Representation; + +public class RenderPanelAdapter implements RenderPanel { + + @Override + public void lock() { + } + + @Override + public void Render() { + } + + @Override + public void unlock() { + } + + @Override + public void clear() { + } + + @Override + public void setCameraPosition(Position xPos) { + } + + @Override + public void resetCamera() { + } + + @Override + public void wheelForward() { + } + + @Override + public void wheelBackward() { + } + + @Override + public void zoomReset() { + } + + @Override + public void resetZoomLater() { + } + + @Override + public void resetZoomAndWait() { + } + + @Override + public void clearSelection() { + } + + @Override + public void setRepresentation(Representation r) { + } + + @Override + public Representation getRepresentation() { + return null; + } + + @Override + public void changeRepresentation(Representation r) { + } + + @Override + public void renderLater() { + } + + @Override + public void renderAndWait() { + } + + @Override + public void addActor(vtkAssembly cor) { + } + + @Override + public void addActor(Actor actor) { + } + + @Override + public void removeActor(Actor actor) { + } + + @Override + public void selectActors(boolean keep, Actor... pickedActor) { + } + + @Override + public void setLowRendering() { + + } + + @Override + public void setHighRendering() { + } + + @Override + public void setActorColor(Color c, Actor... actor) { + } + + @Override + public void addKeyListener(KeyListener listener) { + } + + @Override + public void removeKeyListener(KeyListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public void ParallelProjectionOn() { + } + + @Override + public void ParallelProjectionOff() { + } + + @Override + public VTKPickManager getPickManager() { + return null; + } + + @Override + public Interactor getInteractor() { + return null; + } + + @Override + public vtkImageData toImageData() { + return null; + } + @Override + public void lowRenderingOff() { + } + @Override + public void lowRenderingOn() { + } +} diff --git a/src/eu/engys/vtk/VTK3DActionsToolBar.java b/src/eu/engys/vtk/VTK3DActionsToolBar.java new file mode 100644 index 0000000..28e5e80 --- /dev/null +++ b/src/eu/engys/vtk/VTK3DActionsToolBar.java @@ -0,0 +1,182 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import static eu.engys.util.ui.UiUtil.createButtonBarToggleButton; +import static eu.engys.util.ui.UiUtil.createToolBarButton; +import static eu.engys.util.ui.UiUtil.createToolBarToggleButton; + +import java.util.List; + +import javax.swing.ButtonGroup; +import javax.swing.JToolBar; + +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.project.Model; +import eu.engys.gui.view3D.Context; +import eu.engys.gui.view3D.Controller3D; +import eu.engys.util.plaf.ILookAndFeel; + +public class VTK3DActionsToolBar extends JToolBar { + + static final String _3D_LOAD_MESH = "3d.load.mesh"; + + static final String _3D_AXIS_XPOS = "3d.axis.xpos"; + static final String _3D_AXIS_XNEG = "3d.axis.xneg"; + static final String _3D_AXIS_YPOS = "3d.axis.ypos"; + static final String _3D_AXIS_YNEG = "3d.axis.yneg"; + static final String _3D_AXIS_ZPOS = "3d.axis.zpos"; + static final String _3D_AXIS_ZNEG = "3d.axis.zneg"; + + static final String _3D_ZOOM_RESET = "3d.zoom.reset"; + static final String _3D_ZOOM_TOBOX = "3d.zoom.tobox"; + static final String _3D_ZOOM_OUT = "3d.zoom.out"; + static final String _3D_ZOOM_IN = "3d.zoom.in"; + + static final String _3D_VIEW_PROJECTIONS = "3d.view.projections"; + static final String _3D_VIEW_OUTLINE = "3d.view.outline"; + static final String _3D_VIEW_PROFILE = "3d.view.profile"; + static final String _3D_VIEW_EDGES = "3d.view.edges"; + static final String _3D_VIEW_SURFACE = "3d.view.surface"; + static final String _3D_VIEW_WIREFRAME = "3d.view.wireframe"; + private Model model; + + public VTK3DActionsToolBar(Model model, ILookAndFeel laf) { + super(JToolBar.VERTICAL); + this.model = model; + putClientProperty("Synthetica.toolBar.buttons.paintBorder", Boolean.TRUE); + putClientProperty("Synthetica.opaque", Boolean.FALSE); + setFloatable(false); + setRollover(true); + setOpaque(false); + layoutComponents(); + } + + private void layoutComponents() { + add(createToolBarButton(ActionManager.getInstance().get(_3D_ZOOM_IN))); + add(createToolBarButton(ActionManager.getInstance().get(_3D_ZOOM_OUT))); + add(createToolBarButton(ActionManager.getInstance().get(_3D_ZOOM_TOBOX))); + add(createToolBarButton(ActionManager.getInstance().get(_3D_ZOOM_RESET))); + addSeparator(); + add(createToolBarButton(ActionManager.getInstance().get(_3D_AXIS_XPOS))); + add(createToolBarButton(ActionManager.getInstance().get(_3D_AXIS_XNEG))); + add(createToolBarButton(ActionManager.getInstance().get(_3D_AXIS_YPOS))); + add(createToolBarButton(ActionManager.getInstance().get(_3D_AXIS_YNEG))); + add(createToolBarButton(ActionManager.getInstance().get(_3D_AXIS_ZPOS))); + add(createToolBarButton(ActionManager.getInstance().get(_3D_AXIS_ZNEG))); + addSeparator(); + ButtonGroup viewGroup = new ButtonGroup(); + add(createButtonBarToggleButton(ActionManager.getInstance().get(_3D_VIEW_WIREFRAME), viewGroup)); + add(createButtonBarToggleButton(ActionManager.getInstance().get(_3D_VIEW_SURFACE), viewGroup)); + add(createButtonBarToggleButton(ActionManager.getInstance().get(_3D_VIEW_EDGES), viewGroup)); + add(createButtonBarToggleButton(ActionManager.getInstance().get(_3D_VIEW_PROFILE), viewGroup)); + add(createButtonBarToggleButton(ActionManager.getInstance().get(_3D_VIEW_OUTLINE), viewGroup)); + add(createToolBarToggleButton(ActionManager.getInstance().get(_3D_VIEW_PROJECTIONS))); + } + + public void update(List controllers) { + Context context = getaContext(controllers); + if (context != null) { + ActionManager.getInstance().get(_3D_VIEW_PROJECTIONS).setEnabled(true); + ActionManager.getInstance().get(_3D_VIEW_WIREFRAME).setEnabled(true); + ActionManager.getInstance().get(_3D_VIEW_SURFACE).setEnabled(true); + ActionManager.getInstance().get(_3D_VIEW_EDGES).setEnabled(true); + ActionManager.getInstance().get(_3D_VIEW_PROFILE).setEnabled(true); + ActionManager.getInstance().get(_3D_VIEW_OUTLINE).setEnabled(true); + + switch (context.getRepresentation()) { + case WIREFRAME: + ActionManager.getInstance().get(_3D_VIEW_WIREFRAME).setSelected(true); + break; + case SURFACE: + ActionManager.getInstance().get(_3D_VIEW_SURFACE).setSelected(true); + break; + case SURFACE_WITH_EDGES: + ActionManager.getInstance().get(_3D_VIEW_EDGES).setSelected(true); + break; + case OUTLINE: + ActionManager.getInstance().get(_3D_VIEW_OUTLINE).setSelected(true); + break; + case PROFILE: + ActionManager.getInstance().get(_3D_VIEW_PROFILE).setSelected(true); + break; + } +// if (context instanceof MeshContext) { +// MeshContext mc = (MeshContext) context; +// ActionManager.getInstance().get(_3D_LOAD_MESH).setEnabled(!model.getPatches().isEmpty() && mc.isEmpty()); +// } + } else { + ActionManager.getInstance().get(_3D_VIEW_WIREFRAME).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_SURFACE).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_EDGES).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_PROFILE).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_OUTLINE).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_PROJECTIONS).setEnabled(false); + } + + MeshContext mContext = (MeshContext) getMeshContext(controllers); + if(mContext != null){ + ActionManager.getInstance().get(_3D_LOAD_MESH).setEnabled(!model.getPatches().isEmpty() && mContext.isEmpty()); + } + } + + private Context getaContext(List controllers) { + for (Controller3D c : controllers) { + Context context = c.getCurrentContext(); + if (context != null) { + return context; + } + } + return null; + } + + private Context getMeshContext(List controllers) { + for (Controller3D c : controllers) { + Context context = c.getCurrentContext(); + if (context != null && context instanceof MeshContext) { + return context; + } + } + return null; + } + + public void clear() { + ActionManager.getInstance().get(_3D_VIEW_WIREFRAME).setSelected(false); + ActionManager.getInstance().get(_3D_VIEW_SURFACE).setSelected(false); + ActionManager.getInstance().get(_3D_VIEW_EDGES).setSelected(false); + ActionManager.getInstance().get(_3D_VIEW_PROFILE).setSelected(false); + ActionManager.getInstance().get(_3D_VIEW_OUTLINE).setSelected(false); + ActionManager.getInstance().get(_3D_VIEW_PROJECTIONS).setSelected(false); + + ActionManager.getInstance().get(_3D_VIEW_WIREFRAME).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_SURFACE).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_EDGES).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_PROFILE).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_OUTLINE).setEnabled(false); + ActionManager.getInstance().get(_3D_VIEW_PROJECTIONS).setEnabled(false); + } +} diff --git a/src/eu/engys/vtk/VTKActors.java b/src/eu/engys/vtk/VTKActors.java new file mode 100644 index 0000000..981d1fa --- /dev/null +++ b/src/eu/engys/vtk/VTKActors.java @@ -0,0 +1,43 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.util.Collection; +import java.util.Map; + +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.RenderPanel; + +public interface VTKActors { + + public Collection getActors(); + + public abstract boolean containsActor(Actor pickedActor); + + public abstract Map getActorsMap(); + + void setRenderPanel(RenderPanel renderPanel); +} diff --git a/src/eu/engys/vtk/VTKCameraManager.java b/src/eu/engys/vtk/VTKCameraManager.java new file mode 100644 index 0000000..d13bd21 --- /dev/null +++ b/src/eu/engys/vtk/VTKCameraManager.java @@ -0,0 +1,78 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import vtk.vtkRenderer; +import eu.engys.gui.view3D.CameraManager; + +public class VTKCameraManager implements CameraManager { + + private VTKRenderPanel vtkRenderPanel; + + public VTKCameraManager(VTKRenderPanel vtkRenderPanel) { + this.vtkRenderPanel = vtkRenderPanel; + } + + + public void setCameraPosition(Position pos) { + vtkRenderer renderer = vtkRenderPanel.GetRenderer(); + double[] fp = renderer.GetActiveCamera().GetFocalPoint(); + double[] p = renderer.GetActiveCamera().GetPosition(); + double dist = Math.sqrt(Math.pow(p[0] - fp[0], 2) + Math.pow(p[1] - fp[1], 2) + Math.pow(p[2] - fp[2], 2)); + + vtkRenderPanel.lock(); + switch (pos) { + case X_POS: + renderer.GetActiveCamera().SetPosition(fp[0] - dist, fp[1], fp[2]); + renderer.GetActiveCamera().SetViewUp(0, 0, 1); + break; + case X_NEG: + renderer.GetActiveCamera().SetPosition(fp[0] + dist, fp[1], fp[2]); + renderer.GetActiveCamera().SetViewUp(0, 0, 1); + break; + case Y_POS: + renderer.GetActiveCamera().SetPosition(fp[0], fp[1] - dist, fp[2]); + renderer.GetActiveCamera().SetViewUp(0, 0, 1); + break; + case Y_NEG: + renderer.GetActiveCamera().SetPosition(fp[0], fp[1] + dist, fp[2]); + renderer.GetActiveCamera().SetViewUp(0, 0, 1); + break; + case Z_POS: + renderer.GetActiveCamera().SetPosition(fp[0], fp[1], fp[2] - dist); + renderer.GetActiveCamera().SetViewUp(0, 1, 0); + break; + case Z_NEG: + renderer.GetActiveCamera().SetPosition(fp[0], fp[1], fp[2] + dist); + renderer.GetActiveCamera().SetViewUp(0, 1, 0); + break; + } + vtkRenderPanel.unlock(); + vtkRenderPanel.renderLater(); + } + + +} diff --git a/src/eu/engys/vtk/VTKCellZones.java b/src/eu/engys/vtk/VTKCellZones.java new file mode 100644 index 0000000..9c83de5 --- /dev/null +++ b/src/eu/engys/vtk/VTKCellZones.java @@ -0,0 +1,200 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkDataObject; +import vtk.vtkPolyData; +import vtk.vtkUnstructuredGrid; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.facezones.FaceZone; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.progress.ProgressMonitor; + +public class VTKCellZones implements VTKActors, Picker { + + private static final Logger logger = LoggerFactory.getLogger(VTKCellZones.class); + + private Map actors = new LinkedHashMap<>(); + private Map names = new LinkedHashMap<>(); + private RenderPanel renderPanel; + private Model model; + private ProgressMonitor monitor; + + public VTKCellZones(Model model, ProgressMonitor monitor) { + this.model = model; + this.monitor = monitor; + } + + @Override + public void setRenderPanel(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + } + + public void load(List cellZonesDataset) { + for (int i = 0; i < cellZonesDataset.size(); i++) { + vtkDataObject dataset = cellZonesDataset.get(i); + + if (dataset instanceof vtkPolyData) { + FaceZone zone = model.getFaceZones().get(i); + zone.setLoaded(true); + addActorToZones(new CellZoneActor(zone, (vtkPolyData) dataset)); + } else if (dataset instanceof vtkUnstructuredGrid) { + CellZone zone = model.getCellZones().get(i); + zone.setLoaded(true); + addActorToZones(new CellZoneActor(zone, (vtkUnstructuredGrid) dataset)); + } + } + } + + void addActorToZones(Actor actor) { + logger.debug("[ADD ACTOR] {} ({})", actor.getName(), actor.getVisibility() ? "visible" : "hidden"); + actors.put(actor.getName(), actor); + names.put(actor, actor.getName()); + } + + void addActorsToRenderer() { + for (String name : actors.keySet()) { + Actor actor = actors.get(name); + renderPanel.addActor(actor); + } + } + + public void addCellZonesMap(Map map, Map visibility) { + for (String name : map.keySet()) { + Actor actor = map.get(name); + actor.setVisibility(visibility.get(name)); + addActorToZones(actor); + renderPanel.addActor(actor); + } + } + + public void deleteActors() { + for (Actor actor : actors.values()) { + renderPanel.removeActor(actor); + actor.deleteActor(); + } + actors.clear(); + names.clear(); + } + + public void removeActorsFromRenderer() { + for (Actor actor : actors.values()) { + renderPanel.removeActor(actor); + } + actors.clear(); + names.clear(); + } + + public void VisibilityOff() { + for (Actor actor : actors.values()) { + actor.setVisibility(false); + } + } + + public Collection getActors() { + return actors.values(); + } + + public boolean containsActor(Actor pickedActor) { + return names.containsKey(pickedActor); + } + +// @Override +// public String getActorName(Actor pickedActor) { +// return names.get(pickedActor); +// } + + @Override + public boolean canPickCells(Actor pickedActor) { + return false; + } + + @Override + public boolean canPickMesh() { + return true; + } + + public void selectActors(CellZone[] zones) { + logger.debug("updateSurfaceVisibility: {} zones selected {}", zones.length, zones.length == 1 ? ", selection is: " + zones[0] : ""); + + List selection = new ArrayList(); + for (CellZone zone : zones) { + String name = zone.getName(); + if (zone.isVisible() && actors.containsKey(name)) { + selection.add(actors.get(name)); + } + } + renderPanel.setLowRendering(); + renderPanel.selectActors(false, selection.toArray(new Actor[0])); + renderPanel.setHighRendering(); + } + + public void updateVisibility(CellZone[] selection) { + for (CellZone cellZone : selection) { + Actor actor = actors.get(cellZone.getName()); + actor.setVisibility(cellZone.isVisible()); + } + renderPanel.renderLater(); + } + + public void update(List cellZonesDataset) { + List actorsList = new ArrayList<>(getActors()); + for (int i = 0; i < cellZonesDataset.size(); i++) { + vtkDataObject obj = cellZonesDataset.get(i); + Actor actor = actorsList.get(i); + if (obj instanceof vtkPolyData) { + logger.debug("Update polydata {}", names.get(actor)); + VTKUtil.changeDataset(actor, (vtkPolyData) obj); + } else if (obj instanceof vtkUnstructuredGrid) { + logger.debug("Update unstructured_grid {}", names.get(actor)); + VTKUtil.changeDataset(actor, (vtkUnstructuredGrid) obj); + } + } + } + + @Override + public Map getActorsMap() { + return Collections.unmodifiableMap(actors); + } + + public boolean isLoaded() { + return !actors.isEmpty(); + } + +} diff --git a/src/eu/engys/vtk/VTKColors.java b/src/eu/engys/vtk/VTKColors.java new file mode 100644 index 0000000..b205a93 --- /dev/null +++ b/src/eu/engys/vtk/VTKColors.java @@ -0,0 +1,192 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; + +import vtk.vtkLookupTable; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.core.project.mesh.ScalarBarType; +import eu.engys.gui.view3D.Actor; + +public class VTKColors { + + public static final double[] WHITE = toVTK(Color.WHITE); + public static final double[] BLACK = toVTK(Color.BLACK); + public static final double[] RED = toVTK(Color.RED); + public static final double[] GREEN = toVTK(Color.GREEN); + public static final double[] BLUE = toVTK(Color.BLUE); + public static final double[] ORANGE = toVTK(Color.ORANGE); + public static final double[] PINK = toVTK(Color.PINK); + public static final double[] CYAN = toVTK(Color.CYAN); + public static final double[] MAGENTA = toVTK(Color.MAGENTA); + public static final double[] YELLOW = toVTK(Color.YELLOW); + + public static final double AMBIENT = 0.0; + public static final double DIFFUSE = 0.9; + public static final double SPECULAR = 0.1; + public static final double SPECULAR_POWER = 0.8; + + public static final double SELECTION_AMBIENT = 0.0; + public static final double SELECTION_DIFFUSE = 1.0; + public static final double SELECTION_SPECULAR = 0.0; + public static final double SELECTION_SPECULAR_POWER = 0; + + // public static final double[] SELECTION_COLOR = new double[] {1, 0.5, 0}; + public static final double[] SELECTION_COLOR = new double[] { 0.8, 0.1, 0.1 }; + public static final double[] DESELECTION_COLOR = WHITE; + + static class ScalarsColor { + private List actors = new ArrayList<>(); + private FieldItem field; + + ScalarsColor(FieldItem field) { + this.field = field; + } + + public ScalarsColor to(VTKActors actors) { + this.actors.addAll(actors.getActors()); + + if (field.isAutomaticRange()) { + new VTKRangeCalculator(field).calculateRange_Automatically_For(actors); + } else { + // use existing range + } + + return this; + } + + public void apply() { + vtkLookupTable lut = new vtkLookupTable(); + applyTypeToLookupTable(field, lut); + + for (Actor actor : actors) { + actor.setScalarColors(lut, field); + } + } + } + + public static void applyTypeToLookupTable(FieldItem fieldItem, vtkLookupTable table) { + // Vector Mode + if (fieldItem.getComponent() <= 0) { + table.SetVectorModeToMagnitude(); + } else { + table.SetVectorModeToComponent(); + table.SetVectorComponent(fieldItem.getComponent() - 1); + } + + // Range + table.SetRange(fieldItem.getRange()); + + // Colors + ScalarBarType scalarBarType = fieldItem.getScalarBarType(); + List colors = scalarBarType.getColors(fieldItem.getResolution()); + if (scalarBarType.equals(ScalarBarType.RED_TO_BLUE_RAINBOW) || scalarBarType.equals(ScalarBarType.BLUE_TO_RED_RAINBOW)) { + table.SetNumberOfTableValues(fieldItem.getResolution()); + table.SetHueRange(scalarBarType.getColors(-1).get(0)); + table.ForceBuild(); + } else { + table.SetNumberOfTableValues(colors.size()); + for (int i = 0; i < colors.size(); i++) { + double[] values = colors.get(i); + double red = values[0]; + double green = values[1]; + double blue = values[2]; + table.SetTableValue(i, red, green, blue, 1); + } + table.Build(); + } + } + + static class IndexedColor { + private List actors = new ArrayList<>(); + + public IndexedColor to(VTKActors actors) { + this.actors.addAll(actors.getActors()); + return this; + } + + public void apply() { + vtkLookupTable lut = new vtkLookupTable(); + lut.SetTableRange(0, actors.size() - 1); + lut.ForceBuild(); + + int colorIndex = 0; + for (Actor actor : actors) { + double[] color = lut.GetColor(colorIndex++); + actor.setSolidColor(color, 1); + } + lut.Delete(); + } + } + + static class SolidColor { + private double[] color; + private List actors = new ArrayList<>(); + + public SolidColor(double[] color) { + this.color = color; + } + + public SolidColor to(VTKActors actors) { + this.actors.addAll(actors.getActors()); + return this; + } + + public void apply() { + for (Actor actor : actors) { + actor.setSolidColor(color, 1); + } + } + } + + public static SolidColor solidColor(double[] color) { + return new SolidColor(color); + } + + public static IndexedColor indexedColor() { + return new IndexedColor(); + } + + public static ScalarsColor scalarsColor(FieldItem fieldItem) { + return new ScalarsColor(fieldItem); + } + + public static double[] toVTK(Color color) { + return new double[] { color.getRed() / 255.0, color.getGreen() / 255.0, color.getBlue() / 255.0 }; + } + + public static Color toSwing(double[] color) { + return new Color((float) color[0], (float) color[1], (float) color[2]); + } + + public static Color inverse(double[] color) { + return new Color(1 - (float) color[0], 1 - (float) color[1], 1 - (float) color[2]); + } + +} diff --git a/src/eu/engys/vtk/VTKEmptyView3D.java b/src/eu/engys/vtk/VTKEmptyView3D.java new file mode 100644 index 0000000..194c594 --- /dev/null +++ b/src/eu/engys/vtk/VTKEmptyView3D.java @@ -0,0 +1,290 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.vecmath.Point3d; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.inject.Inject; + +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.gui.events.view3D.VolumeReportVisibilityEvent.Kind; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view.ViewElement; +import eu.engys.gui.view3D.CanvasPanel; +import eu.engys.gui.view3D.Controller3D; +import eu.engys.gui.view3D.Geometry3DController; +import eu.engys.gui.view3D.LayerInfo; +import eu.engys.gui.view3D.Mesh3DController; +import eu.engys.gui.view3D.QualityInfo; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.gui.view3D.Selection; +import eu.engys.gui.view3D.widget.Widget; +import eu.engys.util.ApplicationInfo; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.textfields.DoubleField; + +public class VTKEmptyView3D extends JPanel implements CanvasPanel { + + private static final Logger logger = LoggerFactory.getLogger(VTKEmptyView3D.class); + private Icon engysLogo = ResourcesUtil.getIcon(ApplicationInfo.getVendor().toLowerCase() + ".logo.full"); + + private Model model; + private ProgressMonitor monitor; + + private Mesh3DController meshController; + private Geometry3DController geometryController; + private List controllers; + + private RenderPanel renderPanel; + + @Inject + public VTKEmptyView3D(Model model, Set controllers, ProgressMonitor monitor) { + this.model = model; + this.monitor = monitor; + this.controllers = new ArrayList<>(); + this.renderPanel = new RenderPanelAdapter(); + + // this.meshController = new VTKMesh3DController(model, monitor); + // this.geometryController = new VTKGeometry3DController(model, monitor); + + // registerController(meshController); + // registerController(geometryController); + + for (Controller3D c : controllers) { + registerController(c); + } + } + + @Override + public void registerController(Controller3D controller) { + controller.setRenderPanel(renderPanel); + controllers.add(controller); + if (controller instanceof Geometry3DController) { + this.geometryController = (Geometry3DController) controller; + } else if (controller instanceof Mesh3DController) { + this.meshController = (Mesh3DController) controller; + } + } + + public RenderPanel getRenderPanel() { + return renderPanel; + } + + @Override + public void paintComponent(final Graphics g) { + super.paintComponent(g); + final ImageIcon image = (ImageIcon) engysLogo; + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + if (image != null) { + int xCoord = (getWidth() / 2) - (image.getIconWidth() / 2); + int yCoord = (getHeight() / 2) - (image.getIconHeight() / 2); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f)); + g.drawImage(image.getImage(), xCoord, yCoord, null); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); + } + } + + // @Override + // public void handleInitializeFieldsStarted() { + // } + // + // @Override + // public void handleInitializeFieldsFinished() { + // } + // + // @Override + // public void start() { + // } + // + // @Override + // public void stop() { + // } + + @Override + public void stop(Class klass) { + + } + + @Override + public void start(Class klass) { + + } + + @Override + public void save() { + } + + @Override + public void load() { + for (Controller3D context : controllers) { + logger.info("[LOAD] {}", context.getClass().getSimpleName()); + context.loadActors(); + } + } + + // @Override + // public void load(Class klass) { + // } + + @Override + public void geometryToMesh(GeometryToMesh g2m) { + geometryController.clear(); + meshController.clear(); + } + + @Override + public void clear() { + } + + @Override + public JPanel getPanel() { + return this; + } + + @Override + public void showBox(DoubleField[] min, DoubleField[] max, EventActionType actions) { + } + + @Override + public void showPoint(DoubleField[] point, String key, EventActionType action, Color color) { + } + + @Override + public void showPlane(DoubleField[] origin, DoubleField[] normal, EventActionType actions) { + } + + @Override + public void showPlaneDisplay(DoubleField[] origin, DoubleField[] normal, EventActionType actions) { + } + + @Override + public void showAxis(DoubleField[] origin, DoubleField[] normal, EventActionType actions) { + } + + @Override + public void activateSelection(Selection selection, EventActionType action) { + } + + @Override + public void showQualityFields(QualityInfo qualityInfo, EventActionType action) { + } + + @Override + public void showLayersCoverage(LayerInfo layerInfo, JPanel colorBar, EventActionType action) { + } + + @Override + public void layoutComponents() { + } + + @Override + public void updateMinAndMaxForFields(String varName, Point3d min, Point3d max) { + } + + @Override + public void showMinMaxFieldPoints(String key, Kind kind, boolean visible) { + } + + @Override + public Geometry3DController getGeometryController() { + return geometryController; + } + + @Override + public Mesh3DController getMeshController() { + return meshController; + } + + @SuppressWarnings("unchecked") + @Override + public T getController(Class klass) { + for (Controller3D c : controllers) { + if (klass.isInstance(c)) { + return (T) c; + } + } + return null; + } + + @Override + public BoundingBox computeBoundingBox(boolean visibleOnly) { + return VTKUtil.computeBoundingBox(controllers, true); + } + + @Override + public boolean showWidget(Widget widget) { + return false; + } + + @Override + public void showWidgetPanel(Widget widget) { + } + + @Override + public void hideWidgetPanel(Widget widget) { + } + + @Override + public void hideWidget(Widget widget) { + } + + @Override + public void resetZoom() { + } + + @Override + public void loadWidgets() { + } + + @Override + public void applyContext(Class klass) { + } + + @Override + public void dumpContext(Class klass) { + } + +} diff --git a/src/eu/engys/vtk/VTKGeometry3DController.java b/src/eu/engys/vtk/VTKGeometry3DController.java new file mode 100644 index 0000000..b9b1a36 --- /dev/null +++ b/src/eu/engys/vtk/VTKGeometry3DController.java @@ -0,0 +1,535 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.Arguments; +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.core.project.geometry.Geometry; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.Type; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.geometry.surface.Plane; +import eu.engys.core.project.geometry.surface.Region; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.View3DEvent; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Context; +import eu.engys.gui.view3D.Geometry3DController; +import eu.engys.gui.view3D.Geometry3DEventListener; +import eu.engys.gui.view3D.Picker; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.gui.view3D.Representation; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.checkboxtree.VisibleItem; +import eu.engys.vtk.actors.SurfaceToActor; +import eu.engys.vtk.actors.SurfaceToActor.ActorMode; + +public class VTKGeometry3DController implements Geometry3DController, Picker { + + private static final Logger logger = LoggerFactory.getLogger(VTKGeometry3DController.class); + + protected RenderPanel renderPanel; + private final Model model; + private final ProgressMonitor monitor; + private final ActorsMap actorsMap = new ActorsMap(); + + private boolean isLoading; + + @Inject + public VTKGeometry3DController(Model model, ProgressMonitor monitor) { + this.model = model; + this.monitor = monitor; + + EventManager.registerEventListener(new Geometry3DEventListener(this), View3DEvent.class); + } + + @Override + public void setRenderPanel(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + if (renderPanel.getPickManager() != null) { + renderPanel.getPickManager().registerPickerForActors(this); + } + } + + @Override + public void loadActors() { + if (Arguments.load3Dgeometry) { + isLoading = true; + + Geometry geometry = model.getGeometry(); + + monitor.info("-> Actors"); + _addSurfaces(geometry.getSurfaces()); + _addSurfaces(geometry.getLines().toArray()); + + if (geometry.hasBlock()) { + _addSurfaces(geometry.getBlock()); + } + + isLoading = false; + } + } + + @Override + public void addSurfaces(Surface... surfaces) { + _addSurfaces(surfaces); + updatePlaneActors(); + } + + protected void _addSurfaces(Surface... surfaces) { + BoundingBox bb = computeBoundingBox(new Surface[0]); + SurfaceToActor surfaceToActor = new SurfaceToActor(ActorMode.DEFAULT, bb, monitor); + for (Surface surface : surfaces) { + Actor[] actors = surfaceToActor.toActor(surface); + for (Actor a : actors) { + addActor(a); + } + } + } + + private void addActor(Actor actor) { + Surface surface = (Surface) actor.getVisibleItem(); + logger.debug("[ADD ACTOR] {} ({}) hash: {}", actor.getName(), actor.getVisibility() ? "visible" : "hidden", surface.hashCode()); + actorsMap.put(surface, actor); + if (!isLoading) { + renderPanel.addActor(actor); + } + } + + @Override + public void removeSurfaces(Surface... surfaces) { + _removeSurface(surfaces); + renderPanel.renderLater(); + } + + protected void _removeSurface(Surface... surfaces) { + for (Surface surface : surfaces) { + if (surface.hasRegions()) { + _removeSurface(surface.getRegions()); + continue; + } + logger.info("[REM SURFACE] name: {}, type: {}", surface.getName(), surface.getType()); + removeFromMap(surface); + removeFromContext(surface); + } + // updatePlaneActors(); + } + + private void removeFromMap(Surface surface) { + if (actorsMap.contains(surface)) { + Actor oldActor = actorsMap.remove(surface); + renderPanel.removeActor(oldActor); + } else { + // System.err.println("removeFromMap: " + surface.getName() + " NOT FOUND"); + } + } + + private void removeFromContext(Surface surface) { + for (GeometryContext context : contextMap.values()) { + if (context.getActorsMap() != null) { + if (context.getActorsMap().contains(surface)) { + logger.info("[REM SURFACE FROM CONTEXT] name: {}, context: {}", surface.getName(), context); + context.getActorsMap().remove(surface); + } else { + // System.err.println("removeFromContext: " + surface.getName() + " NOT FOUND"); + } + } + } + } + + boolean containsSurface(Surface... surfaces) { + for (Surface surface : surfaces) { + if (!_containsSurface(surface)) + return false; + } + return true; + } + + private boolean _containsSurface(Surface surface) { + if (surface.getType() == Type.STL) { + Stl stl = (Stl) surface; + for (Region region : stl.getSolids()) { + if (!actorsMap.contains(region)) { + return false; + } + } + return true; + } else { + return actorsMap.contains(surface); + } + } + + @Override + public void changeSurface(Surface... surfaces) { + _removeSurface(surfaces); + _addSurfaces(surfaces); + } + + @Override + public void render() { + renderPanel.renderLater(); + } + + @Override + public void zoomReset() { + renderPanel.resetZoomLater(); + } + + @Override + public void transformSurfaces(AffineTransform t, boolean save, Surface... surfaces) { + _transform(t, save, surfaces); + } + + private void _transform(AffineTransform t, boolean save, Surface[] surfaces) { + for (Surface surface : surfaces) { + if (surface.hasRegions()) { + _transform(t, save, surface.getRegions()); + if (save) { + Region region = surface.getRegions()[0]; + surface.setTransformation(new AffineTransform(region.getTransformation())); + } + continue; + } + if (actorsMap.contains(surface)) { + Actor actor = actorsMap.get(surface); + actor.transformActor(save, t); + if (save) { + surface.setTransformation(AffineTransform.fromVTK(actor.getUserTransform())); + } + } + } + } + + public void updateSurfacesSelection(Surface... surfaces) { + logger.debug("[SELECTION] {} surfaces selected {}", surfaces.length, surfaces.length == 1 ? ", selection is: " + surfaces[0].getName() : ""); + + List selection = new ArrayList(); + + _updateSurfaceSelection(surfaces, selection); + + // if (selection.isEmpty()) { + // logger.debug("updateSurfacesSelection: NONE selected!"); + // } else { + if (!actorsMap.isEmpty()) { + renderPanel.selectActors(false, selection.toArray(new Actor[0])); + } + // } + } + + private void _updateSurfaceSelection(Surface[] surfaces, List selection) { + for (Surface surface : surfaces) { + if (surface.hasRegions()) { + _updateSurfaceSelection(surface.getRegions(), selection); + continue; + } + if (surface.isVisible() && actorsMap.contains(surface)) { + selection.add(actorsMap.get(surface)); + } + } + } + + @Override + public void updateSurfaceVisibility(Surface... surfaces) { + logger.debug("[VISIBILITY] {} selected", surfaces.length == 1 ? surfaces[0] : surfaces.length); + for (Surface surface : surfaces) { + if (surface.hasRegions()) { + _updateSurfaceVisibility(surface.getRegions()); + continue; + } + _updateSurfaceVisibility(surface); + } + render(); + } + + private void _updateSurfaceVisibility(Surface... selection) { + for (Surface surface : selection) { + if (actorsMap.contains(surface)) { + Actor actor = actorsMap.get(surface); + actor.setVisibility(surface.isVisible()); + } + } + } + + @Override + public void updateSurfaceColor(Color color, Surface... selection) { + for (Surface surface : selection) { + if (surface.hasRegions()) { + updateSurfaceColor(color, surface.getRegions()); + continue; + } + _updateSurfaceColor(color, surface); + } + } + + private void _updateSurfaceColor(Color color, Surface surface) { + if (getActorsMap().containsKey(surface)) { + Actor actor = getActorsMap().get(surface); + renderPanel.setActorColor(color, actor); + } + } + + @Override + public void geometryToMesh(GeometryToMesh g2m) { + clear(); + clearContext(); + removeActorsFromRenderer(); + + loadActors(); + + for (Actor actor : getActorsList()) { + actor.setVisibility(false); + } + } + + @Override + public void clear() { + deleteActors(); + } + + private void deleteActors() { + for (Actor actor : actorsMap.values()) { + renderPanel.removeActor(actor); + actor.deleteActor(); + } + actorsMap.clear(); + } + + private void removeActorsFromRenderer() { + for (Actor actor : actorsMap.values()) { + renderPanel.removeActor(actor); + } + actorsMap.clear(); + } + + private void updatePlaneActors() { + Surface[] surfaces = model.getGeometry().getSurfaces(); + if (hasPlanes()) { + BoundingBox bb = VTKUtil.computeBoundingBox(getNonPlaneActorsList()); + for (Surface surface : surfaces) { + if (surface.getType().isPlane()) { + double diagonal = bb.getDiagonal(); + double value = Double.isInfinite(diagonal) ? 1 : diagonal > 0 ? diagonal : 1; + + Plane plane = (Plane) surface; + plane.setDiagonal(2 * value); + changeSurface(plane); + render(); + } + } + } + } + + private List getNonPlaneActorsList() { + List list = new ArrayList<>(); + for (Surface surface : actorsMap.keys()) { + if (!surface.getType().isPlane()) { + list.add(actorsMap.get(surface)); + } + } + return list; + } + + private boolean hasPlanes() { + for (Surface surface : model.getGeometry().getSurfaces()) { + if (surface.getType().isPlane()) + return true; + } + return false; + } + + @Override + public BoundingBox computeBoundingBox(Surface... surfaces) { + Collection actors; + if (surfaces.length == 0) { + actors = getListOfSurfaceActors(model.getGeometry().getSurfaces()); + } else { + actors = getListOfSurfaceActors(surfaces); + } + return VTKUtil.computeBoundingBox(actors); + } + + private Collection getListOfSurfaceActors(Surface[] surfaces) { + Collection list = new ArrayList<>(); + for (Surface surface : surfaces) { + if (surface.getType().isStl()) { + Collection l = getListOfSurfaceActors(((Stl) surface).getSolids()); + list.addAll(l); + continue; + } else if (surface.getType().isPlane()) { + continue; + } + list.add(actorsMap.get(surface)); + } + return list; + } + + @Override + public void showInternalMesh() { + hideAllActorsShowInternalMesh(); + } + + @Override + public void hideInternalMesh() { + showAllActorsHideInternalMesh(); + } + + private void hideAllActorsShowInternalMesh() { + for (Actor actor : getActorsList()) { + actor.setVisibility(false); + } + } + + private void showAllActorsHideInternalMesh() { + for (Actor actor : getActorsList()) { + actor.setVisibility(false); + } + } + + @Override + public void showField(FieldItem fieldItem) { + } + + private Map, GeometryContext> contextMap = new HashMap<>(); + private GeometryContext context; + + @Override + public Context getCurrentContext() { + return context; + } + + @Override + public void applyContext(Class klass) { + removeActorsFromRenderer(); + context = contextMap.get(klass); + if (context != null) { + logger.info("[APPLY CONTEXT] for {} is {}", klass.getSimpleName(), context); + setRepresentationFromContext(context); + addActorsFromContext(context); + } else { + logger.info("[APPLY CONTEXT] for {} is NOT FOUND", klass.getSimpleName()); + } + } + + private void setRepresentationFromContext(GeometryContext context) { + renderPanel.setRepresentation(context.getRepresentation()); + } + + private void addActorsFromContext(GeometryContext context) { + ActorsMap map = context.getActorsMap(); + Map visibility = context.getActorsVisibility(); + + if (map != null) { + for (Surface name : map.keys()) { + Actor actor = map.get(name); + if (visibility.get(name).booleanValue()) { + actor.setVisibility(true); + } else { + actor.setVisibility(false); + } + addActor(actor); + } + } + } + + @Override + public void newContext(Class klass) { + GeometryContext context = new GeometryContext(Representation.SURFACE, getActorsMap()); + contextMap.put(klass, context); + logger.info("[NEW CONTEXT] for {} is {}", klass.getSimpleName(), context); + } + + @Override + public void newEmptyContext(Class klass) { + GeometryContext context = new GeometryContext(Representation.SURFACE, Collections. emptyMap()); + contextMap.put(klass, context); + logger.info("[EMPTY CONTEXT] for {} is {}", klass.getSimpleName(), context); + } + + @Override + public void dumpContext(Class klass) { + if (contextMap.containsKey(klass)) { + contextMap.remove(klass).clear(); + } + GeometryContext context = new GeometryContext(renderPanel.getRepresentation(), actorsMap.getDelegate()); + logger.info("[DUMP CONTEXT] for {} is {}", klass.getSimpleName(), context); + contextMap.put(klass, context); + } + + @Override + public void clearContext() { + logger.info("[CLEAR CONTEXT]"); + for (GeometryContext context : contextMap.values()) { + context.clear(); + } + contextMap.clear(); + } + + @Override + public boolean containsActor(Actor pickedActor) { + return actorsMap.containsActor(pickedActor); + } + + @Override + public Collection getActorsList() { + return actorsMap.values(); + } + + @Override + public Map getActorsMap() { + return actorsMap.getDelegate(); + } + + @Override + public boolean canPickCells(Actor pickedActor) { + VisibleItem surface = pickedActor.getVisibleItem(); + return (surface instanceof Stl || surface instanceof Solid); + } + + @Override + public boolean canPickMesh() { + return false; + } + +} diff --git a/src/eu/engys/vtk/VTKInteractor.java b/src/eu/engys/vtk/VTKInteractor.java new file mode 100644 index 0000000..bac3035 --- /dev/null +++ b/src/eu/engys/vtk/VTKInteractor.java @@ -0,0 +1,101 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import vtk.vtkGenericRenderWindowInteractor; +import vtk.vtkInteractorObserver; +import vtk.vtkInteractorStyle; +import vtk.vtkInteractorStyleRubberBand3D; +import vtk.vtkInteractorStyleRubberBandZoom; +import vtk.vtkInteractorStyleTrackballCamera; +import vtk.vtkRenderWindow; +import eu.engys.gui.view3D.Interactor; + +public class VTKInteractor extends vtkGenericRenderWindowInteractor implements Interactor { + + public VTKInteractor(vtkRenderWindow rw) { + vtkInteractorStyle style = new vtkInteractorStyleTrackballCamera(); + SetRenderWindow(rw); + SetInteractorStyle(style); + +// iren.AddObserver("TimerEvent", this, "TimerEvent"); +// iren.AddObserver("CreateTimerEvent", this, "StartTimer"); +// iren.AddObserver("DestroyTimerEvent", this, "DestroyTimer"); +// +// iren.SetDesiredUpdateRate(HIGHEST_RATE); +// iren.SetStillUpdateRate(LOW_RATE); + + } + + @Override + public void setStyleToDefault() { + System.out.println("VTKInteractor.setStyleToDefault()<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); + SetInteractorStyle(new vtkInteractorStyleTrackballCamera()); + } + + @Override + public void setStyleToArea() { + System.out.println("VTKInteractor.setStyleToArea() >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + SetInteractorStyle(new vtkInteractorStyleRubberBand3D()); + } + + @Override + public void setStyleToZoom() { + SetInteractorStyle(new vtkInteractorStyleRubberBandZoom()); + } + + @Override + public void start() { + Start(); + } + + @Override + public void dispose() { + SetRenderWindow(null); + } + + @Override + public void updateSize(int w, int h) { + SetSize(w, h); + // rw.SetSize(w, h); + ConfigureEvent(); + } + + @Override + public void wheelForwardEvent() { + MouseWheelForwardEvent(); + } + + @Override + public void wheelBackwardEvent() { + MouseWheelBackwardEvent(); + } + + @Override + public void addObserver(vtkInteractorObserver widget) { + widget.SetInteractor(this); + } +} diff --git a/src/eu/engys/vtk/VTKInternalMesh.java b/src/eu/engys/vtk/VTKInternalMesh.java new file mode 100644 index 0000000..cc452f8 --- /dev/null +++ b/src/eu/engys/vtk/VTKInternalMesh.java @@ -0,0 +1,268 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +import vtk.vtkCutter; +import vtk.vtkDataObject; +import vtk.vtkExtractGeometry; +import vtk.vtkPlane; +import vtk.vtkTableBasedClipDataSet; +import vtk.vtkUnstructuredGrid; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.vtk.actors.InternalMeshActor; + +public class VTKInternalMesh implements VTKActors { + + private Actor actor; + private RenderPanel renderPanel; + + private vtkCutter slicer; + private vtkExtractGeometry crinkle; + private vtkTableBasedClipDataSet clipper; + + private vtkUnstructuredGrid internalMeshDataset; + + public VTKInternalMesh(ProgressMonitor monitor) { + } + + @Override + public void setRenderPanel(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + } + + public void update(vtkDataObject dataset) { + if (actor != null) { + renderPanel.removeActor(actor); + + load(dataset); + + VisibilityOn(); + + if (slicer != null) { + slicer.SetInputData(internalMeshDataset); + slicer.Update(); + connectActorToSlicer(); + } else if (clipper != null) { + clipper.SetInputData(internalMeshDataset); + clipper.Update(); + connectActorToClipper(); + } else if (crinkle != null) { + crinkle.SetInputData(internalMeshDataset); + crinkle.Update(); + connectActorToCrinkler(); + } + + renderPanel.addActor(actor); + } + } + + public void load(vtkDataObject internalMeshDataset) { + + if (this.internalMeshDataset != null) { + VTKUtil.deleteDataset(this.internalMeshDataset); + } + + if (this.actor != null) { + this.actor.deleteActor(); + } + + this.internalMeshDataset = new vtkUnstructuredGrid(); + this.internalMeshDataset.ShallowCopy((vtkUnstructuredGrid) internalMeshDataset); + this.actor = new InternalMeshActor(this.internalMeshDataset); + } + + public void deleteActors() { + if (actor != null) { + renderPanel.removeActor(actor); + actor.deleteActor(); + actor = null; + + deleteClipper(); + deleteSlicer(); + } + } + + public void removeActorsFromRenderer() { + if (actor != null) { + renderPanel.removeActor(actor); + } + actor = null; + } + + private void deleteSlicer() { + if (slicer != null) { + slicer.RemoveAllInputs(); + slicer.Delete(); + slicer = null; + } + } + + private void deleteClipper() { + if (clipper != null) { + clipper.RemoveAllInputs(); + clipper.Delete(); + clipper = null; + } + } + + private void deleteCrinkle() { + if (crinkle != null) { + crinkle.RemoveAllInputs(); + crinkle.Delete(); + crinkle = null; + } + } + + public void VisibilityOff() { + if (actor != null) { + actor.setVisibility(false); + } + } + + public void VisibilityOn() { + if (actor != null) { + actor.setVisibility(true); + } + } + + public void disconnectFilters() { + actor.setInput(internalMeshDataset); + + deleteClipper(); + deleteSlicer(); + deleteCrinkle(); + } + + public boolean isLoaded() { + return actor != null; + } + + public void show() { + renderPanel.addActor(actor); + } + + @Override + public Collection getActors() { + return actor != null ? Arrays.asList(actor) : Collections. emptyList(); + } + + @Override + public boolean containsActor(Actor pickedActor) { + return false; + } + + public void clip(vtkPlane plane) { + deleteClipper(); + deleteSlicer(); + deleteCrinkle(); + + clipper = new vtkTableBasedClipDataSet(); + clipper.SetInputData(internalMeshDataset); + clipper.SetClipFunction(plane); + clipper.InsideOutOff(); + clipper.Update(); + + connectActorToClipper(); + + renderPanel.renderLater(); + + VTKUtil.gc(false); + } + + private void connectActorToClipper() { + actor.interactiveOff(); + actor.setInput(clipper.GetOutput()); + } + + void crinkle(vtkPlane plane) { + deleteClipper(); + deleteSlicer(); + deleteCrinkle(); + + crinkle = new vtkExtractGeometry(); + crinkle.SetInputData(internalMeshDataset); + crinkle.ExtractInsideOn(); + crinkle.ExtractOnlyBoundaryCellsOn(); + crinkle.ExtractBoundaryCellsOn(); + crinkle.SetImplicitFunction(plane); + crinkle.Update(); + + connectActorToCrinkler(); + + renderPanel.renderLater(); + } + + private void connectActorToCrinkler() { + actor.interactiveOff(); + actor.setInput(crinkle.GetOutput()); + } + + void slice(vtkPlane plane) { + deleteClipper(); + deleteSlicer(); + deleteCrinkle(); + + slicer = new vtkCutter(); + slicer.SetInputData(internalMeshDataset); + slicer.GenerateTrianglesOff(); + slicer.SetCutFunction(plane); + slicer.Update(); + // slicerSetNumberOfContours(nbContours); + + connectActorToSlicer(); + + renderPanel.renderLater(); + } + + private void connectActorToSlicer() { + actor.interactiveOff(); + actor.setInput(slicer.GetOutput()); + } + + void insideOut(boolean selected) { + if (selected) { + clipper.InsideOutOn(); + } else { + clipper.InsideOutOff(); + } + clipper.Update(); + + connectActorToClipper(); + + renderPanel.renderLater(); + } + + public Map getActorsMap() { + return null; + } +} diff --git a/src/eu/engys/vtk/VTKMesh3DController.java b/src/eu/engys/vtk/VTKMesh3DController.java new file mode 100644 index 0000000..a1efa7f --- /dev/null +++ b/src/eu/engys/vtk/VTKMesh3DController.java @@ -0,0 +1,518 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import static eu.engys.core.project.mesh.ScalarBarType.BLUE_TO_RED_RAINBOW; +import static eu.engys.vtk.VTKColors.WHITE; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; + +import javax.inject.Inject; +import javax.swing.JOptionPane; + +import org.apache.commons.collections.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkPlane; +import eu.engys.core.Arguments; +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.core.project.mesh.ScalarBarType; +import eu.engys.core.project.zero.cellzones.CellZone; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.ActorVisibilityEvent; +import eu.engys.gui.events.view3D.View3DEvent; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Context; +import eu.engys.gui.view3D.Mesh3DController; +import eu.engys.gui.view3D.Mesh3DEventListener; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.gui.view3D.Representation; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.vtk.actors.SurfaceToActor; +import eu.engys.vtk.actors.SurfaceToActor.ActorMode; + +public class VTKMesh3DController implements Mesh3DController { + + private static final Logger logger = LoggerFactory.getLogger(Mesh3DController.class); + + private final Model model; + private final ProgressMonitor monitor; + private final VTKPatches patchActors; + private final VTKCellZones cellZonesActors; + private final VTKInternalMesh internalMeshActor; + + private FieldItem currentField = null; + private double currentTimeStep = 0; + private RenderPanel renderPanel; + + @Inject + public VTKMesh3DController(Model model, ProgressMonitor monitor) { + this.model = model; + this.monitor = monitor; + + this.patchActors = new VTKPatches(model); + this.cellZonesActors = new VTKCellZones(model, monitor); + this.internalMeshActor = new VTKInternalMesh(monitor); + + EventManager.registerEventListener(new Mesh3DEventListener(this), View3DEvent.class); + } + + @Override + public void setRenderPanel(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + + patchActors.setRenderPanel(renderPanel); + cellZonesActors.setRenderPanel(renderPanel); + internalMeshActor.setRenderPanel(renderPanel); + + if (renderPanel.getPickManager() != null) { + renderPanel.getPickManager().registerPickerForActors(patchActors); + renderPanel.getPickManager().registerPickerForActors(cellZonesActors); + } + } + + @Override + public void geometryToMesh(GeometryToMesh g2m) { + clear(); + clearContext(); + removeActorsFromRenderer(); + + SurfaceToActor surfaceToActor = new SurfaceToActor(ActorMode.VIRTUALISED, computeBoundingBox(), monitor); + + for (Surface surface : g2m.getWillBePatches()) { + Actor[] actors = surfaceToActor.toActor(surface); + for (Actor a : actors) { + String actorName = g2m.getPatchName(surface); + a.rename(actorName); + patchActors.addActorToPatches(a); + } + } + for (Surface surface : g2m.getWillBeCellZones()) { + Actor[] actors = surfaceToActor.toActor(surface); + if (actors.length == 1) { + String zoneName = g2m.getCellZoneName(surface); + actors[0].rename(zoneName); + cellZonesActors.addActorToZones(actors[0]); + } else { + for (Actor a : actors) { + cellZonesActors.addActorToZones(a); + } + } + } + + VTKColors.indexedColor().to(patchActors).to(cellZonesActors).apply(); + } + + @Override + public void loadActors() { + if (Arguments.load3Dmesh) { + _loadExternalMesh(); + } + } + + @Override + public BoundingBox computeBoundingBox() { + return VTKUtil.computeBoundingBox(patchActors.getActors()); + } + + @Override + public boolean isInternalMeshLoaded() { + return internalMeshActor.isLoaded(); + } + + @Override + public void clear() { + deleteActors(); + this.currentField = null; + this.currentTimeStep = 0; + } + + private void deleteActors() { + patchActors.deleteActors(); + cellZonesActors.deleteActors(); + internalMeshActor.deleteActors(); + } + + private void removeActorsFromRenderer() { + patchActors.removeActorsFromRenderer(); + cellZonesActors.removeActorsFromRenderer(); + internalMeshActor.removeActorsFromRenderer(); + } + + @Override + public void updatePatchesSelection(Patch[] selection) { + patchActors.updateSelection(selection); + } + + @Override + public void updatePatchesVisibility(Patch... selection) { + patchActors.updateVisibility(selection); + } + + @Override + public void updateCellZonesSelection(CellZone[] selection) { + cellZonesActors.selectActors(selection); + } + + @Override + public void updateCellZonesVisibility(CellZone... selection) { + cellZonesActors.updateVisibility(selection); + } + + @Override + @SuppressWarnings("unchecked") + public Collection getActorsList() { + return CollectionUtils.union(patchActors.getActors(), CollectionUtils.union(cellZonesActors.getActors(), internalMeshActor.getActors())); + } + + @Override + public void readTimeSteps() { + VTKOpenFOAMDataset dataset = new VTKOpenFOAMDataset(model, null); + dataset.loadInformations(currentTimeStep); + dataset.clear(); + } + + @Override + public void showField(FieldItem fieldItem) { + this.currentField = fieldItem; + if (FieldItem.SOLID.equals(fieldItem.getName())) { + setColorsToSolid(); + } else if (FieldItem.INDEXED.equals(fieldItem.getName())) { + setColorsToIndexed(); + } else { + setColorsToScalar(); + } + } + + private void setColorsToSolid() { + VTKColors.solidColor(WHITE).to(patchActors).to(cellZonesActors).to(internalMeshActor).apply(); + renderPanel.renderLater(); + } + + private void setColorsToIndexed() { + VTKColors.indexedColor().to(patchActors).to(cellZonesActors).apply(); + VTKColors.solidColor(WHITE).to(internalMeshActor).apply(); + renderPanel.renderLater(); + } + + private void setColorsToScalar() { + VTKColors.scalarsColor(currentField).to(patchActors).to(cellZonesActors).to(internalMeshActor).apply(); + renderPanel.renderLater(); + } + + @Override + public void showTimeStep(final double currentTimeStep) { + this.currentTimeStep = currentTimeStep; + monitor.start("Loading values for timestep " + currentTimeStep, false, new Runnable() { + @Override + public void run() { + final VTKOpenFOAMDataset dataset = new VTKOpenFOAMDataset(model, monitor); + dataset.loadTimeStep(currentTimeStep); + + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + patchActors.update(dataset.getPatchesDataset()); + cellZonesActors.update(dataset.getCellZonesDataset()); + internalMeshActor.update(dataset.getInternalMeshDataset()); + dataset.clear(); + } + }); + monitor.end(); + } + }); + + if (currentField != null && currentField.isScalar()) { + setColorsToScalar(); + } + } + + @Override + public FieldItem getCurrentFieldItem() { + return currentField; + } + + @Override + public double getCurrentTimeStep() { + return currentTimeStep; + } + + // RESOLUTION + @Override + public void setScalarsActorsResolution(int resolution) { + currentField.setResolution(resolution); + setColorsToScalar(); + } + + // SCALARBAR TYPE + @Override + public void setScalarsBarType(ScalarBarType scalarBarType) { + currentField.setScalarBarType(scalarBarType); + setColorsToScalar(); + } + + // RANGE + @Override + public void setAutomaticRangeCalculation(boolean autoRange) { + currentField.setAutomaticRange(autoRange); + setColorsToScalar(); + } + + @Override + public void setManualRangeCalculation(double[] range) { + currentField.setRange(range); + setColorsToScalar(); + } + + // RESET + @Override + public void resetScalarsActorsRangeAndResolutionAndHue() { + currentField.setAutomaticRange(true); + currentField.setResolution(FieldItem.DEFAULT_RESOLUTION); + currentField.setScalarBarType(BLUE_TO_RED_RAINBOW); + + setColorsToScalar(); + } + + @Override + public void showExternalMesh() { + loadExternalMesh(); + if (patchActors.isLoaded()) { + showAllActors(); + } + } + + private void loadExternalMesh() { + monitor.start("Loading mesh", false, new Runnable() { + @Override + public void run() { + _loadExternalMesh(); + monitor.end(); + } + }); + } + + private void _loadExternalMesh() { + if (!patchActors.isLoaded()) { + VTKOpenFOAMDataset dataset = new VTKOpenFOAMDataset(model, monitor); + dataset.loadExternalMesh(0); + + monitor.info("-> Patches"); + patchActors.load(dataset.getPatchesDataset()); + + monitor.info("-> Cell Zones"); + cellZonesActors.load(dataset.getCellZonesDataset()); + + VTKColors.indexedColor().to(patchActors).to(cellZonesActors).apply(); + + dataset.clear(); + } + } + + @Override + public void showInternalMesh() { + if (model.getPatches().isEmpty()) { + JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "No mesh", "Warning", JOptionPane.WARNING_MESSAGE); + return; + } + loadInternalMesh(); + if (internalMeshActor.isLoaded()) { + hideAllActorsShowInternalMesh(); + internalMeshActor.show(); + if (currentField != null) { + showField(currentField); + } else { + VTKColors.solidColor(WHITE).to(internalMeshActor).apply(); + } + } + } + + private void loadInternalMesh() { + if (!internalMeshActor.isLoaded()) { + monitor.start("Loading internal mesh", false, new Runnable() { + @Override + public void run() { + VTKOpenFOAMDataset dataset = new VTKOpenFOAMDataset(model, monitor); + dataset.loadInternalMesh(currentTimeStep); + + monitor.info("-> Internal Mesh Actor"); + internalMeshActor.load(dataset.getInternalMeshDataset()); + + dataset.clear(); + monitor.end(); + } + }); + } + } + + private void hideAllActorsShowInternalMesh() { + cellZonesActors.VisibilityOff(); + patchActors.VisibilityOff(); + internalMeshActor.VisibilityOn(); + + EventManager.triggerEvent(this, new ActorVisibilityEvent(false)); + } + + @Override + public void hideInternalMesh() { + if (internalMeshActor.isLoaded()) { + internalMeshActor.disconnectFilters(); + showAllActorsHideInternalMesh(); + } + } + + private void showAllActorsHideInternalMesh() { + cellZonesActors.VisibilityOff(); + patchActors.VisibilityOn(); + internalMeshActor.VisibilityOff(); + + EventManager.triggerEvent(this, new ActorVisibilityEvent(true)); + } + + @Override + public void clip(vtkPlane plane) { + if (internalMeshActor.isLoaded()) { + internalMeshActor.clip(plane); + } + } + + @Override + public void crinkle(vtkPlane plane) { + if (internalMeshActor.isLoaded()) { + internalMeshActor.crinkle(plane); + } + } + + @Override + public void slice(vtkPlane plane) { + if (internalMeshActor.isLoaded()) { + internalMeshActor.slice(plane); + } + } + + @Override + public void insideOut(boolean selected) { + if (internalMeshActor.isLoaded()) { + internalMeshActor.insideOut(selected); + } + } + + @Override + public void disconnectFiltersFromInternalMesh() { + if (internalMeshActor.isLoaded()) { + internalMeshActor.disconnectFilters(); + render(); + } + } + + @Override + public void render() { + renderPanel.renderLater(); + } + + @Override + public void zoomReset() { + renderPanel.resetZoomLater(); + } + + /* + * CONTEXT + */ + private HashMap, MeshContext> contextMap = new HashMap<>(); + private MeshContext context; + + private boolean allowSelection; + + @Override + public Context getCurrentContext() { + return context; + } + + @Override + public void applyContext(Class klass) { + context = contextMap.get(klass); + removeActorsFromRenderer(); + if (context != null) { + logger.info("[APPLY CONTEXT] for {} is {}", klass.getSimpleName(), context); + renderPanel.setRepresentation(context.getRepresentation()); + this.allowSelection = context.isAllowSelection(); + cellZonesActors.addCellZonesMap(context.getCellzones(), context.getZonesVisibility()); + patchActors.addPatchMap(context.getPatches(), context.getPatchesVisibility()); + } else { + logger.info("[APPLY CONTEXT] for {} is NOT FOUND", klass.getSimpleName()); + } + } + + @Override + public void newContext(Class klass) { + MeshContext context = new MeshContext(Representation.SURFACE, true, cellZonesActors.getActorsMap(), patchActors.getActorsMap()); + contextMap.put(klass, context); + logger.info("[NEW CONTEXT] for {} is {}", klass.getSimpleName(), context); + } + + @Override + public void newEmptyContext(Class klass) { + MeshContext context = new MeshContext(Representation.SURFACE, true, Collections. emptyMap(), Collections. emptyMap()); + contextMap.put(klass, context); + logger.info("[EMPTY CONTEXT] for {} is {}", klass.getSimpleName(), context); + } + + @Override + public void dumpContext(Class klass) { + if (contextMap.containsKey(klass)) { + contextMap.remove(klass).clear(); + } + MeshContext context = new MeshContext(renderPanel.getRepresentation(), allowSelection, cellZonesActors.getActorsMap(), patchActors.getActorsMap()); + contextMap.put(klass, context); + logger.info("[DUMP CONTEXT] for {} is {}", klass.getSimpleName(), context); + } + + @Override + public void clearContext() { + logger.info("[CLEAR CONTEXT]"); + for (MeshContext context : contextMap.values()) { + context.clear(); + } + contextMap.clear(); + } + + public void showAllActors() { + patchActors.addActorsToRenderer(); + cellZonesActors.addActorsToRenderer(); + } + +} diff --git a/src/eu/engys/vtk/VTKMouseHandler.java b/src/eu/engys/vtk/VTKMouseHandler.java new file mode 100644 index 0000000..20ea04e --- /dev/null +++ b/src/eu/engys/vtk/VTKMouseHandler.java @@ -0,0 +1,245 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +import javax.swing.SwingUtilities; + +import vtk.vtkGenericRenderWindowInteractor; +import vtk.vtkInteractorObserver; +import vtk.vtkInteractorStyleRubberBand3D; +import vtk.vtkInteractorStyleRubberBandZoom; +import vtk.vtkInteractorStyleTrackballCamera; + +public class VTKMouseHandler implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener { + + private boolean isDragging = false; + private VTKRenderPanel vtkRenderPanel; + + public VTKMouseHandler(VTKRenderPanel vtkRenderPanel) { + this.vtkRenderPanel = vtkRenderPanel; + } + + private int ctrlPressed(InputEvent e) { + return (e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK ? 1 : 0; + } + + private int shiftPressed(InputEvent e) { + return (e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK ? 1 : 0; + } + + @Override + public void mouseClicked(MouseEvent e) { +// System.out.println("MOUSE CLICKED"); + VTKPickManager pickManager = vtkRenderPanel.getPickManager(); + vtkGenericRenderWindowInteractor iren = (vtkGenericRenderWindowInteractor) vtkRenderPanel.getInteractor(); + + if (SwingUtilities.isLeftMouseButton(e)) { + if (!isDragging) { + int[] pos = iren.GetEventPosition(); + + if (iren.GetInteractorStyle() instanceof vtkInteractorStyleTrackballCamera) { + pickManager.pick(pos[0], pos[1], e.isControlDown(), e.isShiftDown()); + } + } else if(iren.GetInteractorStyle() instanceof vtkInteractorStyleRubberBand3D) { + vtkInteractorStyleRubberBand3D style = (vtkInteractorStyleRubberBand3D) iren.GetInteractorStyle(); + int[] startPosition = style.GetStartPosition(); + int[] endPosition = style.GetEndPosition(); + pickManager.pickArea(startPosition, endPosition, e.isControlDown(), e.isShiftDown()); + } else if(iren.GetInteractorStyle() instanceof vtkInteractorStyleRubberBandZoom) { + iren.SetInteractorStyle(new vtkInteractorStyleTrackballCamera()); + } + } else if (SwingUtilities.isRightMouseButton(e)) { + if (!isDragging) { + int[] pos = iren.GetEventPosition(); + + if (iren.GetInteractorStyle() instanceof vtkInteractorStyleTrackballCamera) { + pickManager.popup(pos[0], pos[1], e); + } + } + } + } + + @Override + public void mousePressed(MouseEvent e) { +// System.out.println("MOUSE_PRESSED"); + vtkRenderPanel.lock(); + vtkGenericRenderWindowInteractor iren = (vtkGenericRenderWindowInteractor) vtkRenderPanel.getInteractor(); + vtkInteractorObserver style = iren.GetInteractorStyle(); + + if (SwingUtilities.isLeftMouseButton(e)) { + iren.SetEventInformationFlipY(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + iren.LeftButtonPressEvent(); + } else if (SwingUtilities.isMiddleMouseButton(e)) { + iren.SetEventInformationFlipY(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + iren.MiddleButtonPressEvent(); + } else if (SwingUtilities.isRightMouseButton(e)) { + if (style instanceof vtkInteractorStyleRubberBand3D) { + iren.SetEventInformationFlipY(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + } else if (style instanceof vtkInteractorStyleTrackballCamera) { + iren.SetEventInformation(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + } + iren.RightButtonPressEvent(); + } + + vtkRenderPanel.unlock(); + + isDragging = false; + } + + @Override + public void mouseReleased(MouseEvent e) { +// System.out.println("MOUSE RELEASED"); + VTKPickManager pickManager = vtkRenderPanel.getPickManager(); + vtkGenericRenderWindowInteractor iren = (vtkGenericRenderWindowInteractor) vtkRenderPanel.getInteractor(); + iren.SetEventInformationFlipY(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + + vtkRenderPanel.lock(); + + if (SwingUtilities.isLeftMouseButton(e)) { + iren.LeftButtonReleaseEvent(); + if(iren.GetInteractorStyle() instanceof vtkInteractorStyleRubberBandZoom) { + iren.SetInteractorStyle(new vtkInteractorStyleTrackballCamera()); + } else if(iren.GetInteractorStyle() instanceof vtkInteractorStyleRubberBand3D) { + vtkInteractorStyleRubberBand3D style = (vtkInteractorStyleRubberBand3D) iren.GetInteractorStyle(); + int[] startPosition = style.GetStartPosition(); + int[] endPosition = style.GetEndPosition(); + pickManager.pickArea(startPosition, endPosition, e.isControlDown(), e.isShiftDown()); + } + } else if (SwingUtilities.isMiddleMouseButton(e)) { + iren.MiddleButtonReleaseEvent(); + } else if (SwingUtilities.isRightMouseButton(e)) { + iren.RightButtonReleaseEvent(); + } + + vtkRenderPanel.unlock(); + + if (isDragging) { + vtkRenderPanel.setHighRendering(); + } + + isDragging = false; + } + + @Override + public void mouseEntered(MouseEvent e) { +// System.out.println("MOUSE_ENTERED"); + vtkGenericRenderWindowInteractor iren = (vtkGenericRenderWindowInteractor) vtkRenderPanel.getInteractor(); + iren.SetEventInformationFlipY(e.getX(), e.getY(), 0, 0, '0', 0, "0"); + + vtkRenderPanel.lock(); + iren.EnterEvent(); + vtkRenderPanel.unlock(); + } + + @Override + public void mouseExited(MouseEvent e) { +// System.out.println("MOUSE_EXITED"); + vtkGenericRenderWindowInteractor iren = (vtkGenericRenderWindowInteractor) vtkRenderPanel.getInteractor(); + iren.SetEventInformationFlipY(e.getX(), e.getY(), 0, 0, '0', 0, "0"); + + vtkRenderPanel.lock(); + iren.LeaveEvent(); + vtkRenderPanel.unlock(); + } + + @Override + public void mouseMoved(MouseEvent e) { + //System.out.println("MOUSE_MOVED"); + vtkGenericRenderWindowInteractor iren = (vtkGenericRenderWindowInteractor) vtkRenderPanel.getInteractor(); + iren.SetEventInformationFlipY(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + + vtkRenderPanel.lock(); + iren.MouseMoveEvent(); + vtkRenderPanel.unlock(); + isDragging = false; + } + + @Override + public void mouseDragged(MouseEvent e) { + //System.out.println("MOUSE_DRAGGED"); + vtkRenderPanel.setLowRendering(); + + vtkGenericRenderWindowInteractor iren = (vtkGenericRenderWindowInteractor) vtkRenderPanel.getInteractor(); + vtkInteractorObserver style = iren.GetInteractorStyle(); + + if (style instanceof vtkInteractorStyleRubberBand3D) { + iren.SetEventInformationFlipY(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + } else if (style instanceof vtkInteractorStyleRubberBandZoom) { + iren.SetEventInformationFlipY(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + } else if (style instanceof vtkInteractorStyleTrackballCamera) { + if (SwingUtilities.isRightMouseButton(e)) { + iren.SetEventInformation(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + } else { + iren.SetEventInformationFlipY(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + } + } + + vtkRenderPanel.lock(); + iren.MouseMoveEvent(); + vtkRenderPanel.unlock(); + + isDragging = true; + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + // System.out.println("MOUSE_WHEEL_MOVED"); + vtkRenderPanel.setLowRendering(); + vtkGenericRenderWindowInteractor iren = (vtkGenericRenderWindowInteractor) vtkRenderPanel.getInteractor(); + iren.SetEventInformationFlipY(e.getX(), e.getY(), ctrlPressed(e), shiftPressed(e), '0', 0, "0"); + + vtkRenderPanel.lock(); + if (e.getWheelRotation() < 0) + iren.MouseWheelForwardEvent(); + else + iren.MouseWheelBackwardEvent(); + vtkRenderPanel.unlock(); + vtkRenderPanel.setHighRendering(); + } + + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + } + + @Override + public void keyReleased(KeyEvent e) { + } + +} diff --git a/src/eu/engys/vtk/VTKOpenFOAMDataset.java b/src/eu/engys/vtk/VTKOpenFOAMDataset.java new file mode 100644 index 0000000..6e8f6c9 --- /dev/null +++ b/src/eu/engys/vtk/VTKOpenFOAMDataset.java @@ -0,0 +1,436 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import static eu.engys.core.project.zero.fields.Fields.U; +import static eu.engys.vtk.VTKUtil.logBlockNames; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkCompositeDataPipeline; +import vtk.vtkCompositeDataSet; +import vtk.vtkDataObject; +import vtk.vtkExecutive; +import vtk.vtkInformation; +import vtk.vtkInformationDoubleVectorKey; +import vtk.vtkMultiBlockDataSet; +import vtk.vtkPolyData; +import vtk.vtkUnstructuredGrid; +import eu.engys.core.project.Model; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.core.project.mesh.FieldItem.DataType; +import eu.engys.core.project.mesh.Mesh; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.vtk.info.VTKDataInformation; + +public class VTKOpenFOAMDataset { + + private static final Logger logger = LoggerFactory.getLogger(VTKOpenFOAMDataset.class); + + private static final String DEFAULT_REGION = "defaultRegion"; + private static final String INTERNAL_MESH = "internalMesh"; + private static final String ZONES = "Zones"; + private static final String FACE_ZONES = "faceZones"; + private static final String CELL_ZONES = "cellZones"; + private static final String PATCHES = "Patches"; + + private Model model; + private ProgressMonitor monitor; + + private vtkUnstructuredGrid internalMeshDataset = null; + private List patchesDataset = new ArrayList<>(); + private List cellZonesDataset = new ArrayList<>(); + + public VTKOpenFOAMDataset(Model model, ProgressMonitor monitor) { + this.model = model; + this.monitor = monitor; + } + + public void loadInformations(double timeStep) { + logger.info("Load mesh informations for timestep {}", timeStep); + VTKOpenFOAMReader reader = new VTKOpenFOAMReader(model, monitor, "Informations of"); + reader.UpdateInformation(); + reader.ReadInternalMeshOff(); + reader.ReadPatchesOff(); + reader.ReadZonesOff(); + reader.setTimeStep(timeStep); + reader.Update(); + + extractInformations(reader, timeStep); + + reader.Delete(); + } + + public List getCellZonesDataset() { + return cellZonesDataset; + } + + public List getPatchesDataset() { + return patchesDataset; + } + + public vtkUnstructuredGrid getInternalMeshDataset() { + return internalMeshDataset; + } + + public void loadInternalMesh(double timeStep) { + VTKOpenFOAMReader reader = new VTKOpenFOAMReader(model, monitor, "Internal"); + reader.UpdateInformation(); + reader.ReadInternalMeshOn(); + reader.ReadPatchesOff(); + reader.ReadZonesOff(); + reader.setTimeStep(timeStep); + reader.Update(); + + vtkMultiBlockDataSet dataset = reader.GetOutput(); + try { + + if (isSingleRegion(dataset)) { + readSingleRegionInternalMesh(dataset); + } else { + readMultiRegionInternalMesh(dataset); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + dataset.Delete(); + reader.Delete(); + } + } + + private void readSingleRegionInternalMesh(vtkMultiBlockDataSet dataset) { + int numberOfBlocks = dataset.GetNumberOfBlocks(); + if (numberOfBlocks > 0) { + logger.debug("READ [SINGLE] [INTERNAL] blocks are: {}", VTKUtil.logBlockNames(dataset)); + + vtkDataObject internalMesh = getBlock(INTERNAL_MESH, dataset); + if (internalMesh != null) { + extractInternalDataset(internalMesh); + } else { + logger.warn("READ [SINGLE] [INTERNAL]: {} NOT FOUND", INTERNAL_MESH); + } + } else { + logger.warn("READ [SINGLE] [INTERNAL]: EMPTY!"); + } + } + + private void readMultiRegionInternalMesh(vtkMultiBlockDataSet dataset) { + int numberOfBlocks = dataset.GetNumberOfBlocks(); + if (numberOfBlocks > 0) { + logger.debug("READ [MULTI] [INTERNAL] blocks are: {}", VTKUtil.logBlockNames(dataset)); + + vtkDataObject defaultRegion = getBlock(DEFAULT_REGION, dataset); + if (defaultRegion != null) { + readSingleRegionInternalMesh((vtkMultiBlockDataSet) defaultRegion); + } else { + logger.warn("READ [MULTI] [INTERNAL]: {} NOT FOUND", DEFAULT_REGION); + } + } else { + logger.warn("READ [MULTI] [INTERNAL]: EMPTY"); + } + } + + public void loadExternalMesh(double timeStep) { + VTKOpenFOAMReader reader = new VTKOpenFOAMReader(model, monitor, "External"); + reader.ReadInternalMeshOff(); + reader.ReadPatchesOn(); + reader.ReadZonesOn(); + reader.setTimeStep(timeStep); + reader.Update(); + + vtkMultiBlockDataSet dataset = reader.GetOutput(); + + try { + if (isSingleRegion(dataset)) { + readSingleRegion(dataset); + } else { + readMultiRegion(dataset); + } + + extractInformations(reader, timeStep); + + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + dataset.Delete(); + reader.Delete(); + } + } + + private boolean isSingleRegion(vtkMultiBlockDataSet dataset) { + int numberOfBlocks = dataset.GetNumberOfBlocks(); + if (numberOfBlocks > 0) { + String blockName = dataset.GetMetaData(0).Get(new vtkCompositeDataSet().NAME()); + return blockName.equals(PATCHES) || blockName.equals(ZONES) || blockName.equals(INTERNAL_MESH) ; + } + return false; + } + + private void readSingleRegion(vtkMultiBlockDataSet dataset) { + int numberOfBlocks = dataset.GetNumberOfBlocks(); + if (numberOfBlocks > 0) { + logger.debug("READ [SINGLE] [EXTERNAL] blocks are: {}", logBlockNames(dataset)); + + vtkDataObject patches = getBlock(PATCHES, dataset); + if (patches != null) { + extractPatchesDataset(patches); + } else { + logger.warn("READ [SINGLE] [PATCHES]: {} NOT FOUND", PATCHES); + } + + vtkDataObject zones = getBlock(ZONES, dataset); + if (zones != null) { + extractZonesDataset(zones); + } else { + logger.warn("READ [SINGLE] [ZONES]: {} NOT FOUND", ZONES); + } + } + } + + private void readMultiRegion(vtkMultiBlockDataSet dataset) { + int numberOfBlocks = dataset.GetNumberOfBlocks(); + if (numberOfBlocks > 0) { + logger.debug("READ [MULTI] [EXTERNAL] blocks are: {}", logBlockNames(dataset)); + + vtkDataObject defaultRegion = getBlock(DEFAULT_REGION, dataset); + if (defaultRegion != null) { + readSingleRegion((vtkMultiBlockDataSet) defaultRegion); + } else { + logger.warn("READ [MULTI] [EXTERNAL]: {} NOT LOADED", DEFAULT_REGION); + } + } else { + logger.warn("READ [MULTI] [EXTERNAL]: EMPTY!"); + } + } + + private vtkDataObject getBlock(String blockName, vtkMultiBlockDataSet dataset) { + int numberOfBlocks = dataset.GetNumberOfBlocks(); + for (int i = 0; i < numberOfBlocks; i++) { + String name = dataset.GetMetaData(i).Get(new vtkCompositeDataSet().NAME()); + if (blockName.equals(name)) { + return dataset.GetBlock(i); + } + } + return null; + } + + private void extractPatchesDataset(vtkDataObject block) { + if (block != null && block instanceof vtkMultiBlockDataSet) { + vtkMultiBlockDataSet dataset = (vtkMultiBlockDataSet) block; + int subblockNumbers = dataset.GetNumberOfBlocks(); + for (int i = 0; i < subblockNumbers; i++) { + vtkDataObject subBlock = dataset.GetBlock(i); + if (subBlock instanceof vtkPolyData) { + this.patchesDataset.add(shallowCopy((vtkPolyData) subBlock)); + } + } + } + } + + public static vtkDataObject shallowCopy(vtkPolyData data) { + vtkPolyData copy = new vtkPolyData(); + copy.ShallowCopy(data); + return copy; + } + + public static vtkUnstructuredGrid shallowCopy(vtkUnstructuredGrid data) { + vtkUnstructuredGrid copy = new vtkUnstructuredGrid(); + copy.ShallowCopy(data); + return copy; + } + + private void extractZonesDataset(vtkDataObject block) { + if (block != null && block instanceof vtkMultiBlockDataSet) { + + vtkMultiBlockDataSet zones = (vtkMultiBlockDataSet) block; + + + vtkDataObject faceZones = getBlock(FACE_ZONES, zones); + if (faceZones != null) { +// extractFaceZonesDataset(zones); + } else { + logger.warn("READ [SINGLE] [FACE ZONES]: {} NOT FOUND", FACE_ZONES); + } + + vtkDataObject cellZones = getBlock(CELL_ZONES, zones); + if (cellZones != null) { + extractCellZonesDataset(cellZones); + } else { + logger.warn("READ [SINGLE] [ZONES]: {} NOT FOUND", ZONES); + } + + + + zones.Delete(); + } + } + + private void extractCellZonesDataset(vtkDataObject block) { + if (block != null && block instanceof vtkMultiBlockDataSet) { + vtkMultiBlockDataSet cellZones = (vtkMultiBlockDataSet) block; + int cellZonesNumber = cellZones.GetNumberOfBlocks(); + for (int i = 0; i < cellZonesNumber; i++) { + vtkDataObject cellZone = cellZones.GetBlock(i); + if (cellZone instanceof vtkUnstructuredGrid) { + logger.warn("Load as a Cell Zone"); + cellZonesDataset.add(shallowCopy((vtkUnstructuredGrid) cellZone)); + } + } + } + } + + private void extractInternalDataset(vtkDataObject block) { + this.internalMeshDataset = shallowCopy((vtkUnstructuredGrid) block); + } + + public void loadTimeStep(double timeStep) { + VTKOpenFOAMReader reader = new VTKOpenFOAMReader(model, monitor, "Time steps of"); + reader.UpdateInformation(); + reader.ReadInternalMeshOn(); + reader.ReadPatchesOn(); + reader.ReadZonesOn(); + reader.setTimeStep(timeStep); + reader.Update(); + + vtkMultiBlockDataSet dataset = reader.GetOutput(); + try { + if (isSingleRegion(dataset)) { + readSingleRegionInternalMesh(dataset); + readSingleRegion(dataset); + } else { + readMultiRegionInternalMesh(dataset); + readMultiRegion(dataset); + } + + extractInformations(reader, timeStep); + + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + dataset.Delete(); + reader.Delete(); + } + } + + private void extractInformations(VTKOpenFOAMReader reader, double timeStep) { + VTKDataInformation info = new VTKDataInformation(); + info.AddFromMultiBlockDataSet(reader.GetOutput()); + + Mesh mesh = model.getMesh(); + mesh.readStatistics(model); + mesh.setBounds(info.getBounds()); + mesh.setMemorySize(info.getMemorySize()); + + mesh.setTimeSteps(getTimeSteps(reader)); + + readFieldItems(reader, mesh); + + mesh.getTimeStepPointFieldsMap().put(Double.valueOf(timeStep), reader.getPointArrayNames()); + mesh.getTimeStepCellFieldsMap().put(Double.valueOf(timeStep), reader.getCellArrayNames()); + + logger.info("Timesteps = {}", mesh.getTimeSteps()); + logger.info("CellFieldsItems = {}", mesh.getCellFieldMap().keySet()); + logger.info("PointFieldsItems = {}", mesh.getPointFieldMap().keySet()); + + mesh.setRegions(getRegions(reader)); + } + + private List getRegions(VTKOpenFOAMReader reader) { + return null; + } + + private void readFieldItems(VTKOpenFOAMReader reader, Mesh mesh) { + for (String newField : reader.getCellArrayNames()) { + Map cellFieldMap = mesh.getCellFieldMap(); + if (newField.startsWith(U)) { + for (int i = 0; i < FieldItem.COMPONENTS.length; i++) { + FieldItem fieldItem = new FieldItem(newField, DataType.CELL, i); + if (!cellFieldMap.containsKey(newField + "_" + i)) { + cellFieldMap.put(newField + "_" + i, fieldItem); + } + } + } else { + FieldItem fieldItem = new FieldItem(newField, DataType.CELL, -1); + if (!cellFieldMap.containsKey(newField)) { + cellFieldMap.put(newField, fieldItem); + } + } + } + for (String newField : reader.getPointArrayNames()) { + Map pointFieldMap = mesh.getPointFieldMap(); + if (newField.startsWith(U)) { + for (int i = 0; i < FieldItem.COMPONENTS.length; i++) { + FieldItem fieldItem = new FieldItem(newField, DataType.POINT, i); + if (!pointFieldMap.containsKey(newField + "_" + i)) { + pointFieldMap.put(newField + "_" + i, fieldItem); + } + } + } else { + FieldItem fieldItem = new FieldItem(newField, DataType.POINT, -1); + if (!pointFieldMap.containsKey(newField)) { + pointFieldMap.put(newField, fieldItem); + } + } + } + } + + private List getTimeSteps(VTKOpenFOAMReader reader) { + vtkExecutive exe = reader.GetExecutive(); + vtkCompositeDataPipeline pipeline = (vtkCompositeDataPipeline) exe; + vtkInformation outInfo = exe.GetOutputInformation(0); + + vtkInformationDoubleVectorKey timeStepsKey = pipeline.TIME_STEPS(); + int nTimeSteps = outInfo.Length(timeStepsKey); // Get the number of time + // steps + List timesteps = new ArrayList<>(); + for (int i = 0; i < nTimeSteps; i++) { + double timeValue = outInfo.Get(timeStepsKey, i); + timesteps.add(Double.valueOf(timeValue)); + } + return timesteps; + } + + public void clear() { + for (vtkDataObject obj : patchesDataset) { + obj.Delete(); + } + for (vtkDataObject obj : cellZonesDataset) { + obj.Delete(); + } + if (internalMeshDataset != null) { + internalMeshDataset.Delete(); + internalMeshDataset = null; + } + patchesDataset.clear(); + cellZonesDataset.clear(); + } +} diff --git a/src/eu/engys/vtk/VTKOpenFOAMReader.java b/src/eu/engys/vtk/VTKOpenFOAMReader.java new file mode 100644 index 0000000..3f76902 --- /dev/null +++ b/src/eu/engys/vtk/VTKOpenFOAMReader.java @@ -0,0 +1,256 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.apache.log4j.Level; + +import vtk.vtkCompositeDataPipeline; +import vtk.vtkDataObject; +import vtk.vtkDataSet; +import vtk.vtkExecutive; +import vtk.vtkMultiBlockDataSet; +import vtk.vtkPOpenFOAMReader; +import eu.engys.core.LoggerUtil; +import eu.engys.core.project.Model; +import eu.engys.core.project.openFOAMProject; +import eu.engys.core.project.zero.fields.Fields; +import eu.engys.core.project.zero.patches.Patches; +import eu.engys.util.VTKSettings; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.progress.SilentMonitor; +import eu.engys.util.progress.VTKProgressMonitorWrapper; + +public class VTKOpenFOAMReader { + + public static void main(String[] args) { + LoggerUtil.initTestLogger(Level.DEBUG); + VTKSettings.LoadAllNativeLibraries(); + Model model = new Model(); + model.init(); +// model.setProject(openFOAMProject.newParallelProject(new File("/home/stefano/ENGYS/examples/HELYX3/singleChannelPump_static_run"))); + model.setProject(openFOAMProject.newParallelProject(new File("/home/stefano/ENGYS/examples/HELYX3/ECOMARINE/testKCS_01_parallel_01"))); + + VTKOpenFOAMReader reader = new VTKOpenFOAMReader(model, new SilentMonitor(), ""); + reader.ReadInternalMeshOff(); + reader.ReadPatchesOff(); + reader.ReadZonesOff(); + reader.setTimeStep(0.0); +// reader.UpdateInformation(); + reader.Update(); +// reader.UpdateExtent(); + + } + + public static boolean decomposePolyhedra; + + private vtkPOpenFOAMReader reader; + private Model model; + + public VTKOpenFOAMReader(Model model, ProgressMonitor monitor, String meshType) { + this.model = model; + + File baseDir = model.getProject().getBaseDir(); + File foamFile = new File(baseDir, " "); + + boolean parallel = model.getProject().isParallel(); + + reader = new vtkPOpenFOAMReader(); + if (parallel) { + reader.SetCaseType(0); + } else { + reader.SetCaseType(1); + } + reader.SetFileName(foamFile.getAbsolutePath()); + reader.CreateCellToPointOn(); + + reader.DisableAllCellArrays(); + reader.DisableAllLagrangianArrays(); + reader.DisableAllPointArrays(); + reader.DisableAllPatchArrays(); + + reader.CacheMeshOff(); + + reader.DecomposePolyhedraOn(); // se qui si mette OFF viene giu' tutto + + reader.ReleaseDataFlagOn(); + + if (monitor != null) { + VTKProgressMonitorWrapper progressWrapper = new VTKProgressMonitorWrapper("", reader, monitor); + reader.AddObserver("StartEvent", progressWrapper, "onStart"); + reader.AddObserver("EndEvent", progressWrapper, "onEnd"); + reader.AddObserver("ProgressEvent", progressWrapper, "onProgress"); + + monitor.setIndeterminate(false); + monitor.setTotal(100); + monitor.info("-> " + meshType + " Mesh"); + } + } + + public void ReadInternalMeshOff() { + reader.SetPatchArrayStatus("internalMesh", 0); + if (decomposePolyhedra) { + reader.DecomposePolyhedraOn(); + } else { + reader.DecomposePolyhedraOff(); + } + } + + public void ReadInternalMeshOn() { + reader.SetPatchArrayStatus("internalMesh", 1); + if (decomposePolyhedra) { + reader.DecomposePolyhedraOn(); + } else { + reader.DecomposePolyhedraOff(); + } + } + + public void ReadPatchesOff() { + Patches patches = model.getPatches().patchesToDisplay(); + for (String patch : patches.toMap().keySet()) { + reader.SetPatchArrayStatus(patch, 0); + } + } + + public void ReadPatchesOn() { + Patches patches = model.getPatches().patchesToDisplay(); + for (String patch : patches.toMap().keySet()) { + reader.SetPatchArrayStatus(patch, 1); + } + } + + public void ReadZonesOn() { + reader.ReadZonesOn(); + } + + public void ReadZonesOff() { + reader.ReadZonesOff(); + } + + public void setTimeStep(double timeValue) { + vtkExecutive exe = reader.GetExecutive(); + vtkCompositeDataPipeline pipeline = (vtkCompositeDataPipeline) exe; + pipeline.SetUpdateTimeStep(0, timeValue); + } + + public void Delete() { + reader.Delete(); + reader = null; + } + + public void Update() { + reader.Update(); + VTKUtil.printDatasetData(reader); + } + + public void UpdateExtent() { + reader.UpdateWholeExtent(); + } + + public void UpdateInformation() { + reader.UpdateInformation(); + } + + public vtkExecutive GetExecutive() { + return reader.GetExecutive(); + } + + public vtkMultiBlockDataSet GetOutput() { + return reader.GetOutput(); + } + + public List getCellArrayNames() { + vtkDataSet dataSet = getAValidDataSet(reader.GetOutput()); + if (dataSet != null) { + return reorderNames(VTKUtil.getCellFields(dataSet)); + } else if (reader.GetNumberOfCellArrays() > 0) { + List list = new ArrayList<>(); + int cellArraysNumber = reader.GetNumberOfCellArrays(); + for (int i = 0; i < cellArraysNumber; i++) { + list.add(reader.GetCellArrayName(i)); + } + return list; + } else { + return Collections.emptyList(); + } + } + + public List getPointArrayNames() { + vtkDataSet dataSet = getAValidDataSet(reader.GetOutput()); + if (dataSet != null) { + return reorderNames(VTKUtil.getPointFields(dataSet)); + } else if (reader.GetNumberOfPointArrays() > 0) { + List list = new ArrayList<>(); + int pointArraysNumber = reader.GetNumberOfPointArrays(); + for (int i = 0; i < pointArraysNumber; i++) { + list.add(reader.GetPointArrayName(i)); + } + return list; + } else { + return Collections.emptyList(); + } + } + + public static List reorderNames(String[] names) { + List list = new ArrayList<>(); + for (String string : names) { + list.add(string); + } + List fields = Arrays.asList(Fields.EDITABLE_FIELDS); + List ordered = new LinkedList(); + for (String field : fields) { + int index = list.indexOf(field); + if (index >= 0) { + ordered.add(list.remove(index)); + } + } + ordered.addAll(list); + + return ordered; + } + + private vtkDataSet getAValidDataSet(vtkMultiBlockDataSet dataSet) { + if (dataSet != null) { + if (dataSet.GetNumberOfBlocks() > 0) { + vtkDataObject block = dataSet.GetBlock(0); + if (block instanceof vtkMultiBlockDataSet) { + return getAValidDataSet((vtkMultiBlockDataSet) block); + } else if (block instanceof vtkDataSet) { + return (vtkDataSet) block; + } + } + } + return null; + } + + +} diff --git a/src/eu/engys/vtk/VTKPatches.java b/src/eu/engys/vtk/VTKPatches.java new file mode 100644 index 0000000..685f133 --- /dev/null +++ b/src/eu/engys/vtk/VTKPatches.java @@ -0,0 +1,202 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkDataObject; +import vtk.vtkPolyData; +import eu.engys.core.project.Model; +import eu.engys.core.project.zero.patches.Patch; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Picker; +import eu.engys.gui.view3D.RenderPanel; + +public class VTKPatches implements VTKActors, Picker { + + private static final Logger logger = LoggerFactory.getLogger(VTKPatches.class); + + private Map actors = new LinkedHashMap<>(); + private Map names = new LinkedHashMap<>(); + + private RenderPanel renderPanel; + private Model model; + + public VTKPatches(Model model) { + this.model = model; + } + + @Override + public void setRenderPanel(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + } + + public void load(List patchesDataset) { + for (int i = 0; i < patchesDataset.size(); i++) { + vtkDataObject obj = patchesDataset.get(i); + if (obj instanceof vtkPolyData) { + Patch patch = model.getPatches().patchesToDisplay().get(i); + patch.setLoaded(true); + patch.setDataSet((vtkPolyData) obj); + addActorToPatches(new PatchActor(patch)); + } + } + } + + void addActorToPatches(Actor actor) { + logger.debug("[ADD ACTOR] {} ({})", actor.getName(), actor.getVisibility() ? "visible" : "hidden"); + actors.put(actor.getName(), actor); + names.put(actor, actor.getName()); + } + + void addActorsToRenderer() { + for (String name : actors.keySet()) { + Actor actor = actors.get(name); + renderPanel.addActor(actor); + } + } + + public void addPatchMap(Map map, Map visibility) { + for (String name : map.keySet()) { + Actor actor = map.get(name); + actor.setVisibility(visibility.get(name)); + addActorToPatches(actor); + renderPanel.addActor(actor); + + } + } + + public void deleteActors() { + for (Actor actor : actors.values()) { + renderPanel.removeActor(actor); + actor.deleteActor(); + } + actors.clear(); + names.clear(); + } + + public void removeActorsFromRenderer() { + for (Actor actor : actors.values()) { + renderPanel.removeActor(actor); + } + actors.clear(); + names.clear(); + } + + public void VisibilityOn() { + for (Actor actor : actors.values()) { + actor.setVisibility(true); + } + } + + public void VisibilityOff() { + for (Actor actor : actors.values()) { + actor.setVisibility(false); + } + } + + @Override + public Collection getActors() { + return actors.values(); + } + + @Override + public boolean containsActor(Actor actor) { + return names.containsKey(actor); + } + +// @Override +// public String getActorName(Actor pickedActor) { +// return names.get(pickedActor); +// } + + @Override + public boolean canPickCells(Actor pickedActor) { + return false; + } + + @Override + public boolean canPickMesh() { + return true; + } + + public void updateSelection(Patch[] patches) { + logger.debug("updateSurfaceVisibility: {} patches selected {}", patches.length, patches.length == 1 ? ", selection is: " + patches[0] : ""); + + List selection = new ArrayList(); + + for (Patch patch : patches) { + String name = patch.getName(); + if (patch.isVisible() && actors.containsKey(name)) { + selection.add(actors.get(name)); + } + } + renderPanel.setLowRendering(); + renderPanel.selectActors(false, selection.toArray(new Actor[0])); + renderPanel.setHighRendering(); + } + + public void updateVisibility(Patch[] selection) { + for (Patch patch : selection) { + String name = patch.getName(); + if (actors.containsKey(name)) { + Actor actor = actors.get(name); + actor.setVisibility(patch.isVisible()); + } + } + renderPanel.renderLater(); + } + + public void update(List patchesDataset) { + List actorsList = new ArrayList<>(getActors()); + for (int i = 0; i < patchesDataset.size(); i++) { + vtkDataObject subset = patchesDataset.get(i); + Actor actor = actorsList.get(i); + if (subset instanceof vtkPolyData) { + logger.debug("Update polydata {}", names.get(actor)); + VTKUtil.changeDataset(actor, (vtkPolyData) subset); + } + } + } + + @Override + public Map getActorsMap() { + return Collections.unmodifiableMap(actors); + } + + public boolean isLoaded() { + return !actors.isEmpty(); + } + +} diff --git a/src/eu/engys/vtk/VTKPickManager.java b/src/eu/engys/vtk/VTKPickManager.java new file mode 100644 index 0000000..b0a0522 --- /dev/null +++ b/src/eu/engys/vtk/VTKPickManager.java @@ -0,0 +1,222 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +import vtk.vtkAreaPicker; +import vtk.vtkCellPicker; +import vtk.vtkGenericRenderWindowInteractor; +import vtk.vtkWorldPointPicker; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.EventManager.Event; +import eu.engys.gui.events.view3D.ActorPopUpEvent; +import eu.engys.gui.events.view3D.ActorSelectionEvent; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.CellPicker; +import eu.engys.gui.view3D.PickInfo; +import eu.engys.gui.view3D.PickManager; +import eu.engys.gui.view3D.Picker; +import eu.engys.gui.view3D.RenderPanel; + +public class VTKPickManager implements PickManager { + + enum PickFor {ACTOR, CELL}; + + private final RenderPanel renderPanel; + private PickFor pickFor; + + public VTKPickManager(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + } + + public void pick(int x, int y, boolean control, boolean shift) { + PickInfo pi = pickCell(x, y); + pi.shift = shift; + pi.control = control; + + if (pickFor == PickFor.ACTOR) { + pickActor(pi); + } else { + pickCell(pi); + } + } + + public void pickArea(int[] startPosition, int[] endPosition, boolean control, boolean shift) { + PickInfo pi = pickArea(startPosition, endPosition); + pi.shift = shift; + pi.control = control; + + if (pickFor == PickFor.ACTOR) { + pickActor(pi); + } else { + pickCell(pi); + } + } + + void pickActor(PickInfo pi) { + if (pi != null && pi.actor != null) { + renderPanel.selectActors(pi.control, pi.actor); + EventManager.triggerEvent(this, getSelectionEvent(pi.control, pi.actor)); + } else { + renderPanel.selectActors(false); + EventManager.triggerEvent(this, getSelectionEvent(false, null)); + } + } + + private Event getSelectionEvent(boolean keep, Actor pickedActor) { + for (Picker picker : pickersForActors) { + if (picker.containsActor(pickedActor)) { + return new ActorSelectionEvent(picker, pickedActor, keep) ; + } + } + return new ActorSelectionEvent(null, null, false); + } + + private void pickCell(final PickInfo pi) { + for (final CellPicker picker : pickersForCells) { + picker.pick(pi); +// ExecUtil.invokeLater(new Runnable() { +// @Override +// public void run() { +// } +// }); + } + } + + private List pickersForActors = new ArrayList<>(); + private List pickersForCells = new ArrayList<>(); + + public void registerPickerForActors(Picker picker) { + pickersForActors.add(picker); + } + + public void registerPickerForCells(CellPicker picker) { + pickersForCells.add(picker); + } + + public void unregisterPickerForCells(CellPicker picker) { + pickersForCells.remove(picker); + } + + public void pickForActors() { + pickFor = PickFor.ACTOR; + } + + public void pickForCells() { + pickActor(null); + pickFor = PickFor.CELL; + } + + public double[] pickPoint() { + int[] position = ((vtkGenericRenderWindowInteractor)((VTKRenderPanel)renderPanel).getInteractor()).GetLastEventPosition(); + return pickPoint(position); + } + + public double[] pickPoint(int[] eventPosition) { + renderPanel.lock(); + vtkWorldPointPicker pick = new vtkWorldPointPicker(); + if (renderPanel instanceof VTKRenderPanel) { + pick.Pick(eventPosition[0], eventPosition[1], 0, ((VTKRenderPanel)renderPanel).GetRenderer()); + } + renderPanel.unlock(); + return pick.GetPickPosition(); + } + + private PickInfo pickCell(int x, int y) { + vtkCellPicker picker = new vtkCellPicker(); + picker.SetTolerance(0.0005); + renderPanel.lock(); + if (renderPanel instanceof VTKRenderPanel) { + picker.Pick(x, y, 0, ((VTKRenderPanel)renderPanel).GetRenderer()); + } + renderPanel.unlock(); + + PickInfo pi = new PickInfo(); + pi.actor = (Actor) picker.GetActor(); + pi.dataSet = picker.GetDataSet(); + pi.cellId = picker.GetCellId(); + pi.cellIJK = picker.GetCellIJK(); + pi.normal = picker.GetPickNormal(); + pi.position = picker.GetPickPosition(); + + return pi; + } + + public PickInfo pickArea(int[] start, int[] end) { + vtkCellPicker centerPicker = new vtkCellPicker(); + centerPicker.SetTolerance(0.0005); + if (renderPanel instanceof VTKRenderPanel) { + centerPicker.Pick((start[0]+end[0])/2, (start[1]+end[1])/2, 0, ((VTKRenderPanel)renderPanel).GetRenderer()); + } + + vtkAreaPicker picker = new vtkAreaPicker(); + if (renderPanel instanceof VTKRenderPanel) { + picker.AreaPick(start[0], start[1], end[0], end[1], ((VTKRenderPanel)renderPanel).GetRenderer()); + } + + PickInfo pi = new PickInfo(); + pi.actor = (Actor) picker.GetActor();//centerPicker.GetActor(); + pi.dataSet = picker.GetDataSet();//centerPicker.GetDataSet(); + pi.cellId = centerPicker.GetCellId(); + pi.cellIJK = null; + pi.normal = null; + pi.position = picker.GetPickPosition(); + pi.frustum = picker.GetFrustum(); + + return pi; + } + + public void popup(int x, int y, MouseEvent event) { + PickInfo pi = pickCell(x, y); + pi.shift = false; + pi.control = false; + + if (pickFor == PickFor.ACTOR) { + popUp(event, pi); + } + } + + void popUp(MouseEvent event, PickInfo pi) { + if (pi != null && pi.actor != null) { + EventManager.triggerEvent(this, getPopUpEvent(event, pi.actor)); + } else { + EventManager.triggerEvent(this, getPopUpEvent(event, null)); + } + } + + private Event getPopUpEvent(MouseEvent event, Actor pickedActor) { + for (Picker picker : pickersForActors) { + if (picker.containsActor(pickedActor)) { + return new ActorPopUpEvent(event, picker, pickedActor) ; + } + } + return new ActorPopUpEvent(event, null, null); + } +} diff --git a/src/eu/engys/vtk/VTKRangeCalculator.java b/src/eu/engys/vtk/VTKRangeCalculator.java new file mode 100644 index 0000000..b83ea52 --- /dev/null +++ b/src/eu/engys/vtk/VTKRangeCalculator.java @@ -0,0 +1,96 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import vtk.vtkDataArray; +import vtk.vtkMapper; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.core.project.mesh.FieldItem.DataType; +import eu.engys.gui.view3D.Actor; + +public class VTKRangeCalculator { + + private FieldItem fieldItem; + + public VTKRangeCalculator(FieldItem fieldItem) { + this.fieldItem = fieldItem; + } + + public void calculateRange_Automatically_For(VTKActors actors) { + if (!actors.getActors().isEmpty()) { + double[] range = new double[] { Double.MAX_VALUE, -Double.MAX_VALUE }; + for (Actor actor : actors.getActors()) { + if (actor.getVisibility()) { + double[] drange = calculateRangeFor(actor); + if (drange != null) { +// System.out.println("VTKRangeCalculator.calculateRange_Automatically_For() " + Arrays.toString(drange)); + range[0] = Math.min(range[0], drange[0]); + range[1] = Math.max(range[1], drange[1]); + } + } + } + if (range[0] <= range[1] ) { +// System.out.println("VTKRangeCalculator.calculateRange_Automatically_For() " + actors.getClass() + " => " + Arrays.toString(range)); + fieldItem.setRange(range); + } + } + } + + public void calculateRange_Automatically_For(Actor actor) { + double[] range = fieldItem.getRange(); + if (actor.getVisibility()) { + double[] drange = calculateRangeFor(actor); + if (drange != null) { + range[0] = drange[0]; + range[1] = drange[1]; + } + + } + fieldItem.setRange(range); + } + + private double[] calculateRangeFor(Actor actor) { + vtkMapper mapper = actor.getMapper(); + mapper.Update(); + + vtkDataArray pScalars = null; + DataType dataType = fieldItem.getDataType(); + String fieldName = fieldItem.getName(); + + if (dataType.isCell()) { + pScalars = mapper.GetInputAsDataSet().GetCellData().GetScalars(fieldName); + } else if (dataType.isPoint()) { + pScalars = mapper.GetInputAsDataSet().GetPointData().GetScalars(fieldName); + } + + if (pScalars != null) { + return fieldItem.getComponent() >= 0 ? pScalars.GetRange(fieldItem.getComponent() - 1) : pScalars.GetRange(); + } + + return null; + } + +} diff --git a/src/eu/engys/vtk/VTKRenderPanel.java b/src/eu/engys/vtk/VTKRenderPanel.java new file mode 100644 index 0000000..4d68bed --- /dev/null +++ b/src/eu/engys/vtk/VTKRenderPanel.java @@ -0,0 +1,595 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.swing.Timer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkActorCollection; +import vtk.vtkAssembly; +import vtk.vtkImageData; +import vtk.vtkLight; +import vtk.vtkObject; +import vtk.vtkPanel; +import vtk.vtkWindowToImageFilter; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.CameraManager; +import eu.engys.gui.view3D.CameraManager.Position; +import eu.engys.gui.view3D.Interactor; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.gui.view3D.Representation; +import eu.engys.util.PrefUtil; +import eu.engys.util.plaf.ILookAndFeel; +import eu.engys.util.ui.ExecUtil; + +public class VTKRenderPanel extends vtkPanel implements RenderPanel { + + private enum LowRendering {ON, OFF} + + private static final Logger logger = LoggerFactory.getLogger(VTKRenderPanel.class); + + public class DelayTimer extends Timer implements ActionListener { + public DelayTimer() { + super(PrefUtil.getInt(PrefUtil._3D_LOCK_INTRACTIVE_TIME, 2000), null); + addActionListener(this); + } + + public void actionPerformed(ActionEvent evt) { + InteractiveOff(); + } + } + + public class CountdownTimer extends Timer implements ActionListener { + + private int delay = PrefUtil.getInt(PrefUtil._3D_LOCK_INTRACTIVE_TIME, 2000); + private int counter = delay; + + public CountdownTimer() { + super(UPDATE_RATE, null); + addActionListener(this); + } + + @Override + public void stop() { + super.stop(); + counter = delay; + } + + public void actionPerformed(ActionEvent evt) { + // System.err.println("Full rendering in "+(counter/1000.0)+"s"); + if (counter <= 0) { + stop(); + return; + } + counter -= UPDATE_RATE; + } + } + + private static final int UPDATE_RATE = 500; + + private static final double LOWEST_RATE = 0.001; + private static final double LOW_RATE = 0.01; + private static final double HIGH_RATE = 5.0; + private static final double HIGHEST_RATE = 15000; + + protected Timer timer = new DelayTimer(); + protected Timer countdown = new CountdownTimer(); + + private Interactor iren; + private Set selection = new HashSet<>(); + + private ILookAndFeel laf; + private VTKMouseHandler handler; + private VTKPickManager pickManager; + + private CameraManager cameraManager; + private LowRendering lowRendering = LowRendering.ON; + + public VTKRenderPanel(ILookAndFeel laf) { + this.laf = laf; + Initialize(); + } + + private void Initialize() { + iren = new VTKInteractor(rw); + + double[] color1 = laf.get3DColor1(); + double[] color2 = laf.get3DColor2(); + double[] colorSelection = laf.get3DSelectionColor(); + + handler = new VTKMouseHandler(this); + addMouseListener(handler); + addMouseMotionListener(handler); + addMouseWheelListener(handler); + addKeyListener(handler); + + pickManager = new VTKPickManager(this); + pickManager .pickForActors(); + + cameraManager = new VTKCameraManager(this); + + ren.GradientBackgroundOn(); + ren.SetBackground(color1); + ren.SetBackground2(color2); + ren.SetGradientBackground(true); + + // ren.RemoveAllLights(); + ren.AutomaticLightCreationOff(); + ren.LightFollowCameraOn(); + + ren.AddLight(createLight( 45, 45)); + ren.AddLight(createLight(-45, 45)); + ren.AddLight(createLight( 45,-45)); + ren.AddLight(createLight(-45,-45)); + + sren.AutomaticLightCreationOn(); + sren.GradientBackgroundOff(); + //iren.start(); + + addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent event) { + updateSize(getWidth(), getHeight()); + } + }); + +// VTKUtil.observe(rw, ""); + +// rw.AddObserver("AbortCheckEvent", this, "AbortCheckEvent"); + } + +// public void AbortCheckEvent() { +// if (rw.GetEventPending() != 0) { +// System.out.println("VTKRenderPanel.AbortCheckEvent() >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "); +// rw.SetAbortRender(1); +// } +// } + + private vtkLight createLight(double elevation, double azimuth) { + vtkLight light = new vtkLight(); + light.SetIntensity(0.5); + light.SetColor(1,1,1); + light.SetLightTypeToCameraLight(); + light.SetDirectionAngle(elevation, azimuth); + light.SwitchOn(); + + return light; + } + + public void Delete() { + iren = null; + super.Delete(); + } + + public void lock() { + logger.trace("-------------------------- LOCK ---------------------------------"); + Lock(); + } + + public void unlock() { + logger.trace("------------------------- UNLOCK --------------------------------"); + UnLock(); + } + + @Override + public void dispose() { + DestroyTimer(); + + iren.dispose(); + iren = null; + + super.dispose(); + + Initialize(); + } + + private void updateSize(int w, int h) { + if (windowset == 1) { + lock(); + iren.updateSize(w,h); + unlock(); + } + } + + public void renderLater() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + Render(); + } + }); + } + + public void renderAndWait() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + Render(); + } + }); + } + + public void resetZoomLater() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + zoomReset(); + } + }); + } + + public void resetZoomAndWait() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + zoomReset(); + } + }); + } + + @Override + public void setHighRendering() { +// System.out.println("VTKRenderPanel.setHighRendering()"); + if (iren == null) { + return; + } + + if (lowRendering == LowRendering.OFF) { + return; + } + + StartTimer(); + } + + @Override + public void setLowRendering() { +// System.out.println("VTKRenderPanel.setLowRendering()"); + if (iren == null) { + return; + } + + if (lowRendering == LowRendering.OFF) { + return; + } + + DestroyTimer(); + + InteractiveOn(); + } + + private void InteractiveOn() { +// System.err.println("VTKRenderPanel.InteractiveOn()"); + lock(); + + for (Actor actor : getAllActors()) { + actor.interactiveOn(); + } + + unlock(); + } + + private void InteractiveOff() { +// System.err.println("VTKRenderPanel.InteractiveOff()"); + lock(); + + for (Actor actor : getAllActors()) { + actor.interactiveOff(); + } + + unlock(); + renderLater(); + } + + private void StartTimer() { + if (timer.isRunning()) { + timer.stop(); + countdown.stop(); + } + + countdown.start(); + + int delay = PrefUtil.getInt(PrefUtil._3D_LOCK_INTRACTIVE_TIME, 2000); + timer.setDelay(delay); + timer.setRepeats(false); + timer.start(); + } + + public void DestroyTimer() { + if (timer.isRunning()) { + timer.stop(); + countdown.stop(); + } + } + + @Override + public void wheelForward() { + if (iren == null) + return; + lock(); + iren.wheelForwardEvent(); + unlock(); + } + + @Override + public void wheelBackward() { + if (iren == null) + return; + lock(); + iren.wheelBackwardEvent(); + unlock(); + } + + @Override + public void zoomReset() { + if (iren == null) + return; + lock(); + GetRenderer().ResetCamera(); + unlock(); + renderLater(); + } + + @Override + public void setCameraPosition(Position pos) { + cameraManager.setCameraPosition(pos); + } + + @Override + public void addActor(vtkAssembly actor) { + lock(); + GetRenderer().AddActor(actor); + unlock(); + } + + @Override + public void addActor(Actor actor) { + lock(); + actor.setRepresentation(representation); + GetRenderer().AddActor(actor.getActor()); + correctSelectionVisualization(); + unlock(); + } + + private void correctSelectionVisualization() { + int memory_limit = PrefUtil.getInt(PrefUtil._3D_TRANSPARENCY_MEMORY, 10 * 1024); + int size = 0; + for (Actor actor : getAllActors()) { + size += actor.getMemorySize(); + } + + logger.debug("Total Memory Size: {}", size); + + for (Actor actor : getAllActors()) { + if (size > memory_limit) { + actor.deselectedStateOff(); + } else { + actor.deselectedStateOn(); + } + } + } + + @Override + public void removeActor(Actor actor) { + lock(); + GetRenderer().RemoveActor(actor.getActor()); + GetSelectionRenderer().RemoveActor(actor.getSelectionActor()); + correctSelectionVisualization(); + unlock(); + } + + @Override + public void clearSelection() { + lock(); + for (Actor actor : getAllActors()) { + actor.restoreFromSelection(); + } + unlock(); + } + + public void selectActors(boolean keepSelected, Actor... actors) { + setLowRendering(); + lock(); + + if (!keepSelected) { + selection.clear(); + } + + List toSelect = new ArrayList<>(); + if (keepSelected) { + for (Actor actor : actors) { + if (selection.contains(actor)) { + selection.remove(actor); + } else { + toSelect.add(actor); + } + } + } else { + toSelect.addAll(Arrays.asList(actors)); + } + + selection.addAll(toSelect); + + for (Actor actor : getAllActors()) { +// actor.interactiveOn(); + if (selection.size() > 0) { + if (selection.contains(actor)) { + actor.selectActor(); + GetSelectionRenderer().AddActor(actor.getSelectionActor()); + } else { + actor.deselectActor(); + GetSelectionRenderer().RemoveActor(actor.getSelectionActor()); + } + } else { + GetSelectionRenderer().RemoveActor(actor.getSelectionActor()); + actor.restoreFromSelection(); + } + } + unlock(); +// renderLater(); + Render(); +// renderAndWait(); + setHighRendering(); + } + + private List getAllActors() { + List list = new ArrayList<>(); + vtkActorCollection actors = ren.GetActors(); + for (int a = 0; a < actors.GetNumberOfItems(); a++) { + vtkObject item = actors.GetItemAsObject(a); + if (item instanceof Actor) { + list.add((Actor) item); + } + } + + return list; + } + + private List getSelectionActors() { + List list = new ArrayList<>(); + vtkActorCollection actors = sren.GetActors(); + for (int a = 0; a < actors.GetNumberOfItems(); a++) { + vtkObject item = actors.GetItemAsObject(a); + System.out.println("VTKRenderPanel.getSelectionActors() " +item); + } + + return list; + } + + + @Override + public void setActorColor(Color c, Actor... actors) { + if (c == null) + return; + + lock(); + double[] color = new double[] { c.getRed() / 255.0, c.getGreen() / 255.0, c.getBlue() / 255.0 }; + double opacity = c.getAlpha() / 255.0; + + for (Actor actor : actors) { + if (actor == null) + continue; + actor.setSolidColor(color, opacity); + + } + unlock(); + } + + @Override + public void clear() { + selection.clear(); + } + + Representation representation = Representation.WIREFRAME; + + public void setRepresentation(Representation representation) { + this.representation = representation; + } + + public Representation getRepresentation() { + return representation; + } + + @Override + public void changeRepresentation(Representation r) { + lock(); + setRepresentation(r); + for (Actor actor : getAllActors()) { + actor.setRepresentation(representation); + } + unlock(); + Render(); + } + + @Override + public void ParallelProjectionOn() { + lock(); + GetRenderer().GetActiveCamera().ParallelProjectionOn(); + unlock(); + Render(); + } + + @Override + public void ParallelProjectionOff() { + lock(); + GetRenderer().GetActiveCamera().ParallelProjectionOff(); + unlock(); + Render(); + } + +// @Override +// public vtkRenderer GetRenderer() { +// return super.GetRenderer(); +// } +// +// @Override +// public vtkRenderWindow GetRenderWindow() { +// return super.GetRenderWindow(); +// } + + @Override + public Interactor getInteractor() { + return this.iren; + } + + @Override + public VTKPickManager getPickManager() { + return pickManager; + } + + @Override + public vtkImageData toImageData() { + vtkWindowToImageFilter w2i = new vtkWindowToImageFilter(); + w2i.SetInput(rw); + w2i.Modified(); + rw.Render(); + w2i.Update(); + + return w2i.GetOutput(); + } + + @Override + public void lowRenderingOn() { + this.lowRendering = LowRendering.ON; + } + + @Override + public void lowRenderingOff() { + this.lowRendering = LowRendering.OFF; + } +} diff --git a/src/eu/engys/vtk/VTKUtil.java b/src/eu/engys/vtk/VTKUtil.java new file mode 100644 index 0000000..de34be4 --- /dev/null +++ b/src/eu/engys/vtk/VTKUtil.java @@ -0,0 +1,395 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkAlgorithm; +import vtk.vtkAlgorithmOutput; +import vtk.vtkCellData; +import vtk.vtkCleanPolyData; +import vtk.vtkCompositeDataPipeline; +import vtk.vtkCompositeDataSet; +import vtk.vtkDataArray; +import vtk.vtkDataObject; +import vtk.vtkDataSet; +import vtk.vtkDataSetSurfaceFilter; +import vtk.vtkDoubleArray; +import vtk.vtkExecutive; +import vtk.vtkInformation; +import vtk.vtkInformationDoubleKey; +import vtk.vtkInformationDoubleVectorKey; +import vtk.vtkMapper; +import vtk.vtkMultiBlockDataSet; +import vtk.vtkObject; +import vtk.vtkOpenFOAMReader; +import vtk.vtkPointData; +import vtk.vtkPolyData; +import vtk.vtkPolyDataAlgorithm; +import vtk.vtkPolyDataMapper; +import vtk.vtkReferenceInformation; +import vtk.vtkStreamingDemandDrivenPipeline; +import vtk.vtkTrivialProducer; +import vtk.vtkUnstructuredGrid; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Controller3D; +import eu.engys.util.Util; +import eu.engys.util.VTKSettings; + +public class VTKUtil { + + private static final Logger logger = LoggerFactory.getLogger(VTKUtil.class); + + public static BoundingBox computeBoundingBox(List controllers, boolean visibleOnly) { + + List allVisibleActors = new ArrayList<>(); + + for (Controller3D controller : controllers) { + Collection actors = controller.getActorsList(); + for (Actor vtkActor : actors) { + if (!visibleOnly || (visibleOnly && vtkActor.getVisibility())) { + allVisibleActors.add(vtkActor); + } + } + } + + return computeBoundingBox(allVisibleActors); + } + + public static BoundingBox computeBoundingBox(Collection actors) { + if(Util.isVarArgsNotNull(actors.toArray(new Actor[0]))){ + double xmin = Double.MAX_VALUE; + double xmax = -Double.MAX_VALUE; + double ymin = Double.MAX_VALUE; + double ymax = -Double.MAX_VALUE; + double zmin = Double.MAX_VALUE; + double zmax = -Double.MAX_VALUE; + + for (Actor actor : actors) { + if (actor != null) { + double[] bounds = actor.getBounds(); + xmin = Math.min(xmin, bounds[0]); + xmax = Math.max(xmax, bounds[1]); + ymin = Math.min(ymin, bounds[2]); + ymax = Math.max(ymax, bounds[3]); + zmin = Math.min(zmin, bounds[4]); + zmax = Math.max(zmax, bounds[5]); + } + } + + return new BoundingBox(xmin, xmax, ymin, ymax, zmin, zmax); + } else { + return new BoundingBox(0, 0, 0, 0, 0, 0); + } + + } + + public static void printDatasetData(vtkOpenFOAMReader reader) { + logger.debug("[reader] ---------------" + reader.GetFileName() + "----------------"); + int patchesNumber = reader.GetNumberOfPatchArrays(); + logger.debug("[reader] Patches Number: " + patchesNumber); + logger.debug("[reader] Patches List: "); + for (int i = 0; i < patchesNumber; i++) { + String patchName = reader.GetPatchArrayName(i); + int status = reader.GetPatchArrayStatus(patchName); + logger.debug("[reader] (" + i + ") " + patchName + ", status: " + (status == 0 ? "disabled" : "enabled")); + } + + int cellArraysNumber = reader.GetNumberOfCellArrays(); + logger.debug("[reader] Cell Arrays Number: " + cellArraysNumber); + logger.debug("[reader] Cell Arrays List: "); + for (int i = 0; i < cellArraysNumber; i++) { + String cellArrayName = reader.GetCellArrayName(i); + int status = reader.GetCellArrayStatus(cellArrayName); + logger.debug("[reader] (" + i + ") " + cellArrayName + ", status: " + (status == 0 ? "disabled" : "enabled")); + } + + int pointArraysNumber = reader.GetNumberOfPointArrays(); + logger.debug("[reader] Point Arrays Number: " + pointArraysNumber); + logger.debug("[reader] Point Arrays List: "); + for (int i = 0; i < pointArraysNumber; i++) { + String pointArrayName = reader.GetPointArrayName(i); + int status = reader.GetPointArrayStatus(pointArrayName); + logger.debug("[reader] (" + i + ") " + pointArrayName + ", status: " + (status == 0 ? "disabled" : "enabled")); + } + + logger.debug("[reader] Decompose Polyhedra: " + reader.GetDecomposePolyhedra()); + + int lagrangianArraysNumber = reader.GetNumberOfLagrangianArrays(); + logger.debug("[reader] Lagrangian Arrays Number: " + lagrangianArraysNumber); + logger.debug("[reader] Lagrangian Arrays List: "); + for (int i = 0; i < lagrangianArraysNumber; i++) { + String lagrangianArrayName = reader.GetLagrangianArrayName(i); + int status = reader.GetLagrangianArrayStatus(lagrangianArrayName); + logger.debug("[reader] (" + i + ") " + lagrangianArrayName + ", status: " + (status == 0 ? "disabled" : "enabled")); + } + + logger.debug("[reader] Read Zones: " + reader.GetReadZones()); + + vtkDoubleArray times = reader.GetTimeValues(); + if (times != null) { + logger.debug("[reader] Time Values: ["); + for (int i = 0; i < times.GetSize(); i++) { + logger.debug("[Time]" + times.GetValue(i) + ", "); + } + logger.debug("]"); + } else { + // reader.UpdateInformation(); // Scan time steps and create + // metadata + vtkExecutive exe = reader.GetExecutive(); + vtkInformation outInfo = exe.GetOutputInformation(0); + vtkInformationDoubleVectorKey timeStepsKey = new vtkStreamingDemandDrivenPipeline().TIME_STEPS(); + int nTimeSteps = outInfo.Length(timeStepsKey); // Get the number of + // time steps + logger.debug("[reader] Time Values: " + nTimeSteps); + for (int i = 0; i < nTimeSteps; i++) { + double timeValue = outInfo.Get(timeStepsKey, i); // Get the i-th + // time value + logger.debug("[reader] Step: " + i + ", Value: " + timeValue); + } + } + + vtkExecutive exe = reader.GetExecutive(); + vtkCompositeDataPipeline pipeline = (vtkCompositeDataPipeline) exe; + vtkInformation outInfo = exe.GetOutputInformation(0); + vtkInformationDoubleVectorKey TIME_STEPS = pipeline.TIME_STEPS(); + vtkInformationDoubleKey UPDATE_TIME_STEP = pipeline.UPDATE_TIME_STEP(); + + int nTimeSteps = outInfo.Length(TIME_STEPS); // Get the number of time steps + logger.debug("[pipeline] Time Values: " + nTimeSteps); + logger.debug("[pipeline] Time Values: current is " + outInfo.Get(UPDATE_TIME_STEP)); + for (int i = 0; i < nTimeSteps; i++) { + double timeValue = outInfo.Get(TIME_STEPS, i); // Get the i-th time value + logger.debug("[pipeline] Step: " + i + ", Value: " + timeValue); + + } + + vtkMultiBlockDataSet dataset = reader.GetOutput(); + int blocksNumber = dataset.GetNumberOfBlocks(); + logger.debug("[dataset]\tBlocks Number: " + blocksNumber); + for (int i = 0; i < blocksNumber; i++) { + vtkDataObject block = dataset.GetBlock(i); + String name = dataset.GetMetaData(i).Get(new vtkCompositeDataSet().NAME()); + readBlock(block, name, i, "\t"); + } + logger.debug("[reader] ---------------" + reader.GetFileName() + "----------------"); + } + + private static void readBlock(vtkDataObject block, String name, int i, String indent) { + if (block instanceof vtkMultiBlockDataSet) { + vtkMultiBlockDataSet multiBlockDataSet = (vtkMultiBlockDataSet) block; + int nBlocks = multiBlockDataSet.GetNumberOfBlocks(); + logger.debug("[dataset]" + indent + "Block {} '{}': MultiBlockDataset, {} Sub Blocks", i, name, nBlocks); + for (int j = 0; j < nBlocks; j++) { + vtkDataObject subBlock = multiBlockDataSet.GetBlock(j); + String subName = multiBlockDataSet.GetMetaData(j).Get(new vtkCompositeDataSet().NAME()); + readBlock(subBlock, subName, j, indent + indent); + } + } else if (block instanceof vtkUnstructuredGrid) { + logger.debug("[dataset]" + indent + "Block {} '{}': UnstructuredGrid", i, name); + readFields((vtkDataSet) block, indent); + } else if (block instanceof vtkPolyData) { + logger.debug("[dataset]" + indent + "Block {} '{}': PolyData", i, name); + readFields((vtkDataSet) block, indent); + } else { + logger.debug("[dataset]" + indent + "Block {} '{}': OTHER {}", i, name, block); + } + } + + private static void readFields(vtkDataSet dataSet, String indent) { + String[] pointFields = getPointFields(dataSet); + logger.debug("[dataset]" + indent + "\tPointData Arrays Number: " + pointFields.length); + for (int i = 0; i < pointFields.length; i++) { + logger.debug("[dataset]" + indent + "\t\t array " + i + ": " + pointFields[i]); + } + String[] cellFields = getCellFields(dataSet); + logger.debug("[dataset]" + indent + "\tCellData Arrays Number: " + cellFields.length); + for (int i = 0; i < cellFields.length; i++) { + logger.debug("[dataset]" + indent + "\t\t array " + i + ": " + cellFields[i]); + } + } + + public static String[] getPointFields(vtkDataSet dataSet) { + vtkPointData pointData = dataSet.GetPointData(); + String[] fields = new String[pointData.GetNumberOfArrays()]; + for (int i = 0; i < fields.length; i++) { + fields[i] = pointData.GetArrayName(i); + } + return fields; + } + + public static String[] getCellFields(vtkDataSet dataSet) { + vtkCellData cellData = dataSet.GetCellData(); + String[] fields = new String[cellData.GetNumberOfArrays()]; + for (int i = 0; i < fields.length; i++) { + fields[i] = cellData.GetArrayName(i); + } + return fields; + } + + public static void gc(boolean debug) { + if (VTKSettings.librariesAreLoaded()) { + vtkReferenceInformation info = vtkObject.JAVA_OBJECT_MANAGER.gc(debug); + if (debug) { + logger.debug("K: " + info.listKeptReferenceToString()); + logger.debug("R: " + info.listRemovedReferenceToString()); + } + } + } + + public static vtkPolyData geometryFilter(vtkUnstructuredGrid dataset) { + vtkUnstructuredGrid input = new vtkUnstructuredGrid(); + input.ShallowCopy(dataset); + + vtkDataSetSurfaceFilter filter = new vtkDataSetSurfaceFilter(); + filter.SetInputData(input); + filter.PassThroughCellIdsOn(); + filter.PassThroughPointIdsOn(); + filter.Update(); + input.Delete(); + + vtkPolyData output = filter.GetOutput(); + filter.Delete(); + + return output; + } + + public static vtkPolyData repairDataSet(vtkPolyData dataset) { + vtkCleanPolyData clean = new vtkCleanPolyData(); + // clean.ConvertLinesToPointsOff(); //def: on + // clean.ConvertPolysToLinesOff(); //def: on + // clean.ConvertStripsToPolysOff(); //def: on + // clean.PieceInvariantOff(); //def: on + // clean.PointMergingOff(); //def: on + // clean.SetAbsoluteTolerance(0); //def: 1.0 + // clean.SetTolerance(0);//def: 0.0 + // clean.ToleranceIsAbsoluteOn(); //def: off + clean.SetInputData(dataset); + clean.Update(); + + return clean.GetOutput(); + } + + public static void exit() { + vtkObject.JAVA_OBJECT_MANAGER.deleteAll(); + } + + public static void changeDataset(Actor actor, vtkPolyData subset) { + vtkMapper mapper = actor.getMapper(); + ((vtkPolyDataMapper) mapper).SetInputData((vtkPolyData) subset); + } + + public static void changeDataset(Actor actor, vtkUnstructuredGrid subset) { + vtkMapper mapper = actor.getMapper(); + vtkAlgorithmOutput filterOutput = mapper.GetInputConnection(0, 0); + + if (filterOutput.GetProducer() instanceof vtkPolyDataAlgorithm ) { + vtkPolyDataAlgorithm filter = (vtkPolyDataAlgorithm) filterOutput.GetProducer(); + + VTKUtil.deleteDataset(filter.GetInput()); + filter.SetInputData(subset); + mapper.Update(); + } else if (filterOutput.GetProducer() instanceof vtkTrivialProducer ) { + vtkAlgorithm filter = (vtkAlgorithm) filterOutput.GetProducer(); + filter.SetInputDataObject(subset); + mapper.Update(); + } else { + logger.warn("CANNOT CHANGE DATASET FOR: {}", "unstructured grid"); + } + } + + public static void deleteDataset(vtkDataObject dataObject) { + if (dataObject instanceof vtkDataSet) { + vtkDataSet dataSet = (vtkDataSet) dataObject; + vtkPointData pointData = dataSet.GetPointData(); + vtkDataArray pScalars = pointData.GetScalars(); + if (pScalars != null) + pScalars.Delete(); + pointData.Delete(); + + vtkCellData cellData = dataSet.GetCellData(); + vtkDataArray cScalars = cellData.GetScalars(); + if (cScalars != null) + cScalars.Delete(); + cellData.Delete(); + + dataSet.Delete(); + } else { + System.err.println("NOT A DATASET"); + } + } + + public static void observe(vtkObject obj, String label) { + ConsoleObserver o = new ConsoleObserver(obj, label); + + obj.AddObserver("AbortCheckEvent", o, "AbortCheckEvent"); + obj.AddObserver("StartEvent", o, "StartEvent"); + obj.AddObserver("EndEvent", o, "EndEvent"); + obj.AddObserver("ProgressEvent", o, "ProgressEvent"); + obj.AddObserver("TimerEvent", o, "TimerEvent"); + obj.AddObserver("ConfigureEvent", o, "ConfigureEvent"); + obj.AddObserver("ErrorEvent", o, "ErrorEvent"); + obj.AddObserver("WarningEvent", o, "WarningEvent"); + } + + static class ConsoleObserver { + private vtkObject obj; + private String label; + private long time = 0L; + public ConsoleObserver(vtkObject obj, String label) { + this.obj = obj; + this.label = label; + } + public void AbortCheckEvent() { System.err.println("+++ AbortCheckEvent +++" + obj.GetClassName() + " - " + label); } + public void StartEvent() { System.err.println("StartEvent " + obj.GetClassName() + " - " + label); this.time = System.currentTimeMillis();} + public void EndEvent() { System.err.println("EndEvent " + obj.GetClassName() + " - " + label + " - ET: " + (System.currentTimeMillis() - time)/1000D + " sec");} + public void ProgressEvent() { System.err.println("ProgressEvent " + obj.GetClassName() + " - " + label);} + public void ConfigureEvent() { System.err.println("ConfigureEvent " + obj.GetClassName() + " - " + label);} + public void TimerEvent() { System.err.println("TimerEvent " + obj.GetClassName() + " - " + label);} + public void ErrorEvent() { System.err.println("ErrorEvent " + obj.GetClassName() + " - " + label);} + public void WarningEvent() { System.err.println("WarningEvent " + obj.GetClassName() + " - " + label);} + } + + public static String logBlockNames(vtkMultiBlockDataSet dataset) { + StringBuilder sb = new StringBuilder(); + int numberOfBlocks = dataset.GetNumberOfBlocks(); + for (int i = 0; i < numberOfBlocks; i++) { + String name = dataset.GetMetaData(i).Get(new vtkCompositeDataSet().NAME()); + sb.append("(" + i + ") "); + sb.append(name); + sb.append(" "); + } + + return sb.toString(); + } +} diff --git a/src/eu/engys/vtk/VTKView3D.java b/src/eu/engys/vtk/VTKView3D.java new file mode 100644 index 0000000..444ce12 --- /dev/null +++ b/src/eu/engys/vtk/VTKView3D.java @@ -0,0 +1,584 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.vecmath.Point3d; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.controller.GeometryToMesh; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.core.project.Model; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.gui.events.EventManager; +import eu.engys.gui.events.view3D.View3DEvent; +import eu.engys.gui.events.view3D.VolumeReportVisibilityEvent.Kind; +import eu.engys.gui.view.View3DElement; +import eu.engys.gui.view.ViewElement; +import eu.engys.gui.view3D.CanvasPanel; +import eu.engys.gui.view3D.Controller3D; +import eu.engys.gui.view3D.Geometry3DController; +import eu.engys.gui.view3D.LayerInfo; +import eu.engys.gui.view3D.Mesh3DController; +import eu.engys.gui.view3D.QualityInfo; +import eu.engys.gui.view3D.Selection; +import eu.engys.gui.view3D.widget.Widget; +import eu.engys.util.plaf.ILookAndFeel; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.ExecUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.vtk.widgets.AxesWidget; +import eu.engys.vtk.widgets.AxisWidgetManager; +import eu.engys.vtk.widgets.ExtractSelectionWidget; +import eu.engys.vtk.widgets.LayersCoverageWidget; +import eu.engys.vtk.widgets.LogoWidget; +import eu.engys.vtk.widgets.MinMaxPointWidgetManager; +import eu.engys.vtk.widgets.PlaneDisplayWidget; +import eu.engys.vtk.widgets.PlaneWidget; +import eu.engys.vtk.widgets.PointWidgetManager; +import eu.engys.vtk.widgets.QualityWidget; +import eu.engys.vtk.widgets.panels.BoundingBoxBar; +import eu.engys.vtk.widgets.shapes.BoxWidget; + +public class VTKView3D extends JPanel implements CanvasPanel { + + private static Logger logger = LoggerFactory.getLogger(CanvasPanel.class); + + private Set viewElements; + private Set view3DElements; + private Map, View3DElement> elementsByClass = new HashMap<>(); + private Map elementsByTitle = new HashMap<>(); + + private final Model model; + private final Set widgets; + private final VTKRenderPanel renderPanel; + private final VTKView3DController view3DController; + + private final List controllers; + + private VTK3DActionsToolBar genericToolBar; + + private PointWidgetManager pointWidgetManager; + private AxisWidgetManager axisWidgetManager; + private MinMaxPointWidgetManager minMaxPointWidgetManager; + private AxesWidget axesWidget; +// private CORWidget corWidget; + private BoxWidget boxWidget; + private PlaneWidget planeWidget; + private PlaneDisplayWidget planeDisplayWidget; + private ExtractSelectionWidget selectionWidget; + private QualityWidget qualityWidget; + private LayersCoverageWidget layersWidget; + private LogoWidget logoWidget; + + private WidgetToolBar widgetToolBar; + private BoundingBoxBar boundingBoxBar; + private JPanel southPanel; + private WidgetPanel widgetPanel; + + private Mesh3DController meshController; + private Geometry3DController geometryController; + + private ILookAndFeel laf; + private ProgressMonitor monitor; + + @Inject + public VTKView3D(Model model, ILookAndFeel laf, Set viewElements, Set controllers, Set widgets, ProgressMonitor monitor) { + super(); + this.model = model; + this.laf = laf; + this.viewElements = viewElements; + this.view3DElements = new LinkedHashSet<>(); + this.widgets = widgets; + this.monitor = monitor; + this.renderPanel = new VTKRenderPanel(laf); + this.view3DController = new VTKView3DController(this); + this.controllers = new ArrayList<>(); + +// this.meshController = new VTKMesh3DController(model, monitor); +// this.geometryController = new VTKGeometry3DController(model, monitor); +// +// registerController(meshController); +// registerController(geometryController); + + for (Controller3D c : controllers) { + registerController(c); + } + + EventManager.registerEventListener(new HelyxView3DEventListener(this), View3DEvent.class); + } + + @Override + public void registerController(Controller3D controller) { + controller.setRenderPanel(renderPanel); + controllers.add(controller); + if (this.geometryController == null && controller instanceof Geometry3DController) { + this.geometryController = (Geometry3DController) controller; + } else if (this.meshController == null && controller instanceof Mesh3DController) { + this.meshController = (Mesh3DController) controller; + } + } + + @Override + public void layoutComponents() { + setLayout(new BorderLayout()); + + for (ViewElement element : viewElements) { + layoutElements(element); + } + + this.genericToolBar = new VTK3DActionsToolBar(model, laf); + this.widgetToolBar = new WidgetToolBar(widgets); + this.boundingBoxBar = new BoundingBoxBar(this, laf); + + this.southPanel = new JPanel(new BorderLayout()); + this.southPanel.add(boundingBoxBar, BorderLayout.SOUTH); + + add(genericToolBar, BorderLayout.EAST); + if (widgetToolBar.hasWidgets()) { + add(widgetToolBar, BorderLayout.NORTH); + } + + add(renderPanel, BorderLayout.CENTER); + add(southPanel, BorderLayout.SOUTH); + + initWidgets(); + + renderPanel.GetRenderer().AddObserver("EndEvent", this, "handleEndRendering"); + addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + logoWidget.update(renderPanel.getSize()); + } + }); + } + + private void layoutElements(ViewElement element) { + View3DElement view3d = element.getView3D(); + view3d.install(this); + view3DElements.add(view3d); + elementsByClass.put(element.getClass(), view3d); + elementsByTitle.put(element.getTitle(), view3d); + } + + void handleEndRendering() { + ExecUtil.invokeLater(new Runnable() { + @Override + public void run() { + // double timeInSeconds = vtkRendererPanel.GetRenderer().GetLastRenderTimeInSeconds(); + // double fps = 1.0 / timeInSeconds; + // System.out.println("FPS " + fps); + BoundingBox bb = boundingBoxBar.update(); +// corWidget.update(bb); + } + }); + } + + private void initWidgets() { + for (Widget widget : widgets) { + widget.populate(this); + } + this.widgetPanel = new WidgetPanel(widgets); + this.axesWidget = new AxesWidget(renderPanel); + this.logoWidget = new LogoWidget(renderPanel); +// this.corWidget = new CORWidget(renderPanel); + this.planeWidget = new PlaneWidget(renderPanel); + this.planeDisplayWidget = new PlaneDisplayWidget(renderPanel); + this.selectionWidget = new ExtractSelectionWidget(renderPanel, monitor); + this.qualityWidget = new QualityWidget(model, renderPanel, monitor); + this.layersWidget = new LayersCoverageWidget(model, renderPanel, monitor); + this.boxWidget = new BoxWidget(renderPanel); + this.pointWidgetManager = new PointWidgetManager(renderPanel); + this.axisWidgetManager = new AxisWidgetManager(renderPanel); + this.minMaxPointWidgetManager = new MinMaxPointWidgetManager(renderPanel); + } + +// @Override +// public void start() { +// widgetPanel.clear(); +// vtkRendererPanel.resetZoomLater(); +// } + + @Override + public void load() { + for (Controller3D context : controllers) { + logger.info("[LOAD 3D] {}", context.getClass().getSimpleName()); + context.loadActors(); + } + + for (View3DElement element : view3DElements) { + logger.info("[LOAD 3D] {}", element.getClass().getSimpleName()); + _load3D(element); + } + + logger.info("[LOAD] 3D Widgets"); + loadWidgets(); + } + + private void _load3D(final View3DElement view3DElement) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + view3DElement.load(VTKView3D.this); + } + }); + } + + @Override + public void save() { +// if (view3DElement == currentElement) { +// view3DElement.save(this); +// } + } + + @Override + public void stop(Class klass) { + stopWidgets(); + if (elementsByClass.containsKey(klass)) { + final View3DElement view3DElement = elementsByClass.get(klass); + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + view3DElement.stop(VTKView3D.this); + view3DElement.save(VTKView3D.this); + } + }); + } + } + + @Override + public void start(Class klass) { + if (klass == null) { + _start(view3DElements.iterator().next()); + resetZoom(); + } else if (elementsByClass.containsKey(klass)) { + _start(elementsByClass.get(klass)); + } + } + + private void _start(final View3DElement view3DElement) { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + view3DElement.start(VTKView3D.this); + } + }); + renderPanel.renderLater(); + } + + @Override + public void resetZoom() { + renderPanel.resetZoomAndWait(); + } + + @Override + public Geometry3DController getGeometryController() { + return geometryController; + } + + @Override + public Mesh3DController getMeshController() { + return meshController; + } + + @SuppressWarnings("unchecked") + @Override + public T getController(Class klass) { + for (Controller3D c : controllers) { + if (klass.isInstance(c)) { + return (T) c; + } + } + return null; + } + + public VTKRenderPanel getVTKRendererPanel() { + return renderPanel; + } + + @Override + public BoundingBox computeBoundingBox(boolean visibleOnly) { + return VTKUtil.computeBoundingBox(controllers, visibleOnly); + } + + @Override + public void geometryToMesh(GeometryToMesh g2m) { + renderPanel.clearSelection(); + + for (Controller3D controller : controllers) { + controller.geometryToMesh(g2m); + } + + for (View3DElement element : view3DElements) { + _load3D(element); + } + } + + @Override + public void clear() { + ExecUtil.invokeAndWait(new Runnable() { + @Override + public void run() { + renderPanel.lock(); + _clear(); + renderPanel.unlock(); + } + }); + } + + private void _clear() { + logger.info("[CLEAR] "); + renderPanel.clear(); + widgetPanel.clear(); + widgetToolBar.clear(); + + planeWidget.clear(); + planeDisplayWidget.clear(); + selectionWidget.clear(); + qualityWidget.clear(); + layersWidget.clear(); + pointWidgetManager.clear(); + axisWidgetManager.clear(); + minMaxPointWidgetManager.clear(); + + genericToolBar.clear(); + + for (Widget widget : widgets) { + widget.clear(); + } + axesWidget.clear(); +// corWidget.clear(); + + for (Controller3D context : controllers) { + context.clearContext(); + context.clear(); + } + + view3DController.setProjection(false); + VTKUtil.gc(true); + } + + public Dimension getMinimumSize() { + return new Dimension(50, 50); + } + + @Override + public JPanel getPanel() { + final JTabbedPane tabbedPane = new JTabbedPane(); + tabbedPane.addTab("", this); + UiUtil.setOneTabHide(tabbedPane); + final JPanel container = new JPanel(new BorderLayout()); + container.setBorder(BorderFactory.createEmptyBorder(23, 0, 0, 0)); + container.add(tabbedPane, BorderLayout.CENTER); + return container; + } + + @Override + public void showPoint(DoubleField[] point, String key, EventActionType action, Color color) { + pointWidgetManager.showPoint(point, key, action, color); + } + + @Override + public void showAxis(DoubleField[] origin, DoubleField[] normal, EventActionType action) { + axisWidgetManager.showPoint(origin, normal, action); + } + + @Override + public void showPlane(DoubleField[] origin, DoubleField[] normal, EventActionType action) { + BoundingBox bb = computeBoundingBox(true); + double diagonal = bb.getDiagonal() / 2; + double value = Double.isInfinite(diagonal) ? 1 : diagonal > 0 ? diagonal : 1; + planeWidget.showPlane(origin, normal, action, value); + } + + @Override + public void showPlaneDisplay(DoubleField[] origin, DoubleField[] normal, EventActionType action) { + BoundingBox bb = computeBoundingBox(true); + double diagonal = bb.getDiagonal() / 2; + double value = Double.isInfinite(diagonal) ? 1 : diagonal > 0 ? diagonal : 1; + planeDisplayWidget.showPlane(origin, normal, action, value); + } + + @Override + public void activateSelection(Selection selection, EventActionType action) { + selectionWidget.activateSelection(selection, action); + } + + @Override + public void showBox(DoubleField[] min, DoubleField[] max, EventActionType action) { + boxWidget.showBox(null, min, max, action); + } + + @Override + public void showMinMaxFieldPoints(String key, Kind kind, boolean visible) { + minMaxPointWidgetManager.setPointsVisible(key, kind, visible); + } + + @Override + public void updateMinAndMaxForFields(String varName, Point3d min, Point3d max) { + minMaxPointWidgetManager.updateCoordinates(min, max, varName); + } + + @Override + public void showQualityFields(QualityInfo qualityInfo, EventActionType action) { + qualityWidget.activateQualityField(qualityInfo, action); + } + + @Override + public void showLayersCoverage(LayerInfo layerInfo, JPanel colorBar, EventActionType action) { + layersWidget.activateLayersCoverage(layerInfo, colorBar, action); + } + + @Override + public boolean showWidget(Widget widget) { + if (widget.canShow()) { + widget.show(); + if (widget.getWidgetComponent() != null) { + showWidgetPanel(widget); + } + return true; + } else { + return false; + } + } + + @Override + public void showWidgetPanel(Widget widget) { + if (widgetPanel.isHidden()) { + southPanel.add(widgetPanel, BorderLayout.CENTER); + widgetPanel.setHidden(false); + } + widgetPanel.showPanel(widget.getWidgetComponent().getKey()); + southPanel.revalidate(); + } + + @Override + public void hideWidget(Widget widget) { + widget.hide(); + if (widget.getWidgetComponent() != null) { + hideWidgetPanel(widget); + } + } + + @Override + public void hideWidgetPanel(Widget widget) { + widgetPanel.hidePanel(widget.getWidgetComponent().getKey()); + if (widgetPanel.isEmpty()) { + widgetPanel.setHidden(true); + southPanel.remove(widgetPanel); + } + southPanel.revalidate(); + } + +// @Override +// public void handleInitializeFieldsStarted(){ +// for (Widget widget : widgets) { +// widget.handleInitializeFieldsStarted(); +// } +// } +// +// @Override +// public void handleInitializeFieldsFinished(){ +// for (Widget widget : widgets) { +// widget.handleInitializeFieldsFinished(); +// } +// } + + public void stopWidgets() { + for (Widget widget : widgets) { + widget.stop(); + } + } + + public void loadWidgets() { +// corWidget.on(); + for (Widget widget : widgets) { + widget.load(); + } + } + + public void updateWidgets_fieldChanged() { + for (Widget widget : widgets) { + widget.handleFieldChanged(); + } + } + + public void updateWidgets_timeStepChanged() { + for (Widget widget : widgets) { + widget.handleTimeStepChanged(); + } + } + + public void updateWidgets_newTimeStep() { + for (Widget widget : widgets) { + widget.handleNewTimeStepsRead(); + } + } + + public VTKView3DController getVTKController() { + return view3DController; + } + + public Model getModel() { + return model; + } + + public void dumpContext(Class klass) { + for (Controller3D c : controllers) { + c.dumpContext(klass); + } + } + + public void applyContext(Class klass) { + for (Controller3D c : controllers) { + c.applyContext(klass); + } + genericToolBar.update(controllers); + for (Widget widget : widgets) { + widget.applyContext(); + } + } + +} diff --git a/src/eu/engys/vtk/VTKView3DController.java b/src/eu/engys/vtk/VTKView3DController.java new file mode 100644 index 0000000..b26831b --- /dev/null +++ b/src/eu/engys/vtk/VTKView3DController.java @@ -0,0 +1,181 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import static eu.engys.vtk.VTK3DActionsToolBar._3D_AXIS_XNEG; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_AXIS_XPOS; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_AXIS_YNEG; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_AXIS_YPOS; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_AXIS_ZNEG; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_AXIS_ZPOS; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_LOAD_MESH; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_VIEW_EDGES; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_VIEW_OUTLINE; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_VIEW_PROFILE; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_VIEW_PROJECTIONS; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_VIEW_SURFACE; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_VIEW_WIREFRAME; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_ZOOM_IN; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_ZOOM_OUT; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_ZOOM_RESET; +import static eu.engys.vtk.VTK3DActionsToolBar._3D_ZOOM_TOBOX; +import eu.engys.core.presentation.Action; +import eu.engys.core.presentation.ActionContainer; +import eu.engys.core.presentation.ActionManager; +import eu.engys.core.presentation.ActionToggle; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.gui.view3D.CameraManager.Position; +import eu.engys.gui.view3D.Representation; + +public class VTKView3DController implements ActionContainer { + + private VTKRenderPanel vtkRendererPanel; + private VTKView3D view3D; + + public VTKView3DController(VTKView3D vtkView3D) { + this.view3D = vtkView3D; + this.vtkRendererPanel = vtkView3D.getVTKRendererPanel(); + ActionManager.getInstance().parseActions(this); + } + + @Override + public boolean isDemo() { + return false; + } + + @Action(key=_3D_LOAD_MESH) + public void loadMesh() { + view3D.getMeshController().showExternalMesh(); + view3D.load(); + view3D.start(null); + } + + @Action(key=_3D_AXIS_XPOS) + public void viewXPos() { + vtkRendererPanel.setCameraPosition(Position.X_POS); + } + + @Action(key=_3D_AXIS_XNEG) + public void viewXNeg() { + vtkRendererPanel.setCameraPosition(Position.X_NEG); + } + + @Action(key=_3D_AXIS_YPOS) + public void viewYPos() { + vtkRendererPanel.setCameraPosition(Position.Y_POS); + } + + @Action(key=_3D_AXIS_YNEG) + public void viewYNeg() { + vtkRendererPanel.setCameraPosition(Position.Y_NEG); + } + + @Action(key=_3D_AXIS_ZPOS) + public void viewZPos() { + vtkRendererPanel.setCameraPosition(Position.Z_POS); + } + + @Action(key=_3D_AXIS_ZNEG) + public void viewZNeg() { + vtkRendererPanel.setCameraPosition(Position.Z_NEG); + } + + @Action(key=_3D_ZOOM_IN) + public void zoomIn() { + vtkRendererPanel.wheelForward(); + } + + @Action(key=_3D_ZOOM_OUT) + public void zoomOut() { + vtkRendererPanel.wheelBackward(); + } + + @Action(key=_3D_ZOOM_TOBOX) + public void zoomToBox() { + vtkRendererPanel.getInteractor().setStyleToZoom(); + } + + @Action(key=_3D_ZOOM_RESET) + public void zoomReset() { + vtkRendererPanel.zoomReset(); + } + + @Action(key=_3D_VIEW_EDGES) + public void setRepresentationToSurfaceWithEdges() { + vtkRendererPanel.clearSelection(); + vtkRendererPanel.changeRepresentation(Representation.SURFACE_WITH_EDGES); + } + + @Action(key=_3D_VIEW_PROFILE) + public void setRepresentationToProfile() { + vtkRendererPanel.clearSelection(); + vtkRendererPanel.changeRepresentation(Representation.PROFILE); + } + + @Action(key=_3D_VIEW_SURFACE) + public void setRepresentationToSurface() { + vtkRendererPanel.clearSelection(); + vtkRendererPanel.changeRepresentation(Representation.SURFACE); + } + + @Action(key=_3D_VIEW_WIREFRAME) + public void setRepresentationToWireframe() { + vtkRendererPanel.clearSelection(); + vtkRendererPanel.changeRepresentation(Representation.WIREFRAME); + } + + @Action(key=_3D_VIEW_OUTLINE) + public void setRepresentationToOutline() { + vtkRendererPanel.clearSelection(); + vtkRendererPanel.changeRepresentation(Representation.OUTLINE); + } + + @ActionToggle(key=_3D_VIEW_PROJECTIONS, normal="perspective", selected="parallel") + public void setProjection(boolean parallel) { + if (parallel) { + vtkRendererPanel.ParallelProjectionOn(); + } else { + vtkRendererPanel.ParallelProjectionOff(); + } + } + + public void showScalarsForField(FieldItem fieldItem) { + view3D.getMeshController().showField(fieldItem); + view3D.getGeometryController().showField(fieldItem); + view3D.updateWidgets_fieldChanged(); + } + + public void showTimeStep(double time) { + view3D.getMeshController().showTimeStep(time); + view3D.updateWidgets_timeStepChanged(); + } + + public void readTimeSteps() { + view3D.getMeshController().readTimeSteps(); + view3D.updateWidgets_newTimeStep(); + } +} diff --git a/src/eu/engys/vtk/VTKView3DProvider.java b/src/eu/engys/vtk/VTKView3DProvider.java new file mode 100644 index 0000000..0baca03 --- /dev/null +++ b/src/eu/engys/vtk/VTKView3DProvider.java @@ -0,0 +1,82 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + + +//public class VTKView3DProvider implements Provider, Runnable { +// +// private CanvasPanel panel1; +// private ILookAndFeel laf; +// private Model model; +// private Set elements; +// private Set widgets; +// private ProgressMonitor monitor; +// private Set controllers; +// +// @Inject +// public VTKView3DProvider(Model model, ILookAndFeel laf, Set elements, Set controllers, Set widgets, ProgressMonitor monitor) { +// this.model = model; +// this.laf = laf; +// this.elements = elements; +// this.controllers = controllers; +// this.widgets = widgets; +// this.monitor = monitor; +// } +// +// @Override +// public void run() { +// if (!VTKSettings.librariesAreLoaded()) { +// VTKSettings.LoadAllNativeLibraries(); +// } +// if (VTKSettings.librariesAreLoaded()) { +// if (Arguments.no3D) { +// panel1 = new VTKEmptyView3D(model, controllers, monitor); +// } else { +// panel1 = new VTKView3D(model, laf, elements, controllers, widgets, monitor); +// } +// } else { +// panel1 = new FallbackView3D(); +// } +// } +// +// @Override +// public CanvasPanel get() { +// try { +// if (EventQueue.isDispatchThread()) { +// run(); +// } else { +// EventQueue.invokeAndWait(this); +// } +// } catch (InvocationTargetException e) { +// throw new RuntimeException(e); // should not happen +// } catch (InterruptedException e) { +// Thread.currentThread().interrupt(); +// } +// +// return panel1; +// } +//} diff --git a/src/eu/engys/vtk/WidgetPanel.java b/src/eu/engys/vtk/WidgetPanel.java new file mode 100644 index 0000000..3afe9c8 --- /dev/null +++ b/src/eu/engys/vtk/WidgetPanel.java @@ -0,0 +1,106 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk; + +import java.awt.BorderLayout; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; + +import eu.engys.gui.view3D.widget.Widget; +import eu.engys.gui.view3D.widget.WidgetComponent; + +public class WidgetPanel extends JPanel { + + private JTabbedPane tabbedPane; + private Set components; + private Map componentsMap; + private boolean hidden = true; + + @Inject + public WidgetPanel(Set components) { + super(new BorderLayout()); + this.components = components; + this.componentsMap = new HashMap<>(); + layoutComponents(); + } + + private void layoutComponents() { + tabbedPane = new JTabbedPane(); + for (Widget widget : components) { + WidgetComponent widgetComponent = widget.getWidgetComponent(); + if (widgetComponent != null) { + componentsMap.put(widgetComponent.getKey(), widgetComponent); + } + } + add(tabbedPane, BorderLayout.CENTER); + } + + public void showPanel(String key) { + WidgetComponent c = componentsMap.get(key); + c.handleShow(); + if(getTabIndex(key) == -1){ + tabbedPane.addTab(key, c.getPanel()); + } + tabbedPane.setSelectedComponent(c.getPanel()); + } + + private int getTabIndex(String tab){ + for (int i = 0; i < tabbedPane.getTabCount(); i++) { + if(tabbedPane.getTitleAt(i).equals(tab)){ + return i; + } + } + return -1; + } + + public void hidePanel(String key) { + tabbedPane.removeTabAt(getTabIndex(key)); + } + + public boolean isEmpty() { + return tabbedPane.getTabCount() == 0; + } + + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + public boolean isHidden() { + return hidden; + } + + public void clear() { + for (WidgetComponent wc : componentsMap.values()) { + wc.clear(); + } + } +} diff --git a/src/eu/engys/vtk/WidgetToolBar.java b/src/eu/engys/vtk/WidgetToolBar.java new file mode 100644 index 0000000..f0883ca --- /dev/null +++ b/src/eu/engys/vtk/WidgetToolBar.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk; + +import static eu.engys.vtk.VTK3DActionsToolBar._3D_LOAD_MESH; + +import java.awt.FlowLayout; +import java.util.Set; + +import javax.swing.Box; +import javax.swing.JToolBar; + +import eu.engys.core.presentation.ActionManager; +import eu.engys.gui.view3D.widget.Widget; +import eu.engys.util.ui.WrappedFlowLayout; + +public class WidgetToolBar extends JToolBar { + + private Set widgets; + + public WidgetToolBar(Set widgets) { + super(JToolBar.HORIZONTAL); + setLayout(new WrappedFlowLayout(FlowLayout.LEFT, 0, 0)); + this.widgets = widgets; + putClientProperty("Synthetica.toolBar.buttons.paintBorder", Boolean.TRUE); + putClientProperty("Synthetica.opaque", Boolean.FALSE); + setFloatable(false); + setRollover(true); + layoutComponents(); + } + + private void layoutComponents() { + add(ActionManager.getInstance().get(_3D_LOAD_MESH)); + for (Widget widget : widgets) { + widget.populate(this); + } + add(Box.createHorizontalGlue()); + } + + public void clear() { + } + + public boolean hasWidgets() { + return widgets.size() > 0; + } + +} diff --git a/src/eu/engys/vtk/actions/ExtractLines.java b/src/eu/engys/vtk/actions/ExtractLines.java new file mode 100644 index 0000000..3373773 --- /dev/null +++ b/src/eu/engys/vtk/actions/ExtractLines.java @@ -0,0 +1,172 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkBox; +import vtk.vtkExtractGeometry; +import vtk.vtkFeatureEdges; +import vtk.vtkGeometryFilter; +import vtk.vtkPolyData; + +public class ExtractLines { + + private static final Logger logger = LoggerFactory.getLogger(ExtractLines.class); + + private vtkPolyData input; + + private double[] insideMin; + private double[] insideMax; + + private double[] outsideMin; + private double[] outsideMax; + + private double angle; + + private boolean boundary; + + private boolean manifold; + + private boolean nonmanifold; + + public ExtractLines() { + this.input = null; + this.insideMin = null; + this.insideMax = null; + this.outsideMin = null; + this.outsideMax = null; + } + + public void setInput(vtkPolyData input) { + this.input = input; + } + public void setAngle(double angle) { + this.angle = angle; + } + public void setInsideMin(double[] insideMin) { + this.insideMin = insideMin; + } + public void setInsideMax(double[] insideMax) { + this.insideMax = insideMax; + } + public void setOutsideMin(double[] outsideMin) { + this.outsideMin = outsideMin; + } + public void setOutsideMax(double[] outsideMax) { + this.outsideMax = outsideMax; + } + public void setBoundary(boolean boundary) { + this.boundary = boundary; + } + public void setManifold(boolean manifold) { + this.manifold = manifold; + } + public void setNonmanifold(boolean nonmanifold) { + this.nonmanifold = nonmanifold; + } + + public vtkPolyData execute() { + vtkFeatureEdges edges = new vtkFeatureEdges(); + if (boundary) { + edges.BoundaryEdgesOn(); + } else { + edges.BoundaryEdgesOff(); + } + if (manifold) { + edges.ManifoldEdgesOn(); + } else { + edges.ManifoldEdgesOff(); + } + if (nonmanifold) { + edges.NonManifoldEdgesOn(); + } else { + edges.NonManifoldEdgesOff(); + } + edges.FeatureEdgesOn(); + edges.SetFeatureAngle(angle); + edges.ColoringOff(); + edges.SetInputData(input); + edges.Update(); + + vtkPolyData output = edges.GetOutput(); + log("EDGES", output); + + if (insideMin != null && insideMax != null) { + vtkBox box = new vtkBox(); + box.SetXMin(insideMin); + box.SetXMax(insideMax); + + vtkExtractGeometry extract = new vtkExtractGeometry(); + extract.ExtractInsideOn(); + extract.ExtractBoundaryCellsOff(); + extract.SetImplicitFunction(box); + extract.SetInputData(output); + extract.Update(); + + vtkGeometryFilter geometry = new vtkGeometryFilter(); + geometry.SetInputData(extract.GetOutput()); + geometry.Update(); + + output = geometry.GetOutput(); + log("INSIDE", output); + } + + if (outsideMin != null && outsideMax != null) { + vtkBox box = new vtkBox(); + box.SetXMin(outsideMin); + box.SetXMax(outsideMax); + + vtkExtractGeometry extract = new vtkExtractGeometry(); + extract.ExtractInsideOff(); + extract.ExtractBoundaryCellsOff(); + extract.SetImplicitFunction(box); + extract.SetInputData(output); + extract.Update(); + + vtkGeometryFilter geometry = new vtkGeometryFilter(); + geometry.SetInputData(extract.GetOutput()); + geometry.Update(); + + output = geometry.GetOutput(); + log("OUTSIDE", output); + } + + return output; + } + + private void log(String title, vtkPolyData data) { + logger.info(title + "points: {}, cells: {}, lines: {}", data.GetNumberOfPoints(), data.GetNumberOfCells(), data.GetNumberOfLines()); +// final double[] bounds = data.GetBounds(); +// System.out.println(title + " Z : [" + bounds[4] + ", " + bounds[5] + "]"); +// System.out.println(title + " points: " + data.GetNumberOfPoints()); +// System.out.println(title + " cells : " + data.GetNumberOfCells()); +// System.out.println(title + " lines : " + data.GetNumberOfLines()); + + } + +} diff --git a/src/eu/engys/vtk/actions/ExtractSelection.java b/src/eu/engys/vtk/actions/ExtractSelection.java new file mode 100644 index 0000000..286a453 --- /dev/null +++ b/src/eu/engys/vtk/actions/ExtractSelection.java @@ -0,0 +1,377 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actions; + +import java.util.HashSet; +import java.util.Set; + +import javax.vecmath.Vector3d; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkCellData; +import vtk.vtkDataArray; +import vtk.vtkDataSet; +import vtk.vtkExtractPolyDataGeometry; +import vtk.vtkExtractSelection; +import vtk.vtkFloatArray; +import vtk.vtkGeometryFilter; +import vtk.vtkIdFilter; +import vtk.vtkIdList; +import vtk.vtkIdTypeArray; +import vtk.vtkPolyData; +import vtk.vtkPolyDataNormals; +import vtk.vtkSelection; +import vtk.vtkSelectionNode; +import eu.engys.gui.view3D.PickInfo; +import eu.engys.gui.view3D.Selection; +import eu.engys.gui.view3D.Selection.SelectionMode; + +public class ExtractSelection { + + private static final Logger logger = LoggerFactory.getLogger(ExtractSelection.class); + + private Selection selection; + + private vtkPolyData selectionData; + private vtkPolyData inverseSelectionData; + private vtkIdTypeArray list; + + public void setSelection(Selection selection) { + this.selection = selection; + } + + public void execute(PickInfo pi) { + + String name = (pi.actor != null ? pi.actor.getName() : null); + + logger.debug("------------- PICK --------------"); + logger.debug(" ACTOR : " + name); + logger.debug(" CELL : " + pi.cellId); + logger.debug(" FRUSTUM : " + (pi.frustum != null ? pi.frustum.GetClassName() : "null")); + if (selection.getDataSet() != null) { + logger.debug(" DATASET 1 "); + logger.debug(" hashcode : " + selection.getDataSet().hashCode()); + logger.debug(" cells : " + selection.getDataSet().GetNumberOfCells()); + logger.debug(" point : " + selection.getDataSet().GetNumberOfPoints()); + } else { + logger.debug(" DATASET 1 : " + "null"); + } + if (pi.dataSet != null) { + logger.debug(" DATASET 2 "); + logger.debug(" hashcode : " + pi.dataSet.hashCode()); + logger.debug(" cells : " + pi.dataSet.GetNumberOfCells()); + logger.debug(" points : " + pi.dataSet.GetNumberOfPoints()); + } else { + logger.debug(" DATASET 2 : " + "null"); + } + + boolean keepSelection = selection.isKeepSelection() || pi.control; + +// if (selection.getDataSet() != pi.dataSet) { +// return; +// } + + if (keepSelection) { + logger.debug("SELECTION: KEEP"); + this.list = selection.getIdList() != null ? selection.getIdList() : new vtkIdTypeArray(); + } else { + logger.debug("SELECTION: DISCARD"); + this.list = new vtkIdTypeArray(); + } + + switch (selection.getType()) { + case CELL: + logger.debug("PICK BY: CELL"); + pickByCell(pi); + break; + case AREA: + logger.debug("PICK BY: AREA"); + pickByArea(pi); + break; + case FEATURE: + logger.debug("PICK BY: FEATURE"); + pickByFeature(pi); + break; + + default: + break; + } + + applySelection(selection.getDataSet()); + + selection.setSelectionData(selectionData); + selection.setInverseSelectionData(inverseSelectionData); + selection.setIdList(list); + + logger.debug("SELECTION cells: "+selectionData.GetNumberOfCells()); + logger.debug("SELECTION points: "+selectionData.GetNumberOfPoints()); + logger.debug("---------------------------"); + } + + private void pickByCell(PickInfo pi) { + int cellId = pi.cellId; + if (cellId < 0) + return; + + performSelection(cellId); + } + + private void pickByArea(PickInfo pi) { + if (pi.frustum != null && pi.dataSet != null) { + + vtkDataSet input = selection.getDataSet();//pi.dataSet; + vtkIdFilter idFilter = new vtkIdFilter(); + idFilter.CellIdsOn(); +// idFilter.PointIdsOff(); +// idFilter.FieldDataOff(); + idFilter.SetIdsArrayName("originalCellIds"); + idFilter.SetInputData(input); + idFilter.Update(); + + vtkExtractPolyDataGeometry extractor = new vtkExtractPolyDataGeometry(); + extractor.SetInputData(idFilter.GetOutput()); + extractor.ExtractInsideOn(); + extractor.ExtractBoundaryCellsOff(); + extractor.SetImplicitFunction(pi.frustum); + extractor.Update(); + vtkDataSet output = extractor.GetOutput(); + + vtkIdTypeArray ids = (vtkIdTypeArray) output.GetCellData().GetArray("originalCellIds"); + if (ids != null) { + for (int i = 0; i < ids.GetNumberOfTuples(); i++) { + int id = ids.GetValue(i); + performSelection(id); + } + } + +// vtkExtractSelectedFrustum extractor = new vtkExtractSelectedFrustum(); +// extractor.SetInput(pi.dataSet); +// extractor.ShowBoundsOff(); +// extractor.PreserveTopologyOff(); +// extractor.SetFrustum(pi.frustum); +// extractor.Update(); +// vtkDataSet output = (vtkDataSet) extractor.GetOutput(); +// +// vtkIdTypeArray ids = (vtkIdTypeArray) output.GetCellData().GetArray("vtkOriginalCellIds"); +// if (ids != null) { +// for (int i = 0; i < ids.GetNumberOfTuples(); i++) { +// performSelection(ids.GetValue(i)); +// } +// } + } + } + + private void pickByFeature(PickInfo pi) { + double[] normal = pi.normal; + vtkDataSet input = pi.dataSet; + int cellId = pi.cellId; + + if (input == null) + return; + + vtkPolyData output = getNormalsDataSet(normal, input); + Set cells = new HashSet<>(); + + if (output.GetNumberOfCells() > 0 ) { + analyseNeighbours(cellId, output, cells); + + performSelection(cellId); + + for (Integer id : cells) { + performSelection(id); + } + } + + } + + private void analyseNeighbours(int cellId, vtkPolyData output, Set cells) { + vtkCellData outputData = output.GetCellData(); + vtkDataArray angles = outputData.GetVectors("Angles"); + + vtkIdList cellPointIds = new vtkIdList(); + output.GetCellPoints(cellId, cellPointIds); + + // neighbor cells may be listed multiple times + // use set instead of list to get a unique list of neighbors + Set neighbors = new HashSet<>(); + /* + * For each vertice of the cell, we calculate which cells uses that + * point. So if we make this, for each vertice, we have all the + * neighbors. In the case we use ''cellPointIds'' as a parameter of + * ''GeteCellNeighbors'', we will obtain an empty set. Because the only + * cell that is using that set of points is the current one. That is why + * we have to make each vertice at time. + */ + + for (int i = 0; i < cellPointIds.GetNumberOfIds(); i++) { + vtkIdList idList = new vtkIdList(); + idList.InsertNextId(cellPointIds.GetId(i)); + + // get the neighbors of the cell + vtkIdList neighborCellIds = new vtkIdList(); + + output.GetCellNeighbors(cellId, idList, neighborCellIds); + + for (int j = 0; j < neighborCellIds.GetNumberOfIds(); j++) { + int id = neighborCellIds.GetId(j); + double angle = angles.GetComponent(id, 0); + if (angle < selection.getFeatureAngle()) { + neighbors.add(id); + } + } + } + + Set newCells = new HashSet<>(); + for (Integer id : neighbors) { + if (!cells.contains(id)) { + newCells.add(id); + cells.add(id); + } + } + + if (!newCells.isEmpty()) { + for (Integer newCell : newCells) { + analyseNeighbours(newCell, output, cells); + } + } + } + + private vtkPolyData getNormalsDataSet(double[] normal, vtkDataSet dataSet) { + vtkPolyDataNormals normalsFilter = new vtkPolyDataNormals(); + normalsFilter.SetInputData(dataSet); + normalsFilter.SplittingOff(); + normalsFilter.SetFeatureAngle(60); + normalsFilter.ComputeCellNormalsOn(); + // normalsFilter.AutoOrientNormalsOn(); + normalsFilter.Update(); + + vtkPolyData output = normalsFilter.GetOutput(); + vtkCellData outputData = output.GetCellData(); + vtkDataArray normals = outputData.GetVectors("Normals"); + + vtkFloatArray angles = new vtkFloatArray(); + angles.SetName("Angles"); + + if (normals != null) { + for (int i = 0; i < normals.GetNumberOfTuples(); i++) { + double[] t = normals.GetTuple3(i); + double a = computeAngle(t, normal); + angles.InsertNextValue(a); + } + } + outputData.AddArray(angles); + return output; + } + + private double computeAngle(double[] t, double[] normal) { + Vector3d v = new Vector3d(t); + Vector3d n = new Vector3d(normal); + double angle = n.angle(v); + + return Math.toDegrees(angle); + } + + private void performSelection(int cellId) { + if (selection.getMode() == SelectionMode.SELECT) { + select(cellId); + } else { + deselect(cellId); + } + } + + private void select(int cellId) { + list.InsertNextValue(cellId); + } + + private void deselect(int cellId) { + int index = -1; + if ((index = alreadySelected(cellId)) >= 0) { + list.RemoveTuple(index); + } + } + + private int alreadySelected(int cellId) { + for (int i = 0; i < list.GetNumberOfTuples(); i++) { + if (list.GetValue(i) == cellId) { + return i; + } + } + return -1; + } + + private void applySelection(vtkDataSet dataSet) { + vtkSelection selection = new vtkSelection(); + vtkSelectionNode node = new vtkSelectionNode(); + node.SetContentType(4); //INDICES + node.SetFieldType(0); //CELL + node.SetSelectionList(list); + selection.AddNode(node); + + vtkExtractSelection filter = new vtkExtractSelection(); + filter.SetInputData(0, dataSet); + filter.SetInputData(1, selection); + filter.Update(); + + vtkGeometryFilter geom = new vtkGeometryFilter(); + geom.SetInputData(filter.GetOutput()); + geom.Update(); + + selectionData = geom.GetOutput(); + selection.Delete(); + node.Delete(); + filter.Delete(); + geom.Delete(); + + selection = new vtkSelection(); + node = new vtkSelectionNode(); + node.SetContentType(4); // INDICES + node.SetFieldType(0); // CELL + node.SetSelectionList(list); + node.GetProperties().Set(node.INVERSE(), 1); + selection.AddNode(node); + + filter = new vtkExtractSelection(); + filter.SetInputData(0, dataSet); + filter.SetInputData(1, selection); +// VTKProgressConsoleWrapper progressWrapper = new VTKProgressConsoleWrapper("", filter, monitor); +// filter.AddObserver("StartEvent", progressWrapper, "onStart"); +// filter.AddObserver("EndEvent", progressWrapper, "onEnd"); +// filter.AddObserver("ProgressEvent", progressWrapper, "onProgress"); + filter.Update(); + + geom = new vtkGeometryFilter(); + geom.SetInputData(filter.GetOutput()); + geom.Update(); + + inverseSelectionData = geom.GetOutput(); + selection.Delete(); + node.Delete(); + filter.Delete(); + geom.Delete(); + } +} diff --git a/src/eu/engys/vtk/actions/IntersectSurfaces.java b/src/eu/engys/vtk/actions/IntersectSurfaces.java new file mode 100644 index 0000000..1ff4c9c --- /dev/null +++ b/src/eu/engys/vtk/actions/IntersectSurfaces.java @@ -0,0 +1,111 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkIntersectionPolyDataFilter; +import vtk.vtkPolyData; +import vtk.vtkTriangleFilter; + +public class IntersectSurfaces { + + private static final Logger logger = LoggerFactory.getLogger(IntersectSurfaces.class); + + private vtkPolyData input1; + private vtkPolyData input2; + + private boolean triangulateInput1; + private boolean triangulateInput2; + + public IntersectSurfaces() { + this.input1 = null; + this.input2 = null; + } + + public void setInput1(vtkPolyData input1) { + this.input1 = input1; + } + public void setInput2(vtkPolyData input2) { + this.input2 = input2; + } + + public void setTriangulateInput1(boolean triangulateInput1) { + this.triangulateInput1 = triangulateInput1; + } + + public void setTriangulateInput2(boolean triangulateInput2) { + this.triangulateInput2 = triangulateInput2; + } + + public vtkPolyData execute() { + if (input1 != null && input2 != null) { + + vtkIntersectionPolyDataFilter intersect = new vtkIntersectionPolyDataFilter(); + + if (triangulateInput1) { + vtkTriangleFilter triangle = new vtkTriangleFilter(); + triangle.SetInputData(input1); + triangle.Update(); + + intersect.SetInputData(0, triangle.GetOutput()); + } else { + intersect.SetInputData(0, input1); + } + + if (triangulateInput2) { + vtkTriangleFilter triangle = new vtkTriangleFilter(); + triangle.SetInputData(input2); + triangle.Update(); + + intersect.SetInputData(1, triangle.GetOutput()); + } else { + intersect.SetInputData(1, input2); + } + + intersect.SplitFirstOutputOff(); + intersect.SplitSecondOutputOff(); + intersect.Update(); + + log("LINE", intersect.GetOutput()); + return intersect.GetOutput(); + } else { + return null; + } + } + + private void log(String title, vtkPolyData data) { + logger.info(title + "points: {}, cells: {}, lines: {}", data.GetNumberOfPoints(), data.GetNumberOfCells(), data.GetNumberOfLines()); + final double[] bounds = data.GetBounds(); + System.out.println(title + " Z : [" + bounds[4] + ", " + bounds[5] + "]"); + System.out.println(title + " points: " + data.GetNumberOfPoints()); + System.out.println(title + " cells : " + data.GetNumberOfCells()); + System.out.println(title + " lines : " + data.GetNumberOfLines()); + + } + +} diff --git a/src/eu/engys/vtk/actors/BoxActor.java b/src/eu/engys/vtk/actors/BoxActor.java new file mode 100644 index 0000000..1a9eba8 --- /dev/null +++ b/src/eu/engys/vtk/actors/BoxActor.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import eu.engys.core.project.geometry.surface.Box; + +public class BoxActor extends SurfaceActor { + + public BoxActor(Box box) { + super(box); + newActor(box.getDataSet(), box.isVisible()); + } +} diff --git a/src/eu/engys/vtk/actors/CylinderActor.java b/src/eu/engys/vtk/actors/CylinderActor.java new file mode 100644 index 0000000..318f178 --- /dev/null +++ b/src/eu/engys/vtk/actors/CylinderActor.java @@ -0,0 +1,38 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import eu.engys.core.project.geometry.surface.Cylinder; + +public class CylinderActor extends SurfaceActor { + + public CylinderActor(Cylinder cylinder) { + super(cylinder); + newActor(cylinder.getDataSet(), cylinder.isVisible()); + } + + +} diff --git a/src/eu/engys/vtk/actors/DefaultActor.java b/src/eu/engys/vtk/actors/DefaultActor.java new file mode 100644 index 0000000..ebbe0ef --- /dev/null +++ b/src/eu/engys/vtk/actors/DefaultActor.java @@ -0,0 +1,592 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import vtk.vtkActor; +import vtk.vtkDataSet; +import vtk.vtkDataSetSurfaceFilter; +import vtk.vtkFeatureEdges; +import vtk.vtkLookupTable; +import vtk.vtkMapper; +import vtk.vtkOutlineFilter; +import vtk.vtkPolyData; +import vtk.vtkPolyDataAlgorithm; +import vtk.vtkPolyDataMapper; +import vtk.vtkProperty; +import vtk.vtkQuadricClustering; +import vtk.vtkTransform; +import vtk.vtkUnstructuredGrid; +import eu.engys.core.project.geometry.stl.AffineTransform; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.Representation; +import eu.engys.util.PrefUtil; +import eu.engys.vtk.VTKColors; +import eu.engys.vtk.VTKUtil; + +public abstract class DefaultActor extends vtkActor implements Actor { + + private enum SelectionState {BASE, SELECTED, DESELECTED}; + + private static final double BASE_OPACITY = 1.0; + private static final double DESELECTION_OPACITY = 0.2; + private static final double SELECTION_OPACITY = 0.6; + + private vtkPolyDataMapper mapper; + private vtkPolyDataMapper LODMapper; + private String name; + private vtkQuadricClustering LODFilter; + private vtkTransform transform; + private vtkPolyDataMapper outlineMapper; + private vtkPolyDataAlgorithm outlineFilter; + private vtkFeatureEdges edges; + private vtkPolyDataMapper edgesMapper; + + private boolean outline; + private boolean profile; + private boolean scalar; + private SelectionState selectionState = SelectionState.BASE; + private boolean useDeselectedState = true; + + private vtkProperty DESELECTION_PROPERTY; + private vtkProperty SELECTION_PROPERTY; + private vtkProperty BASE_PROPERTY; + + private int memorySize; + private vtkActor selectionActor; + + public DefaultActor(String name) { + this.name = name; + this.transform = new vtkTransform(); + this.selectionActor = new vtkActor(); + + setUpBaseProperty(); + setUpSelectionProperty(); + setUpDeselectionProperty(); + } + + private void setUpBaseProperty() { + BASE_PROPERTY = new vtkProperty(); + BASE_PROPERTY.SetColor(VTKColors.WHITE); + BASE_PROPERTY.SetOpacity(BASE_OPACITY); + } + + private void applyCommonProperty(vtkActor actor) { + actor.GetProperty().SetRepresentationToSurface(); + actor.GetProperty().EdgeVisibilityOff(); + actor.GetProperty().SetEdgeColor(VTKColors.BLACK); + actor.GetProperty().SetLineWidth(1); + + actor.GetProperty().LightingOn(); + actor.GetProperty().SetAmbient(VTKColors.AMBIENT); + actor.GetProperty().SetDiffuse(VTKColors.DIFFUSE); + actor.GetProperty().SetSpecular(VTKColors.SPECULAR); + actor.GetProperty().SetSpecularPower(VTKColors.SPECULAR_POWER); + } + + private void applyBaseProperty(vtkActor actor) { + if (selectionState != SelectionState.BASE) { + actor.GetProperty().SetColor(BASE_PROPERTY.GetColor()); + actor.GetProperty().SetOpacity(BASE_PROPERTY.GetOpacity()); + } + } + + private void setUpSelectionProperty() { + SELECTION_PROPERTY = new vtkProperty(); + SELECTION_PROPERTY.SetColor(VTKColors.SELECTION_COLOR); + SELECTION_PROPERTY.SetOpacity(SELECTION_OPACITY); + } + + private void applySelectionProperty(vtkActor actor) { + if (selectionState != SelectionState.SELECTED) { + actor.GetProperty().SetColor(BASE_PROPERTY.GetColor()); + actor.GetProperty().SetOpacity(DESELECTION_PROPERTY.GetOpacity()); + } + } + + private void setUpDeselectionProperty() { + DESELECTION_PROPERTY = new vtkProperty(); + DESELECTION_PROPERTY.SetColor(VTKColors.DESELECTION_COLOR); + DESELECTION_PROPERTY.SetOpacity(DESELECTION_OPACITY); + } + + private void applyDeselectionProperty(vtkActor actor) { + actor.GetProperty().SetColor(DESELECTION_PROPERTY.GetColor()); + actor.GetProperty().SetOpacity(DESELECTION_PROPERTY.GetOpacity()); + } + + protected void newActor(vtkPolyData dataset, boolean visible) { + vtkPolyData input = new vtkPolyData(); + input.ShallowCopy(dataset); + + this.mapper = new vtkPolyDataMapper(); + this.mapper.ImmediateModeRenderingOff(); +// this.mapper.StaticOn(); +// VTKUtil.observe(mapper, getName()); + + SetMapper(mapper); + selectionActor.SetMapper(mapper); + + this.outlineMapper = new vtkPolyDataMapper(); + this.outlineFilter = new vtkOutlineFilter(); + + this.edgesMapper = new vtkPolyDataMapper(); + this.edges = new vtkFeatureEdges(); + this.edges.SetBoundaryEdges(1); + this.edges.SetFeatureEdges(1); + this.edges.SetNonManifoldEdges(0); + this.edges.SetManifoldEdges(0); + this.edges.SetFeatureAngle(30D); + this.edges.ColoringOff(); + + this.outline = false; + this.profile = false; + this.scalar = false; + + setInput(input); + + input.Delete(); + + SetVisibility(visible ? 1 : 0); + + applyCommonProperty(this); + applyCommonProperty(selectionActor); + applyBaseProperty(this); + selectionActor.GetProperty().SetColor(SELECTION_PROPERTY.GetColor()); + selectionActor.GetProperty().SetOpacity(SELECTION_PROPERTY.GetOpacity()); + } + + protected void newActor(vtkUnstructuredGrid dataset, boolean visible) { + vtkUnstructuredGrid input = new vtkUnstructuredGrid(); + input.ShallowCopy(dataset); + + vtkDataSetSurfaceFilter filter = new vtkDataSetSurfaceFilter(); + filter.SetInputData(input); + filter.PassThroughCellIdsOn(); + filter.PassThroughPointIdsOn(); + filter.Update(); + input.Delete(); + + newActor(filter.GetOutput(), visible); + filter.Delete(); + } + + void createLOD() + { + this.LODMapper.ImmediateModeRenderingOff(); + this.LODMapper.StaticOn(); +// VTKUtil.observe(LODMapper, "LOD_" + getName()); + + int dim = 30; + + this.LODFilter.UseInputPointsOn(); + this.LODFilter.CopyCellDataOn(); + this.LODFilter.UseInternalTrianglesOff(); + this.LODFilter.SetNumberOfDivisions(dim, dim, dim); + this.LODFilter.AutoAdjustNumberOfDivisionsOff(); + } + + @Override + public void setInput(vtkPolyData input) { +// System.out.println("DefaultActor.setInput() size: " + input.GetActualMemorySize() + " kB"); + mapper.RemoveAllInputs(); + mapper.SetInputData(input); + + int memory_limit = PrefUtil.getInt(PrefUtil._3D_LOCK_INTRACTIVE_MEMORY, 512); + this.memorySize = input.GetActualMemorySize(); + if (memorySize > memory_limit) { + if (LODMapper == null) { + this.LODMapper = new vtkPolyDataMapper(); + this.LODFilter = new vtkQuadricClustering(); + + createLOD(); + } + } else { + this.LODMapper = null; + this.LODFilter = null; + } + + if (LODMapper != null) { + LODFilter.RemoveAllInputs(); + LODFilter.SetInputData(input); + LODFilter.Update(); + + LODMapper.RemoveAllInputs(); + LODMapper.SetInputData(LODFilter.GetOutput()); + LODMapper.Update(); + } + + if (outlineFilter != null) { + outlineFilter.RemoveAllInputs(); + outlineFilter.SetInputData(input); + outlineFilter.Update(); + + outlineMapper.RemoveAllInputs(); + outlineMapper.SetInputData(outlineFilter.GetOutput()); + outlineMapper.Update(); + } + + if (edges != null) { + edges.RemoveAllInputs(); + edges.SetInputData(input); + edges.Update(); + + edgesMapper.RemoveAllInputs(); + edgesMapper.SetInputData(edges.GetOutput()); + edgesMapper.Update(); + } + } + + @Override + public void setInput(vtkUnstructuredGrid input) { + vtkPolyData filter = VTKUtil.geometryFilter(input); + setInput(filter); + } + + @Override + public void interactiveOn() { + if (!outline && !profile) { + if (LODMapper != null) { + SetMapper(LODMapper); + selectionActor.SetMapper(LODMapper); + } + } + } + + @Override + public void interactiveOff() { + if (!outline && !profile) { + if (LODMapper != null) { + SetMapper(mapper); + selectionActor.SetMapper(mapper); + } + } + } + + @Override + public String getName() { + return name; + } + + @Override + public void rename(String name) { + this.name = name; + } + + @Override + public vtkMapper getMapper() { + return GetMapper(); + } + + @Override + public boolean getVisibility() { + return GetVisibility() == 1; + } + + @Override + public void setVisibility(boolean onoff) { + SetVisibility(onoff ? 1 : 0); + selectionActor.SetVisibility(GetVisibility()); + } + + @Override + public double[] getBounds() { + return GetBounds(); + } + + @Override + public vtkActor getActor() { + return this; + } + + @Override + public vtkActor getSelectionActor() { + return selectionActor; + } + + @Override + public void deleteActor() { + if (LODFilter != null) { + LODMapper.RemoveAllInputs(); + LODMapper.Delete(); + LODFilter.RemoveAllInputs(); + LODFilter.Delete(); + } + vtkDataSet dataset = mapper.GetInputAsDataSet(); + + VTKUtil.deleteDataset(dataset); + + mapper.RemoveAllInputs(); + mapper.Delete(); + + selectionActor.SetMapper(null); + selectionActor.Delete(); + + SetMapper(null); + Delete(); + } + + @Override + public void transformActor(boolean save, AffineTransform t) { + vtkTransform transform = t.toVTK(this.transform); + + SetUserTransform(transform); + selectionActor.SetUserTransform(transform); + + if (save) { + this.transform = transform; + } + } + + @Override + public vtkTransform getUserTransform() { + return (vtkTransform) GetUserTransform(); + } + + @Override + public void setSolidColor(double[] color, double opacity) { + this.scalar = false; + setColor(color, opacity); + + scalarVisibilityOff(); + } + + @Override + public void setScalarColors(vtkLookupTable lut, FieldItem field) { + this.scalar = true; + setColor(VTKColors.WHITE, BASE_OPACITY); + + if (mapper != null) { + setScalarColor(mapper, lut, field); + } + + if (LODMapper != null) { + setScalarColor(LODMapper, lut, field); + } + } + + protected void setLineWidth(int width) { + GetProperty().SetLineWidth(width); + +// BASE_PROPERTY.SetLineWidth(width); +// SELECTION_PROPERTY.SetLineWidth(width); +// DESELECTION_PROPERTY.SetLineWidth(width); + } + + protected void setColor(double[] color, double opacity) { + GetProperty().SetColor(color); + GetProperty().SetOpacity(opacity); + + BASE_PROPERTY.SetColor(color); + BASE_PROPERTY.SetOpacity(opacity); + +// SELECTION_PROPERTY.SetColor(color); +// DESELECTION_PROPERTY.SetColor(color); + } + + private static void setScalarColor(vtkMapper mapper, vtkLookupTable lut, FieldItem field) { + mapper.SetLookupTable(lut); + mapper.UseLookupTableScalarRangeOn(); + mapper.ScalarVisibilityOn(); + mapper.SetColorModeToMapScalars(); + + if (field.getDataType().isCell()) { + mapper.SetScalarModeToUseCellFieldData(); + } else if (field.getDataType().isPoint()) { + mapper.SetScalarModeToUsePointFieldData(); + } + + mapper.SetScalarRange(lut.GetRange()); + mapper.SelectColorArray(field.getName()); + mapper.Update(); + } + + @Override + public void setRepresentation(Representation representation) { + switch (representation) { + case SURFACE: + GetProperty().SetRepresentationToSurface(); + GetProperty().EdgeVisibilityOff(); + +// BASE_PROPERTY.SetRepresentationToSurface(); +// BASE_PROPERTY.EdgeVisibilityOff(); + setOutLine(false); + setProfile(false); + break; + case WIREFRAME: + GetProperty().SetRepresentationToWireframe(); + GetProperty().EdgeVisibilityOff(); + +// BASE_PROPERTY.SetRepresentationToWireframe(); +// BASE_PROPERTY.EdgeVisibilityOff(); + setOutLine(false); + setProfile(false); + break; + case SURFACE_WITH_EDGES: + GetProperty().SetRepresentationToSurface(); + GetProperty().EdgeVisibilityOn(); + +// BASE_PROPERTY.SetRepresentationToSurface(); +// BASE_PROPERTY.EdgeVisibilityOn(); + setOutLine(false); + setProfile(false); + break; + case OUTLINE: +// GetProperty().SetRepresentationToSurface(); +// GetProperty().EdgeVisibilityOff(); +// +// BASE_PROPERTY.SetRepresentationToSurface(); +// BASE_PROPERTY.EdgeVisibilityOff(); + setProfile(false); + setOutLine(true); + break; + + case PROFILE: +// GetProperty().SetRepresentationToSurface(); +// GetProperty().EdgeVisibilityOff(); +// +// BASE_PROPERTY.SetRepresentationToSurface(); +// BASE_PROPERTY.EdgeVisibilityOff(); + setOutLine(false); + setProfile(true); + break; + + default: + break; + } + } + + private void setOutLine(boolean outline) { + if (outline) { + if (!this.outline) { + outlineActor(); + } + } else { + if (this.outline) { + deoutlineActor(); + } + } + this.outline = outline; + } + + private void setProfile(boolean profile) { + if (profile) { + if (!this.profile) { + profileActor(); + } + } else { + if (this.profile) { + deprofileActor(); + } + } + this.profile = profile; + } + + private void outlineActor() { + SetMapper(outlineMapper); + } + + private void deoutlineActor() { + SetMapper(mapper); + } + + private void profileActor() { + SetMapper(edgesMapper); + } + + private void deprofileActor() { + SetMapper(mapper); + } + + @Override + public void restoreFromSelection() { + if (this.selectionState != SelectionState.BASE) { + applyBaseProperty(this); + if (scalar) { + scalarVisibilityOn(); + } else { + scalarVisibilityOff(); + } + } + this.selectionState = SelectionState.BASE; + } + + @Override + public void selectActor() { + if (this.selectionState != SelectionState.SELECTED) { + applySelectionProperty(this); + scalarVisibilityOff(); + } + this.selectionState = SelectionState.SELECTED; + } + + @Override + public void deselectActor() { + if (useDeselectedState) { + if (this.selectionState != SelectionState.DESELECTED) { + applyDeselectionProperty(this); + scalarVisibilityOff(); + } + this.selectionState = SelectionState.DESELECTED; + } else { + restoreFromSelection(); + } + } + + private void scalarVisibilityOff() { + if (mapper != null) { + mapper.ScalarVisibilityOff(); + } + + if (LODMapper != null) { + LODMapper.ScalarVisibilityOff(); + } + } + + private void scalarVisibilityOn() { + if (mapper != null) { + mapper.ScalarVisibilityOn(); + } + + if (LODMapper != null) { + LODMapper.ScalarVisibilityOn(); + } + } + + @Override + public void deselectedStateOn() { + this.useDeselectedState = true; + } + @Override + public void deselectedStateOff() { + this.useDeselectedState = false; + } + + @Override + public int getMemorySize() { + return memorySize; + } +} diff --git a/src/eu/engys/vtk/actors/HelyxActor.java b/src/eu/engys/vtk/actors/HelyxActor.java new file mode 100644 index 0000000..42a8f34 --- /dev/null +++ b/src/eu/engys/vtk/actors/HelyxActor.java @@ -0,0 +1,516 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +//package eu.engys.vtk.actors; +// +//import org.apache.commons.lang.ArrayUtils; +// +//import vtk.vtkActor; +//import vtk.vtkDataSetSurfaceFilter; +//import vtk.vtkHELYXActor; +//import vtk.vtkLookupTable; +//import vtk.vtkMapper; +//import vtk.vtkPolyData; +//import vtk.vtkPolyDataMapper; +//import vtk.vtkProperty; +//import vtk.vtkTransform; +//import vtk.vtkUnstructuredGrid; +//import eu.engys.core.project.geometry.stl.AffineTransform; +//import eu.engys.core.project.mesh.FieldItem; +//import eu.engys.gui.view3D.Actor; +//import eu.engys.gui.view3D.Representation; +//import eu.engys.util.PrefUtil; +//import eu.engys.vtk.VTKColors; +//import eu.engys.vtk.VTKUtil; + +//public abstract class HelyxActor extends vtkHELYXActor implements Actor { +// +// private static final double BASE_OPACITY = 1.0; +// private static final double DESELECTION_OPACITY = BASE_OPACITY;//0.2; +// private static final double SELECTION_OPACITY = BASE_OPACITY;//0.95; +// +// private String name; +// private vtkTransform transform; +// +// private boolean outline; +// private boolean profile; +// private boolean scalar; +// +// private vtkProperty DESELECTION_PROPERTY; +// private vtkProperty SELECTION_PROPERTY; +// private vtkProperty baseProperty; +// private vtkPolyDataMapper mapper; +// +// public HelyxActor(String name) { +// this.name = name; +// this.transform = new vtkTransform(); +// +// setUpBaseProperty(); +// setUpSelectionProperty(); +// setUpDeselectionProperty(); +// } +// +// private void setUpBaseProperty() { +// baseProperty = new vtkProperty(); +// baseProperty.SetRepresentationToSurface(); +// baseProperty.EdgeVisibilityOff(); +// baseProperty.SetEdgeColor(VTKColors.BLACK); +// baseProperty.SetLineWidth(1); +// +//// baseProperty.SetColor(WHITE); +// baseProperty.LightingOn(); +// baseProperty.SetOpacity(BASE_OPACITY); +// +// baseProperty.SetAmbient(VTKColors.AMBIENT); +// baseProperty.SetDiffuse(VTKColors.DIFFUSE); +// baseProperty.SetSpecular(VTKColors.SPECULAR); +// baseProperty.SetSpecularPower(VTKColors.SPECULAR_POWER); +// } +// +// private void applyBaseProperty() { +// if (!ArrayUtils.isEquals(GetProperty().GetColor(), VTKColors.WHITE)) { +// GetProperty().SetRepresentationToSurface(); +// GetProperty().EdgeVisibilityOff(); +// GetProperty().SetEdgeColor(VTKColors.BLACK); +// GetProperty().SetLineWidth(1); +// +// GetProperty().SetColor(VTKColors.WHITE); +// GetProperty().LightingOn(); +// GetProperty().SetOpacity(BASE_OPACITY); +// +// GetProperty().SetAmbient(VTKColors.AMBIENT); +// GetProperty().SetDiffuse(VTKColors.DIFFUSE); +// GetProperty().SetSpecular(VTKColors.SPECULAR); +// GetProperty().SetSpecularPower(VTKColors.SPECULAR_POWER); +// } +// } +// +// private void setUpSelectionProperty() { +// SELECTION_PROPERTY = new vtkProperty(); +// SELECTION_PROPERTY.SetRepresentationToSurface(); +// SELECTION_PROPERTY.EdgeVisibilityOff(); +//// SELECTION_PROPERTY.EdgeVisibilityOn(); +// SELECTION_PROPERTY.SetEdgeColor(VTKColors.WHITE); +// SELECTION_PROPERTY.SetLineWidth(1); +// +// SELECTION_PROPERTY.SetColor(VTKColors.SELECTION_COLOR); +// SELECTION_PROPERTY.LightingOff(); +//// SELECTION_PROPERTY.SetOpacity(SELECTION_OPACITY); +// +// SELECTION_PROPERTY.SetAmbient(VTKColors.SELECTION_AMBIENT); +// SELECTION_PROPERTY.SetDiffuse(VTKColors.SELECTION_DIFFUSE); +// SELECTION_PROPERTY.SetSpecular(VTKColors.SELECTION_SPECULAR); +// SELECTION_PROPERTY.SetSpecularPower(VTKColors.SELECTION_SPECULAR_POWER); +// } +// +// private void applySelectionProperty() { +// if (ArrayUtils.isEquals(GetProperty().GetColor(), VTKColors.WHITE)) { +// GetProperty().SetRepresentationToSurface(); +// GetProperty().EdgeVisibilityOff(); +//// GetProperty().EdgeVisibilityOn(); +// GetProperty().SetEdgeColor(VTKColors.WHITE); +// GetProperty().SetLineWidth(1); +// +// GetProperty().SetColor(VTKColors.SELECTION_COLOR); +// GetProperty().LightingOn(); +//// SELECTION_PROPERTY.SetOpacity(SELECTION_OPACITY); +// +// GetProperty().SetAmbient(VTKColors.SELECTION_AMBIENT); +// GetProperty().SetDiffuse(VTKColors.SELECTION_DIFFUSE); +// GetProperty().SetSpecular(VTKColors.SELECTION_SPECULAR); +// GetProperty().SetSpecularPower(VTKColors.SELECTION_SPECULAR_POWER); +// } +// } +// +// private void setUpDeselectionProperty() { +// DESELECTION_PROPERTY = new vtkProperty(); +// DESELECTION_PROPERTY.SetOpacity(DESELECTION_OPACITY); +// +// DESELECTION_PROPERTY.SetColor(VTKColors.DESELECTION_COLOR); +// DESELECTION_PROPERTY.SetAmbient(VTKColors.SELECTION_AMBIENT); +// DESELECTION_PROPERTY.SetDiffuse(VTKColors.SELECTION_DIFFUSE); +// DESELECTION_PROPERTY.SetSpecular(VTKColors.SELECTION_SPECULAR); +// DESELECTION_PROPERTY.SetSpecularPower(VTKColors.SELECTION_SPECULAR_POWER); +// } +// +// private void applyDeselectionProperty() { +// GetProperty().SetOpacity(DESELECTION_OPACITY); +// +// GetProperty().SetColor(VTKColors.DESELECTION_COLOR); +// GetProperty().SetAmbient(VTKColors.SELECTION_AMBIENT); +// GetProperty().SetDiffuse(VTKColors.SELECTION_DIFFUSE); +// GetProperty().SetSpecular(VTKColors.SELECTION_SPECULAR); +// GetProperty().SetSpecularPower(VTKColors.SELECTION_SPECULAR_POWER); +// } +// +// protected void newActor(vtkPolyData dataset, boolean visible) { +// vtkPolyData input = new vtkPolyData(); +// input.ShallowCopy(dataset); +// +// this.mapper = new vtkPolyDataMapper(); +// SetMapper(mapper); +// //StaticOn(); +// +// this.outline = false; +// this.profile = false; +// this.scalar = false; +// +// setInput(input); +// +// input.Delete(); +// +// SetVisibility(visible ? 1 : 0); +// +// GetProperty().DeepCopy(baseProperty); +// } +// +// protected void newActor(vtkUnstructuredGrid dataset, boolean visible) { +// vtkUnstructuredGrid input = new vtkUnstructuredGrid(); +// input.ShallowCopy(dataset); +// +// vtkDataSetSurfaceFilter filter = new vtkDataSetSurfaceFilter(); +// filter.SetInputData(input); +// filter.PassThroughCellIdsOn(); +// filter.PassThroughPointIdsOn(); +// filter.Update(); +// input.Delete(); +// +// newActor(filter.GetOutput(), visible); +// filter.Delete(); +// } +// +// @Override +// public void setInput(vtkPolyData input) { +//// System.out.println("DefaultActor.setInput() size: " + input.GetActualMemorySize() + " kB"); +// mapper.RemoveAllInputs(); +// mapper.SetInputData(input); +// +// int memory = PrefUtil.getInt(PrefUtil._3D_LOCK_INTRACTIVE_MEMORY, 512); +// if (input.GetActualMemorySize() > memory) { +// SetEnableLOD(1); +// } else { +// SetEnableLOD(1); +// } +// +// } +// +// @Override +// public void setInput(vtkUnstructuredGrid input) { +// vtkPolyData filter = VTKUtil.geometryFilter(input); +// setInput(filter); +// } +// +// @Override +// public void interactiveOn() { +// if (!outline && !profile) { +// SetDisplayTypeToInteractive(); +// } +// } +// +// @Override +// public void interactiveOff() { +// if (!outline && !profile) { +// SetDisplayTypeToFull(); +// } +// } +// +// @Override +// public String getName() { +// return name; +// } +// +// @Override +// public void rename(String name) { +// this.name = name; +// } +// +// @Override +// public vtkMapper getMapper() { +// return GetMapper(); +// } +// +// @Override +// public boolean getVisibility() { +// return GetVisibility() == 1; +// } +// +// @Override +// public void setVisibility(boolean onoff) { +// SetVisibility(onoff ? 1 : 0); +// } +// +// @Override +// public double[] getBounds() { +// return GetBounds(); +// } +// +// @Override +// public vtkActor getActor() { +// return this; +// } +// +// @Override +// public void deleteActor() { +//// if (LODFilter != null) { +//// LODMapper.RemoveAllInputs(); +//// LODMapper.Delete(); +//// LODFilter.RemoveAllInputs(); +//// LODFilter.Delete(); +//// } +//// vtkDataSet dataset = mapper.GetInputAsDataSet(); +//// +//// VTKUtil.deleteDataset(dataset); +//// +//// mapper.RemoveAllInputs(); +//// mapper.Delete(); +// +// SetMapper(null); +// Delete(); +// } +// +// @Override +// public void transformActor(boolean save, AffineTransform t) { +// vtkTransform transform = t.toVTK(this.transform); +// +// SetUserTransform(transform); +// +// if (save) { +// this.transform = transform; +// } +// } +// +// @Override +// public vtkTransform getUserTransform() { +// return (vtkTransform) GetUserTransform(); +// } +// +// @Override +// public void setSolidColor(double[] color, double opacity) { +// this.scalar = false; +// setColor(color, opacity); +// +// scalarVisibilityOff(); +// } +// +// @Override +// public void setScalarColors(vtkLookupTable lut, FieldItem field) { +// this.scalar = true; +// setColor(VTKColors.WHITE, BASE_OPACITY); +// +//// if (mapper != null) { +//// setScalarColor(mapper, lut, field); +//// } +//// +//// if (LODMapper != null) { +//// setScalarColor(LODMapper, lut, field); +//// } +// } +// +// protected void setLineWidth(int width) { +// GetProperty().SetLineWidth(width); +// +// baseProperty.SetLineWidth(width); +// SELECTION_PROPERTY.SetLineWidth(width); +// DESELECTION_PROPERTY.SetLineWidth(width); +// } +// +// protected void setColor(double[] color, double opacity) { +// GetProperty().SetColor(color); +// GetProperty().SetOpacity(opacity); +// +// baseProperty.SetColor(color); +// baseProperty.SetOpacity(opacity); +// +//// SELECTION_PROPERTY.SetColor(color); +// +//// DESELECTION_PROPERTY.SetColor(color); +// } +// +// private static void setScalarColor(vtkMapper mapper, vtkLookupTable lut, FieldItem field) { +// mapper.SetLookupTable(lut); +// mapper.UseLookupTableScalarRangeOn(); +// mapper.ScalarVisibilityOn(); +// mapper.SetColorModeToMapScalars(); +// +// if (field.getDataType().isCell()) { +// mapper.SetScalarModeToUseCellFieldData(); +// } else if (field.getDataType().isPoint()) { +// mapper.SetScalarModeToUsePointFieldData(); +// } +// +// mapper.SetScalarRange(lut.GetRange()); +// mapper.SelectColorArray(field.getName()); +// mapper.Update(); +// } +// +// @Override +// public void setRepresentation(Representation representation) { +// switch (representation) { +// case SURFACE: +// GetProperty().SetRepresentationToSurface(); +// GetProperty().EdgeVisibilityOff(); +// +// baseProperty.SetRepresentationToSurface(); +// baseProperty.EdgeVisibilityOff(); +// setOutLine(false); +// setProfile(false); +// break; +// case WIREFRAME: +// GetProperty().SetRepresentationToWireframe(); +// GetProperty().EdgeVisibilityOff(); +// +// baseProperty.SetRepresentationToWireframe(); +// baseProperty.EdgeVisibilityOff(); +// setOutLine(false); +// setProfile(false); +// break; +// case SURFACE_WITH_EDGES: +// GetProperty().SetRepresentationToSurface(); +// GetProperty().EdgeVisibilityOn(); +// +// baseProperty.SetRepresentationToSurface(); +// baseProperty.EdgeVisibilityOn(); +// setOutLine(false); +// setProfile(false); +// break; +// case OUTLINE: +// GetProperty().SetRepresentationToSurface(); +// GetProperty().EdgeVisibilityOff(); +// +// baseProperty.SetRepresentationToSurface(); +// baseProperty.EdgeVisibilityOff(); +// setOutLine(true); +// setProfile(false); +// break; +// +// case PROFILE: +// GetProperty().SetRepresentationToSurface(); +// GetProperty().EdgeVisibilityOff(); +// +// baseProperty.SetRepresentationToSurface(); +// baseProperty.EdgeVisibilityOff(); +// setOutLine(false); +// setProfile(true); +// break; +// +// default: +// break; +// } +// } +// +// private void setOutLine(boolean outline) { +// if (outline) { +// if (!this.outline) { +// outlineActor(); +// } +// } else { +// if (this.outline) { +// deoutlineActor(); +// } +// } +// this.outline = outline; +// } +// +// private void setProfile(boolean profile) { +// if (profile) { +// if (!this.profile) { +// profileActor(); +// } +// } else { +// if (this.profile) { +// deprofileActor(); +// } +// } +// this.profile = profile; +// } +// +// private void outlineActor() { +// SetDisplayTypeToOutline(); +// } +// +// private void deoutlineActor() { +// SetDisplayTypeToFull(); +// } +// +// private void profileActor() { +// SetDisplayTypeToProfile(); +// } +// +// private void deprofileActor() { +// SetDisplayTypeToFull(); +// } +// +// @Override +// public void restoreFromSelection() { +//// GetProperty().DeepCopy(baseProperty); +// applyBaseProperty(); +// +// if (scalar) { +// scalarVisibilityOn(); +// } else { +// scalarVisibilityOff(); +// } +// } +// +// @Override +// public void selectActor() { +//// GetProperty().DeepCopy(SELECTION_PROPERTY); +// applySelectionProperty(); +// +// scalarVisibilityOff(); +// } +// +// @Override +// public void deselectActor() { +//// GetProperty().DeepCopy(DESELECTION_PROPERTY); +//// applyDeselectionProperty(); +// applyBaseProperty(); +// +// scalarVisibilityOff(); +// } +// +// private void scalarVisibilityOff() { +// GetMapper().ScalarVisibilityOff(); +//// if (mapper != null) { +//// mapper.ScalarVisibilityOff(); +//// } +//// +//// if (LODMapper != null) { +//// LODMapper.ScalarVisibilityOff(); +//// } +// } +// +// private void scalarVisibilityOn() { +// GetMapper().ScalarVisibilityOn(); +//// if (mapper != null) { +//// mapper.ScalarVisibilityOn(); +//// } +//// +//// if (LODMapper != null) { +//// LODMapper.ScalarVisibilityOn(); +//// } +// } +// +//} diff --git a/src/eu/engys/vtk/actors/InternalMeshActor.java b/src/eu/engys/vtk/actors/InternalMeshActor.java new file mode 100644 index 0000000..442c07b --- /dev/null +++ b/src/eu/engys/vtk/actors/InternalMeshActor.java @@ -0,0 +1,46 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import vtk.vtkUnstructuredGrid; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +public class InternalMeshActor extends DefaultActor { + + public InternalMeshActor(vtkUnstructuredGrid internalMeshDataset) { + super("internalMesh"); + newActor(internalMeshDataset, false); + + GetMapper().ScalarVisibilityOff(); + VisibilityOff(); + GetProperty().SetOpacity(1); + } + + @Override + public VisibleItem getVisibleItem() { + return null; + } +} diff --git a/src/eu/engys/vtk/actors/LineActor.java b/src/eu/engys/vtk/actors/LineActor.java new file mode 100644 index 0000000..9e52752 --- /dev/null +++ b/src/eu/engys/vtk/actors/LineActor.java @@ -0,0 +1,47 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.gui.view3D.Representation; +import eu.engys.vtk.VTKColors; + + +public class LineActor extends SurfaceActor { + + public LineActor(FeatureLine line) { + super(line); + setColor(VTKColors.toVTK(line.getColor()), 1.0); + setLineWidth(2); + newActor(line.getDataSet(), line.isVisible()); + } + + @Override + public void setRepresentation(Representation representation) { + // do nothing!!! + } + +} diff --git a/src/eu/engys/vtk/actors/PlaneActor.java b/src/eu/engys/vtk/actors/PlaneActor.java new file mode 100644 index 0000000..9999976 --- /dev/null +++ b/src/eu/engys/vtk/actors/PlaneActor.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import eu.engys.core.project.geometry.surface.Plane; + +public class PlaneActor extends SurfaceActor { + + public PlaneActor(Plane plane) { + super(plane); + newActor(plane.getDataSet(), plane.isVisible()); + } +} diff --git a/src/eu/engys/vtk/actors/PlaneRegionActor.java b/src/eu/engys/vtk/actors/PlaneRegionActor.java new file mode 100644 index 0000000..0d86195 --- /dev/null +++ b/src/eu/engys/vtk/actors/PlaneRegionActor.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import vtk.vtkLookupTable; +import eu.engys.core.project.geometry.surface.PlaneRegion; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.gui.view3D.Representation; +import eu.engys.vtk.VTKColors; +import eu.engys.vtk.actors.SurfaceToActor.ActorMode; + +public class PlaneRegionActor extends SurfaceActor { + + private ActorMode mode; + + public PlaneRegionActor(PlaneRegion plane, ActorMode mode) { + super(plane); + this.mode = mode; + newActor(plane.getDataSet(), plane.isVisible()); + if (mode == ActorMode.DEFAULT) { + setColor(VTKColors.CYAN, 0.5); + } + } + + @Override + public void setRepresentation(Representation representation) { + if (mode == ActorMode.DEFAULT) { + super.setRepresentation(Representation.SURFACE_WITH_EDGES); + } else { + super.setRepresentation(representation); + } + } + + @Override + public void setScalarColors(vtkLookupTable lut, FieldItem field) { + if (mode == ActorMode.VIRTUALISED) { + super.setScalarColors(lut, field); + } + } + + @Override + public void setSolidColor(double[] color, double opacity) { + if (mode == ActorMode.VIRTUALISED) { + super.setSolidColor(color, opacity); + } + } +} diff --git a/src/eu/engys/vtk/actors/RingActor.java b/src/eu/engys/vtk/actors/RingActor.java new file mode 100644 index 0000000..f7458d2 --- /dev/null +++ b/src/eu/engys/vtk/actors/RingActor.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import eu.engys.core.project.geometry.surface.Ring; + +public class RingActor extends SurfaceActor { + + public RingActor(Ring ring) { + super(ring); + newActor(ring.getDataSet(), ring.isVisible()); + } +} diff --git a/src/eu/engys/vtk/actors/SolidActor.java b/src/eu/engys/vtk/actors/SolidActor.java new file mode 100644 index 0000000..419f2d1 --- /dev/null +++ b/src/eu/engys/vtk/actors/SolidActor.java @@ -0,0 +1,38 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import eu.engys.core.project.geometry.surface.Solid; + + +public class SolidActor extends SurfaceActor { + + public SolidActor(Solid solid) { + super(solid); + newActor(solid.getDataSet(), solid.isVisible()); + transformActor(true, solid.getTransformation()); + } +} diff --git a/src/eu/engys/vtk/actors/SphereActor.java b/src/eu/engys/vtk/actors/SphereActor.java new file mode 100644 index 0000000..132bdd6 --- /dev/null +++ b/src/eu/engys/vtk/actors/SphereActor.java @@ -0,0 +1,36 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import eu.engys.core.project.geometry.surface.Sphere; + +public class SphereActor extends SurfaceActor { + + public SphereActor(Sphere sphere) { + super(sphere); + newActor(sphere.getDataSet(), sphere.isVisible()); + } +} diff --git a/src/eu/engys/vtk/actors/StlActor.java b/src/eu/engys/vtk/actors/StlActor.java new file mode 100644 index 0000000..6a71460 --- /dev/null +++ b/src/eu/engys/vtk/actors/StlActor.java @@ -0,0 +1,56 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import vtk.vtkAppendPolyData; +import vtk.vtkCleanPolyData; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.core.project.geometry.surface.Stl; + + +public class StlActor extends SurfaceActor { + + public StlActor(Stl stl) { + super(stl); + + vtkAppendPolyData append = new vtkAppendPolyData(); + + for (Solid solid : stl.getSolids()) { + append.SetInputData(solid.getDataSet()); + } + append.Update(); + + vtkCleanPolyData clean = new vtkCleanPolyData(); + clean.AddInputData(append.GetOutput()); + clean.Update(); + + newActor(clean.GetOutput(), stl.isVisible()); + append.Delete(); + clean.Delete(); + + transformActor(true, stl.getTransformation()); + } +} diff --git a/src/eu/engys/vtk/actors/SurfaceActor.java b/src/eu/engys/vtk/actors/SurfaceActor.java new file mode 100644 index 0000000..16900d3 --- /dev/null +++ b/src/eu/engys/vtk/actors/SurfaceActor.java @@ -0,0 +1,43 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.actors; + +import eu.engys.core.project.geometry.Surface; +import eu.engys.util.ui.checkboxtree.VisibleItem; + +abstract class SurfaceActor extends DefaultActor { + private Surface surface; + + public SurfaceActor(Surface surface) { + super(surface.getPatchName()); + this.surface = surface; + } + + @Override + public VisibleItem getVisibleItem() { + return surface; + } +} diff --git a/src/eu/engys/vtk/actors/SurfaceToActor.java b/src/eu/engys/vtk/actors/SurfaceToActor.java new file mode 100644 index 0000000..809c01a --- /dev/null +++ b/src/eu/engys/vtk/actors/SurfaceToActor.java @@ -0,0 +1,183 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.actors; + +import static eu.engys.util.FormatUtil.format; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.core.project.geometry.FeatureLine; +import eu.engys.core.project.geometry.Surface; +import eu.engys.core.project.geometry.surface.Box; +import eu.engys.core.project.geometry.surface.Cylinder; +import eu.engys.core.project.geometry.surface.MultiPlane; +import eu.engys.core.project.geometry.surface.Plane; +import eu.engys.core.project.geometry.surface.PlaneRegion; +import eu.engys.core.project.geometry.surface.Ring; +import eu.engys.core.project.geometry.surface.Solid; +import eu.engys.core.project.geometry.surface.Sphere; +import eu.engys.core.project.geometry.surface.Stl; +import eu.engys.gui.view3D.Actor; +import eu.engys.util.progress.ProgressMonitor; + +public class SurfaceToActor { + + public enum ActorMode { + DEFAULT, VIRTUALISED + }; + + private static final Logger logger = LoggerFactory.getLogger(SurfaceToActor.class); + + private final ActorMode mode; + private final ProgressMonitor monitor; + private final BoundingBox boundingBox; + + public SurfaceToActor(ActorMode mode, BoundingBox boundingBox, ProgressMonitor monitor) { + this.mode = mode; + this.boundingBox = boundingBox; + this.monitor = monitor; + } + + public Actor[] toActor(Surface surface) { + // System.out.println("SurfaceToActor.toActor() "+surface.getName() + " ["+surface.getType()+"] "+(surface.isVisible() ? "visible" : " NOT visible")); + switch (surface.getType()) { + case BOX: + Box box = (Box) surface; + return getBoxActor(box); + case CYLINDER: + Cylinder cyl = (Cylinder) surface; + return getCylinderActor(cyl); + case SPHERE: + Sphere sphere = (Sphere) surface; + return getSphereActor(sphere); + case RING: + Ring ring = (Ring) surface; + return getRingActor(ring); + case PLANE: + if (surface instanceof Plane) { + Plane plane = (Plane) surface; + return getPlaneActor(plane); + } else if (surface instanceof PlaneRegion) { + PlaneRegion plane = (PlaneRegion) surface; + return getPlaneRegionActor(plane); + } else { + return new SurfaceActor[0]; + } + case STL: + Stl stl = (Stl) surface; + return getSTLActor(stl); + case MULTI: + MultiPlane multi = (MultiPlane) surface; + return getMultiPlaneActor(multi); + case SOLID: + Solid solid = (Solid) surface; + return getSolidActor(solid); + case LINE: + FeatureLine line = (FeatureLine) surface; + return getLineActor(line); + default: + return null; + } + } + + private Actor[] getSTLActor(Stl stl) { + logger.info("[ADD STL] name: {}", stl.getPatchName()); + List actors = new ArrayList<>(); + if (mode == ActorMode.DEFAULT) { + try { + for (Solid solid : stl.getSolids()) { + actors.add(new SolidActor(solid)); + } + } catch (Throwable e) { + logger.error("Errors loading STL", e); + } + } else { + actors.add(new StlActor(stl)); + } + return actors.toArray(new Actor[0]); + } + + private Actor[] getSolidActor(Solid solid) { + logger.info("[ADD SOLID] name: {}", solid.getPatchName()); + return new Actor[] { new SolidActor(solid) }; + } + + private SurfaceActor[] getLineActor(FeatureLine line) { + logger.info("[ADD LINE] name: {}", line.getPatchName()); + return new SurfaceActor[] { new LineActor(line) }; + } + + private SurfaceActor[] getBoxActor(Box box) { + logger.info("[ADD BOX] min: {}, max: {}", format(box.getMin()).toCents(), format(box.getMax()).toCents()); + return new SurfaceActor[] { new BoxActor(box) }; + } + + private SurfaceActor[] getCylinderActor(Cylinder cylinder) { + logger.info("[ADD CYLINDER] point1: {}, point2: {}, radius: {}", format(cylinder.getPoint1()).toCents(), format(cylinder.getPoint2()).toCents(), format(cylinder.getRadius()).toCents()); + return new SurfaceActor[] { new CylinderActor(cylinder) }; + } + + private SurfaceActor[] getSphereActor(Sphere sphere) { + logger.info("[ADD SPHERE] center: {}, radius: {}", format(sphere.getCenter()).toCents(), sphere.getRadius()); + return new SurfaceActor[] { new SphereActor(sphere) }; + } + + private SurfaceActor[] getRingActor(Ring ring) { + logger.info("[ADD RING] point1: {}, point2: {}, innerRadius: {}, outerRadius: {}", format(ring.getPoint1()).toCents(), format(ring.getPoint2()).toCents(), ring.getInnerRadius(), ring.getOuterRadius()); + return new SurfaceActor[] { new RingActor(ring) }; + } + + private SurfaceActor[] getMultiPlaneActor(MultiPlane surface) { + logger.info("[ADD MULTIPLANE] name: {}", surface.getPatchName()); + List actors = new ArrayList<>(); + for (PlaneRegion plane : surface.getPlanes()) { + actors.add(new PlaneRegionActor(plane, mode)); + } + return actors.toArray(new SurfaceActor[0]); + } + + private SurfaceActor[] getPlaneRegionActor(PlaneRegion plane) { + logger.info("[ADD PLANE] name: {}", plane.getPatchName()); + return new SurfaceActor[] { new PlaneRegionActor(plane, mode) }; + } + + private SurfaceActor[] getPlaneActor(Plane plane) { + if (plane.getCenter() == null) { + plane.setCenter(boundingBox.getCenter()); + } + if (plane.getNormal() == null) { + plane.setNormal(new double[] {0, 0, 1}); + } + logger.info("[ADD PLANE] origin: {}, normal: {}", format(plane.getCenter()).toCents(), format(plane.getNormal()).toCents()); + return new SurfaceActor[] { new PlaneActor(plane) }; + } +} diff --git a/src/eu/engys/vtk/info/VTKArrayInformation.java b/src/eu/engys/vtk/info/VTKArrayInformation.java new file mode 100644 index 0000000..809a850 --- /dev/null +++ b/src/eu/engys/vtk/info/VTKArrayInformation.java @@ -0,0 +1,647 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.info; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import vtk.vtkAbstractArray; +import vtk.vtkDataArray; +import vtk.vtkObject; + +public class VTKArrayInformation { + String Name; + double[][] Ranges; + List ComponentNames; + String DefaultComponentName; + List InformationKeys; + int DataType; + int NumberOfComponents; + int NumberOfTuples; + boolean IsPartial; + private Object NumberOfInformationKeys; + +// namespace +// { +// typedef std::vector vtkInternalComponentNameBase; +// +// struct vtkPVArrayInformationInformationKey +// { +// vtkStdString Location; +// vtkStdString Name; +// }; +// +// typedef std::vector vtkInternalInformationKeysBase; +// } +// +// class vtkPVArrayInformation::vtkInternalComponentNames: +// public vtkInternalComponentNameBase +// { +// }; +// +// class vtkPVArrayInformation::vtkInternalInformationKeys: +// public vtkInternalInformationKeysBase +// { +// }; + + //---------------------------------------------------------------------------- + public VTKArrayInformation() + { + this.Initialize(); + } + + //---------------------------------------------------------------------------- + void Initialize() + { + this.Name = null; + this.DataType = VTKConstants.VTK_VOID; + this.NumberOfComponents = 0; + this.NumberOfTuples = 0; + + this.ComponentNames = new ArrayList<>(); + this.DefaultComponentName = null; + + this.Ranges = null; + this.IsPartial = false; + + this.InformationKeys = new ArrayList<>(); + } + + //---------------------------------------------------------------------------- + void PrintSelf(PrintStream os, String indent) + { + if (this.Name != null) + { + os.println(indent+"Name: " + this.Name); + } + os.println(indent+"DataType: " + this.DataType); + os.println(indent+"NumberOfComponents: " + this.NumberOfComponents); + if (this.ComponentNames != null) + { + os.println(indent+"ComponentNames:"); + for (int i = 0; i < this.ComponentNames.size(); ++i) + { + os.println(indent+indent+this.ComponentNames.get(i)); + } + } + os.println(indent+"NumberOfTuples: " + this.NumberOfTuples); + os.println(indent+"IsPartial: " + this.IsPartial); + + os.println(indent+"Ranges :"); + int num = this.NumberOfComponents; + if (num > 1) + { + ++num; + } + for (int idx = 0; idx < num; ++idx) + { + os.println(indent+indent+this.Ranges[idx][0] + ", " + this.Ranges[idx][1]); + } + + os.println(indent+"InformationKeys :"); + if(this.InformationKeys != null) + { +// num = this.NumberOfInformationKeys; +// for (idx = 0; idx < num; ++idx) +// { +// os + i2 + this.GetInformationKeyLocation(idx) + "::" +// + this.GetInformationKeyName(idx)); +// } + } else + { + os.println(indent+indent+"None"); + } + } + + //---------------------------------------------------------------------------- +// void vtkPVArrayInformation::SetNumberOfComponents(int numComps) +// { +// if (this.NumberOfComponents == numComps) +// { +// return; +// } +// if (this.Ranges) +// { +// delete[] this.Ranges; +// this.Ranges = NULL; +// } +// this.NumberOfComponents = numComps; +// if (numComps <= 0) +// { +// this.NumberOfComponents = 0; +// return; +// } +// if (numComps > 1) +// { // Extra range for vector magnitude (first in array). +// numComps = numComps + 1; +// } +// +// int idx; +// this.Ranges = new double[numComps * 2]; +// for (idx = 0; idx < numComps; ++idx) +// { +// this.Ranges[2 * idx] = VTK_DOUBLE_MAX; +// this.Ranges[2 * idx + 1] = -VTK_DOUBLE_MAX; +// } +// } + + //---------------------------------------------------------------------------- +// void vtkPVArrayInformation::SetComponentName(vtkIdType component, +// const char *name) +// { +// if (component < 0 || name == NULL) +// { +// return; +// } +// +// unsigned int index = static_cast (component); +// if (this.ComponentNames == NULL) +// { +// //delayed allocate +// this.ComponentNames +// = new vtkPVArrayInformation::vtkInternalComponentNames(); +// } +// +// if (index == this.ComponentNames.size()) +// { +// //the array isn't large enough, so we will resize +// this.ComponentNames.push_back(new vtkStdString(name)); +// return; +// } +// else if (index > this.ComponentNames.size()) +// { +// this.ComponentNames.resize(index + 1, NULL); +// } +// +// //replace an exisiting element +// vtkStdString *compName = this.ComponentNames.at(index); +// if (!compName) +// { +// compName = new vtkStdString(name); +// this.ComponentNames.at(index) = compName; +// } +// else +// { +// compName.assign(name); +// } +// } + + //---------------------------------------------------------------------------- +// const char* vtkPVArrayInformation::GetComponentName(vtkIdType component) +// { +// unsigned int index = static_cast (component); +// //check signed component for less than zero +// if (this.ComponentNames && component >= 0 && index +// < this.ComponentNames.size()) +// { +// vtkStdString *compName = this.ComponentNames.at(index); +// if (compName) +// { +// return compName.c_str(); +// } +// } +// else if (this.ComponentNames && component == -1 +// && this.ComponentNames.size() >= 1) +// { +// //we have a scalar array, and we need the component name +// vtkStdString *compName = this.ComponentNames.at(0); +// if (compName) +// { +// return compName.c_str(); +// } +// } +// //we have failed to find a user set component name, use the default component name +// this.DetermineDefaultComponentName(component, this.GetNumberOfComponents()); +// return this.DefaultComponentName.c_str(); +// } + + //---------------------------------------------------------------------------- +// void vtkPVArrayInformation::SetComponentRange(int comp, double min, double max) +// { +// if (comp >= this.NumberOfComponents || this.NumberOfComponents <= 0) +// { +// vtkErrorMacro("Bad component"); +// } +// if (this.NumberOfComponents > 1) +// { // Shift over vector mag range. +// ++comp; +// } +// if (comp < 0) +// { // anything less than 0 just defaults to the vector mag. +// comp = 0; +// } +// this.Ranges[comp * 2] = min; +// this.Ranges[comp * 2 + 1] = max; +// } + + //---------------------------------------------------------------------------- +// double* vtkPVArrayInformation::GetComponentRange(int comp) +// { +// if (comp >= this.NumberOfComponents || this.NumberOfComponents <= 0) +// { +// vtkErrorMacro("Bad component"); +// return NULL; +// } +// if (this.NumberOfComponents > 1) +// { // Shift over vector mag range. +// ++comp; +// } +// if (comp < 0) +// { // anything less than 0 just defaults to the vector mag. +// comp = 0; +// } +// return this.Ranges + comp * 2; +// } + + //---------------------------------------------------------------------------- +// void vtkPVArrayInformation::GetComponentRange(int comp, double *range) +// { +// double *ptr; +// +// ptr = this.GetComponentRange(comp); +// +// if (ptr == NULL) +// { +// range[0] = VTK_DOUBLE_MAX; +// range[1] = -VTK_DOUBLE_MAX; +// return; +// } +// +// range[0] = ptr[0]; +// range[1] = ptr[1]; +// } + + //---------------------------------------------------------------------------- +// void vtkPVArrayInformation::GetDataTypeRange(double range[2]) +// { +// int dataType = this.GetDataType(); +// switch (dataType) +// { +// case VTK_BIT: +// range[0] = VTK_BIT_MAX; +// range[1] = VTK_BIT_MAX; +// break; +// case VTK_UNSIGNED_CHAR: +// range[0] = VTK_UNSIGNED_CHAR_MIN; +// range[1] = VTK_UNSIGNED_CHAR_MAX; +// break; +// case VTK_CHAR: +// range[0] = VTK_CHAR_MIN; +// range[1] = VTK_CHAR_MAX; +// break; +// case VTK_UNSIGNED_SHORT: +// range[0] = VTK_UNSIGNED_SHORT_MIN; +// range[1] = VTK_UNSIGNED_SHORT_MAX; +// break; +// case VTK_SHORT: +// range[0] = VTK_SHORT_MIN; +// range[1] = VTK_SHORT_MAX; +// break; +// case VTK_UNSIGNED_INT: +// range[0] = VTK_UNSIGNED_INT_MIN; +// range[1] = VTK_UNSIGNED_INT_MAX; +// break; +// case VTK_INT: +// range[0] = VTK_INT_MIN; +// range[1] = VTK_INT_MAX; +// break; +// case VTK_UNSIGNED_LONG: +// range[0] = VTK_UNSIGNED_LONG_MIN; +// range[1] = VTK_UNSIGNED_LONG_MAX; +// break; +// case VTK_LONG: +// range[0] = VTK_LONG_MIN; +// range[1] = VTK_LONG_MAX; +// break; +// case VTK_FLOAT: +// range[0] = VTK_FLOAT_MIN; +// range[1] = VTK_FLOAT_MAX; +// break; +// case VTK_DOUBLE: +// range[0] = VTK_DOUBLE_MIN; +// range[1] = VTK_DOUBLE_MAX; +// break; +// default: +// // Default value: +// range[0] = 0; +// range[1] = 1; +// break; +// } +// } + //---------------------------------------------------------------------------- + void AddRanges(VTKArrayInformation info) + { + if (this.NumberOfComponents != info.NumberOfComponents) + { + System.err.println("Component mismatch."); + } + + double[] range = info.Ranges[0]; + if (this.NumberOfComponents > 1) + { + if (range[0] < this.Ranges[0][0]) + { + Ranges[0][0] = range[0]; + } + if (range[1] > Ranges[0][1]) + { + Ranges[0][1] = range[1]; + } + for (int idx = 0; idx < this.NumberOfComponents; ++idx) + { + range = info.Ranges[idx]; + if (range[0] < Ranges[idx+1][0]) + { + Ranges[idx+1][0] = range[0]; + } + if (range[1] > Ranges[idx+1][1]) + { + Ranges[idx+1][1] = range[1]; + } + } + } else { + if (range[0] < this.Ranges[0][0]) + { + Ranges[0][0] = range[0]; + } + if (range[1] > Ranges[0][1]) + { + Ranges[0][1] = range[1]; + } + } + + + this.NumberOfTuples += info.NumberOfTuples; + } + + //---------------------------------------------------------------------------- + void DeepCopy(VTKArrayInformation info) + { + this.Name = info.Name; + this.DataType = info.DataType; + this.NumberOfComponents = info.NumberOfComponents; + this.NumberOfTuples = info.NumberOfTuples; + + if (this.NumberOfComponents > 1) + { + this.Ranges = new double[this.NumberOfComponents+1][2]; + for (int idx = 0; idx < this.NumberOfComponents+1; ++idx) + { + this.Ranges[idx] = info.Ranges[idx]; + } + } else { + this.Ranges = new double[this.NumberOfComponents][2]; + this.Ranges[0] = info.Ranges[0]; + } + + + //clear the vector of old data + if (this.ComponentNames != null) + { + this.ComponentNames = null; + } + + if (info.ComponentNames != null) + { +// this.ComponentNames +// = new vtkPVArrayInformation::vtkInternalComponentNames(); +// //copy the passed in components if they exist +// this.ComponentNames.reserve(info.ComponentNames.size()); +// const char *name; +// for (unsigned i = 0; i < info.ComponentNames.size(); ++i) +// { +// name = info.GetComponentName(i); +// if (name) +// { +// this.SetComponentName(i, name); +// } +// } + } + + if (this.InformationKeys == null) + { + this.InformationKeys = new ArrayList<>(); + } + + //clear the vector of old data + this.InformationKeys.clear(); + + if (info.InformationKeys != null) + { +// //copy the passed in components if they exist +// for (unsigned i = 0; i < info.InformationKeys.size(); ++i) +// { +// this.InformationKeys.push_back(info.InformationKeys.at(i)); +// } + } + } + + //---------------------------------------------------------------------------- + boolean Compare(VTKArrayInformation info) { + if (info == null) { + return false; + } + if (info.Name.equals(this.Name) && info.NumberOfComponents == this.NumberOfComponents && this.NumberOfInformationKeys == info.NumberOfInformationKeys) { + return true; + } + return false; + } + + //---------------------------------------------------------------------------- + void CopyFromObject(vtkObject obj) + { + this.Initialize(); + + vtkAbstractArray array = (vtkAbstractArray) obj; +// if (!array) +// { +// vtkErrorMacro("Cannot downcast to abstract array."); +// this.Initialize(); +// return; +// } + + this.Name = array.GetName(); + this.DataType = array.GetDataType(); + this.NumberOfComponents = array.GetNumberOfComponents(); + this.NumberOfTuples = array.GetNumberOfTuples(); + + if (array.HasAComponentName()) + { + //copy the component names over + for (int i = 0; i < this.NumberOfComponents; ++i) + { + String name = array.GetComponentName(i); + if (name != null) + { + //each component doesn't have to be named + this.ComponentNames.add(i, name); + } + } + } + + if (obj instanceof vtkDataArray) + { + vtkDataArray data_array = (vtkDataArray) obj; + + if (this.NumberOfComponents > 1) + { + this.Ranges = new double[this.NumberOfComponents+1][2]; + // First store range of vector magnitude. + data_array.GetRange(this.Ranges[0], -1); + for (int idx = 0; idx < this.NumberOfComponents; ++idx) + { + data_array.GetRange(this.Ranges[idx+1], idx); + } + } else { + this.Ranges = new double[this.NumberOfComponents][2]; + data_array.GetRange(this.Ranges[0], 0); + } + } + +// if(this.InformationKeys) +// { +// this.InformationKeys.clear(); +// delete this.InformationKeys; +// this.InformationKeys = 0; +// } + if (array.HasInformation()) + { +// vtkInformation info = array.GetInformation(); +// vtkInformationIterator it = new vtkInformationIterator(); +// it.SetInformationWeak(info); +// it.GoToFirstItem(); +// while (!it.IsDoneWithTraversal()) +// { +// vtkInformationKey key = it.GetCurrentKey(); +// this.AddInformationKey(key.GetLocation(), key.GetName()); +// it.GoToNextItem(); +// } +// it.Delete(); + } + } + + //---------------------------------------------------------------------------- + void AddInformation(VTKArrayInformation info) + { + if (info == null) { + return; + } + + if (info.NumberOfComponents > 0) + { + if (this.NumberOfComponents == 0) + { + // If this object is uninitialized, copy. + this.DeepCopy(info); + } + else + { + // Leave everything but ranges and unique values as original, add ranges and unique values. + this.AddRanges(info); + //this.AddInformationKeys(info); + } + } + } + + //----------------------------------------------------------------------------- +// void DetermineDefaultComponentName( +// const int &component_no, const int &num_components) +// { +// if (!this.DefaultComponentName) +// { +// this.DefaultComponentName = new vtkStdString(); +// } +// +// this.DefaultComponentName.assign(vtkPVPostFilter::DefaultComponentName(component_no, num_components)); +// } + +// void AddInformationKeys(VTKArrayInformation info) +// { +// for (int k = 0; k < info.NumberOfInformationKeys; k++) +// { +// this.AddUniqueInformationKey(info.GetInformationKeyLocation(k), +// info.GetInformationKeyName(k)); +// } +// } + +// void AddInformationKey(String location, String name) +// { +// if(this.InformationKeys == null) +// { +// this.InformationKeys = new vtkInternalInformationKeys(); +// } +// vtkPVArrayInformationInformationKey info = vtkPVArrayInformationInformationKey(); +// info.Location = location; +// info.Name = name; +// this.InformationKeys.push_back(info); +// } + +// void AddUniqueInformationKey(String location, String name) +// { +// if (!this.HasInformationKey(location, name)) +// { +// this.AddInformationKey(location, name); +// } +// } + +// int GetNumberOfInformationKeys() +// { +// return static_cast(this.InformationKeys ? this.InformationKeys.size() : 0); +// } + +// String GetInformationKeyLocation(int index) +// { +// if (index < 0 || index >= this.GetNumberOfInformationKeys()) +// return NULL; +// +// return this.InformationKeys.at(index).Location; +// } + +// String GetInformationKeyName(int index) +// { +// if (index < 0 || index >= this.GetNumberOfInformationKeys()) +// return NULL; +// +// return this.InformationKeys.at(index).Name; +// } + +// int HasInformationKey(String location, String name) +// { +// for (int k = 0; k < this.GetNumberOfInformationKeys(); k++) +// { +// String key_location = this.GetInformationKeyLocation(k); +// String key_name = this.GetInformationKeyName(k); +// if (strcmp(location, key_location) == 0 && strcmp(name, key_name) == 0) +// { +// return 1; +// } +// } +// return 0; +// } + +} diff --git a/src/eu/engys/vtk/info/VTKCompositeDataInformation.java b/src/eu/engys/vtk/info/VTKCompositeDataInformation.java new file mode 100644 index 0000000..e04e62c --- /dev/null +++ b/src/eu/engys/vtk/info/VTKCompositeDataInformation.java @@ -0,0 +1,419 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.info; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import vtk.vtkCompositeDataSet; +import vtk.vtkDataObject; +import vtk.vtkInformation; +import vtk.vtkMultiBlockDataSet; +import vtk.vtkMultiPieceDataSet; +import vtk.vtkObject; + +public class VTKCompositeDataInformation { + + class DataInformation { + VTKDataInformation Info; + String Name; + } + + private boolean DataIsComposite; + private boolean DataIsMultiPiece; + private int NumberOfPieces; + private List ChildrenInformation; + + public VTKCompositeDataInformation() { + // this.Internal = new vtkPVCompositeDataInformationInternals; + this.DataIsComposite = false; + this.DataIsMultiPiece = false; + this.NumberOfPieces = 0; + // DON'T FORGET TO UPDATE Initialize(). + } + + boolean GetDataIsComposite() { + return DataIsComposite; + } + + boolean GetDataIsMultiPiece() { + return DataIsMultiPiece; + } + void PrintSelf(PrintStream os, String indent) + { + os.println(indent+"DataIsMultiPiece: " + this.DataIsMultiPiece); + os.println(indent+"DataIsComposite: " + this.DataIsComposite); + } + +// VTKDataInformation GetDataInformationForCompositeIndex(int index) +// { +// if (!this.DataIsComposite) +// { +// return null; +// } +// +// if (this.DataIsMultiPiece) +// { +// if (index < this.NumberOfPieces) { +// (*index)=-1; +// return null; +// } +// +// (*index) -= this.NumberOfPieces; +// } +// +// for ( DataInformation d : ChildrenInformation) +// { +// if (d.Info != null) +// { +// VTKDataInformation info = d.Info.GetDataInformationForCompositeIndex(index); +// if ( (*index) == -1) +// { +// return info; +// } +// } else { +// (*index)--; +// if ((*index) < 0) +// { +// return null; +// } +// } +// } +// return null; +// } + + void Initialize() { + this.DataIsMultiPiece = false; + this.NumberOfPieces = 0; + this.DataIsComposite = false; + this.ChildrenInformation = new ArrayList<>(); + } + + int GetNumberOfChildren() { + return this.DataIsMultiPiece ? this.NumberOfPieces : ChildrenInformation.size(); + } + + VTKDataInformation GetDataInformation(int idx) { + if (this.DataIsMultiPiece) { + return null; + } + + if (idx >= ChildrenInformation.size()) { + return null; + } + + return this.ChildrenInformation.get(idx).Info; + } + + String GetName(int idx) { + if (this.DataIsMultiPiece) { + return null; + } + + if (idx >= this.ChildrenInformation.size()) { + return null; + } + + return this.ChildrenInformation.get(idx).Name; + } + + void CopyFromObject(vtkObject object) { + this.Initialize(); + + if (!(object instanceof vtkCompositeDataSet)) { + return; + } + + vtkCompositeDataSet cds = (vtkCompositeDataSet) object; + this.DataIsComposite = true; + + if (object instanceof vtkMultiPieceDataSet) { + vtkMultiPieceDataSet mpDS = (vtkMultiPieceDataSet) object; + this.DataIsMultiPiece = true; + this.NumberOfPieces = mpDS.GetNumberOfPieces(); + return; + } + + if(object instanceof vtkMultiBlockDataSet){ + vtkMultiBlockDataSet mbds = (vtkMultiBlockDataSet) object; + for (int i = 0; i < mbds.GetNumberOfBlocks(); i++) { + VTKDataInformation childInfo = null; + vtkDataObject block = mbds.GetBlock(i); + if (block != null) { + if (block != null) { + childInfo = new VTKDataInformation(); + childInfo.CopyFromObject(block); + } + DataInformation d = new DataInformation(); + d.Info = childInfo; + + vtkInformation info = block.GetInformation(); + if (info.Has(cds.NAME()) != 0) { + d.Name = info.Get(cds.NAME()); + } + +// if (iter.HasCurrentMetaData() != 0) { +// vtkInformation info = iter.GetCurrentMetaData(); +// if (info.Has(cds.NAME()) != 0) { +// d.Name = info.Get(cds.NAME()); +// } +// } + + ChildrenInformation.add(d); + } + } + } + // vtkTimerLog::MarkEndEvent("Copying information from composite data"); + } + + + // void vtkPVCompositeDataInformation::CopyFromAMR(vtkUniformGridAMR* amr) + // { + // unsigned int num_levels = amr.GetNumberOfLevels(); + // if (num_levels == 0) + // { + // this.Internal.ChildrenInformation.clear(); + // } + // else + // { + // this.Internal.ChildrenInformation.resize(num_levels); + // } + // + // // we use this to "simulate" a composite tree from AMR + // vtkNew tempMultiPiece; + // vtkNew tempDSInfo; + // + // for (unsigned int level=0; level < num_levels; level++) + // { + // unsigned int num_datasets = amr.GetNumberOfDataSets(level); + // tempMultiPiece.SetNumberOfPieces(num_datasets); + // + // vtkNew levelInfo; + // levelInfo.CopyFromCompositeDataSetInitialize(tempMultiPiece.GetPointer()); + // + // // now fill up levelInfo with meta-data about arrays. + // for (unsigned int idx=0; idx < num_datasets; idx++) + // { + // vtkUniformGrid* dataset = amr.GetDataSet(level, idx); + // if (dataset) + // { + // tempDSInfo.CopyFromObject(dataset); + // levelInfo.AddInformation(tempDSInfo.GetPointer(), 1); + // } + // } + // levelInfo.CopyFromCompositeDataSetFinalize(tempMultiPiece.GetPointer()); + // this.Internal.ChildrenInformation[level].Info = levelInfo.GetPointer(); + // } + // } + + //Called to merge informations from two processess. + void AddInformation(VTKCompositeDataInformation info) + { + if (info == null) + { + System.err.println("Cound not cast object to data information."); + return; + } + + this.DataIsComposite = info.GetDataIsComposite(); + this.DataIsMultiPiece = info.GetDataIsMultiPiece(); + if (this.DataIsMultiPiece) + { + if (this.NumberOfPieces != info.NumberOfPieces) + { + // vtkWarningMacro("Mismatch in number of pieces among processes."); + } + if (info.NumberOfPieces > this.NumberOfPieces) + { + this.NumberOfPieces = info.NumberOfPieces; + } + return; + } + + int otherNumChildren = info.ChildrenInformation.size(); + int numChildren = this.ChildrenInformation.size(); + if ( otherNumChildren > numChildren) + { + numChildren = otherNumChildren; + //this.ChildrenInformation.resize(numChildren); + } + + for (int i=0; i < otherNumChildren; i++) + { + VTKDataInformation otherInfo = info.ChildrenInformation.get(i).Info; + VTKDataInformation localInfo = this.ChildrenInformation.get(i).Info; + if (otherInfo != null) + { + if (localInfo != null) + { + localInfo.AddInformation(otherInfo); + } + else + { + VTKDataInformation dinf = new VTKDataInformation(); + dinf.AddInformation(otherInfo); + this.ChildrenInformation.get(i).Info = dinf; + } + } + + String otherName = info.ChildrenInformation.get(i).Name; + String localName = this.ChildrenInformation.get(i).Name; + if (!otherName.isEmpty()) + { + if (!localName.isEmpty() && localName != otherName) + { + //vtkWarningMacro("Same block is named as \'" << localName.c_str() + // << "\' as well as \'" << otherName.c_str() << "\'"); + } + localName = otherName; + } + } + } + + // void vtkPVCompositeDataInformation::CopyToStream( + // vtkClientServerStream* css) + // { + // // vtkTimerLog::MarkStartEvent("Copying composite information to stream"); + // css.Reset(); + // *css << vtkClientServerStream::Reply + // << this.DataIsComposite + // << this.DataIsMultiPiece + // << this.NumberOfPieces; + // + // unsigned int numChildren = static_cast( + // this.Internal.ChildrenInformation.size()); + // *css << numChildren; + // + // for(unsigned i=0; i(length)); + // } + // } + // *css << numChildren; // DONE marker + // *css << vtkClientServerStream::End; + // // vtkTimerLog::MarkEndEvent("Copying composite information to stream"); + // } + // + // //---------------------------------------------------------------------------- + // void vtkPVCompositeDataInformation::CopyFromStream( + // const vtkClientServerStream* css) + // { + // this.Initialize(); + // + // if(!css.GetArgument(0, 0, &this.DataIsComposite)) + // { + // vtkErrorMacro("Error parsing data set type."); + // return; + // } + // + // if(!css.GetArgument(0, 1, &this.DataIsMultiPiece)) + // { + // vtkErrorMacro("Error parsing data set type."); + // return; + // } + // + // if(!css.GetArgument(0, 2, &this.NumberOfPieces)) + // { + // vtkErrorMacro("Error parsing number of pieces."); + // return; + // } + // + // unsigned int numChildren; + // if(!css.GetArgument(0, 3, &numChildren)) + // { + // vtkErrorMacro("Error parsing number of children."); + // return; + // } + // int msgIdx = 3; + // this.Internal.ChildrenInformation.resize(numChildren); + // + // while (1) + // { + // msgIdx++; + // unsigned int childIdx; + // if(!css.GetArgument(0, msgIdx, &childIdx)) + // { + // vtkErrorMacro("Error parsing data set type."); + // return; + // } + // if (childIdx >= numChildren) //receiver DONE marker. + // { + // break; + // } + // msgIdx++; + // + // const char* name = 0; + // if (!css.GetArgument(0, msgIdx, &name)) + // { + // vtkErrorMacro("Error parsing the name for the block."); + // return; + // } + // + // vtkTypeUInt32 length; + // std::vector data; + // vtkClientServerStream dcss; + // + // msgIdx++; + // // Data information. + // vtkPVDataInformation* dataInf = vtkPVDataInformation::New(); + // if(!css.GetArgumentLength(0, msgIdx, &length)) + // { + // vtkErrorMacro("Error parsing length of cell data information."); + // dataInf.Delete(); + // return; + // } + // data.resize(length); + // if(!css.GetArgument(0, msgIdx, &*data.begin(), length)) + // { + // vtkErrorMacro("Error parsing cell data information."); + // dataInf.Delete(); + // return; + // } + // dcss.SetData(&*data.begin(), length); + // dataInf.CopyFromStream(&dcss); + // this.Internal.ChildrenInformation[childIdx].Info = dataInf; + // this.Internal.ChildrenInformation[childIdx].Name = name; + // dataInf.Delete(); + // } + // + // } + +} diff --git a/src/eu/engys/vtk/info/VTKConstants.java b/src/eu/engys/vtk/info/VTKConstants.java new file mode 100644 index 0000000..e87614c --- /dev/null +++ b/src/eu/engys/vtk/info/VTKConstants.java @@ -0,0 +1,68 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.info; + +public class VTKConstants { + + public static final int VTK_VOID = -1; + public static final int VTK_POLY_DATA = 0; + public static final int VTK_STRUCTURED_POINTS = 1; + public static final int VTK_STRUCTURED_GRID = 2; + public static final int VTK_RECTILINEAR_GRID = 3; + public static final int VTK_UNSTRUCTURED_GRID = 4; + public static final int VTK_PIECEWISE_FUNCTION = 5; + public static final int VTK_IMAGE_DATA = 6; + public static final int VTK_DATA_OBJECT = 7; + public static final int VTK_DATA_SET = 8; + public static final int VTK_POINT_SET = 9; + public static final int VTK_UNIFORM_GRID = 10; + public static final int VTK_COMPOSITE_DATA_SET = 11; + public static final int VTK_MULTIGROUP_DATA_SET = 12; + public static final int VTK_MULTIBLOCK_DATA_SET = 13; + public static final int VTK_HIERARCHICAL_DATA_SET = 14; + public static final int VTK_HIERARCHICAL_BOX_DATA_SET = 15; + public static final int VTK_GENERIC_DATA_SET = 16; + public static final int VTK_HYPER_OCTREE = 17; + public static final int VTK_TEMPORAL_DATA_SET = 18; + public static final int VTK_TABLE = 19; + public static final int VTK_GRAPH = 20; + public static final int VTK_TREE = 21; + public static final int VTK_SELECTION = 22; + public static final int VTK_DIRECTED_GRAPH = 23; + public static final int VTK_UNDIRECTED_GRAPH = 24; + public static final int VTK_MULTIPIECE_DATA_SET = 25; + public static final int VTK_DIRECTED_ACYCLIC_GRAPH = 26; + public static final int VTK_ARRAY_DATA = 27; + public static final int VTK_REEB_GRAPH = 28; + public static final int VTK_UNIFORM_GRID_AMR = 29; + public static final int VTK_NON_OVERLAPPING_AMR = 30; + public static final int VTK_OVERLAPPING_AMR = 31; + public static final int VTK_HYPER_TREE_GRID = 32; + public static final int VTK_MOLECULE = 33; + public static final int VTK_PISTON_DATA_OBJECT = 34; + public static final int VTK_PATH = 35; + +} diff --git a/src/eu/engys/vtk/info/VTKDataInformation.java b/src/eu/engys/vtk/info/VTKDataInformation.java new file mode 100644 index 0000000..2baac66 --- /dev/null +++ b/src/eu/engys/vtk/info/VTKDataInformation.java @@ -0,0 +1,1240 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.info; + +import java.io.PrintStream; + +import vtk.vtkAlgorithm; +import vtk.vtkAlgorithmOutput; +import vtk.vtkCompositeDataSet; +import vtk.vtkDataObject; +import vtk.vtkDataSet; +import vtk.vtkFieldData; +import vtk.vtkGenericDataSet; +import vtk.vtkImageData; +import vtk.vtkInformation; +import vtk.vtkMultiBlockDataSet; +import vtk.vtkObject; +import vtk.vtkPointSet; +import vtk.vtkRectilinearGrid; +import vtk.vtkStructuredGrid; +import vtk.vtkUniformGrid; +import eu.engys.util.Util; + +public class VTKDataInformation { + + private VTKCompositeDataInformation CompositeDataInformation = new VTKCompositeDataInformation(); + private VTKDataSetAttributesInformation PointDataInformation = new VTKDataSetAttributesInformation(); + private VTKDataSetAttributesInformation CellDataInformation = new VTKDataSetAttributesInformation(); + private VTKDataSetAttributesInformation VertexDataInformation = new VTKDataSetAttributesInformation(); + private VTKDataSetAttributesInformation EdgeDataInformation = new VTKDataSetAttributesInformation(); + private VTKDataSetAttributesInformation RowDataInformation = new VTKDataSetAttributesInformation(); + private VTKDataSetAttributesInformation FieldDataInformation = new VTKDataSetAttributesInformation(); + private VTKArrayInformation PointArrayInformation = new VTKArrayInformation(); + + private int CompositeDataSetType, DataSetType, NumberOfPoints, NumberOfCells, NumberOfRows, MemorySize, PolygonCount, NumberOfDataSets, HasTime, PortNumber; + private String DataClassName, TimeLabel, CompositeDataClassName; + private double[] Bounds; + private int[] Extent; + private double Time; + private boolean SortArrays; + + public VTKDataInformation() { + Initialize(); + } + + private void Initialize() { + this.DataSetType = -1; + this.CompositeDataSetType = -1; + this.NumberOfPoints = 0; + this.NumberOfCells = 0; + this.NumberOfRows = 0; + this.NumberOfDataSets = 0; + this.MemorySize = 0; + this.PolygonCount = 0; + this.Bounds = new double[6]; + this.Bounds[0] = this.Bounds[2] = this.Bounds[4] = Double.MAX_VALUE; + this.Bounds[1] = this.Bounds[3] = this.Bounds[5] = -Double.MAX_VALUE; + this.Extent = new int[6]; + this.Extent[0] = this.Extent[2] = this.Extent[4] = Integer.MAX_VALUE; + this.Extent[1] = this.Extent[3] = this.Extent[5] = -Integer.MAX_VALUE; + this.PointDataInformation.Initialize(); + this.CellDataInformation.Initialize(); + this.VertexDataInformation.Initialize(); + this.EdgeDataInformation.Initialize(); + this.RowDataInformation.Initialize(); + this.FieldDataInformation.Initialize(); + this.CompositeDataInformation.Initialize(); + this.PointArrayInformation.Initialize(); + this.DataClassName = ""; + this.CompositeDataClassName = ""; + // this.TimeSpan[0] = VTK_DOUBLE_MAX; + // this.TimeSpan[1] = -VTK_DOUBLE_MAX; + this.HasTime = 0; + this.Time = 0.0; + // this.SetTimeLabel(NULL); + } + + private void DeepCopy(VTKDataInformation dataInfo, boolean copyCompositeInformation) { + + this.DataSetType = dataInfo.DataSetType; + this.CompositeDataSetType = dataInfo.CompositeDataSetType; + this.DataClassName = dataInfo.DataClassName; + this.CompositeDataClassName = dataInfo.CompositeDataClassName; + + this.NumberOfDataSets = dataInfo.NumberOfDataSets; + + this.NumberOfPoints = dataInfo.NumberOfPoints; + this.NumberOfCells = dataInfo.NumberOfCells; + this.NumberOfRows = dataInfo.NumberOfRows; + this.MemorySize = dataInfo.MemorySize; + this.PolygonCount = dataInfo.PolygonCount; + + Util.deepCopy(dataInfo.Bounds, this.Bounds); + Util.deepCopy(dataInfo.Extent, this.Extent); + + // Copy attribute information. + this.PointDataInformation.DeepCopy(dataInfo.PointDataInformation); + this.CellDataInformation.DeepCopy(dataInfo.CellDataInformation); + this.VertexDataInformation.DeepCopy(dataInfo.VertexDataInformation); + this.EdgeDataInformation.DeepCopy(dataInfo.EdgeDataInformation); + this.RowDataInformation.DeepCopy(dataInfo.RowDataInformation); + this.FieldDataInformation.DeepCopy(dataInfo.FieldDataInformation); + if (copyCompositeInformation) { + this.CompositeDataInformation.AddInformation(dataInfo.CompositeDataInformation); + } + this.PointArrayInformation.AddInformation(dataInfo.PointArrayInformation); + + // double *timespan; + // timespan = dataInfo.GetTimeSpan(); + // this.TimeSpan[0] = timespan[0]; + // this.TimeSpan[1] = timespan[1]; + // this.SetTimeLabel(dataInfo.GetTimeLabel()); + } + + public void AddFromMultiBlockDataSet(vtkMultiBlockDataSet data) { + for (int i = 0; i < data.GetNumberOfBlocks(); i++) { + vtkDataObject block = data.GetBlock(i); + if (block != null) { + VTKDataInformation dinf = new VTKDataInformation(); + dinf.CopyFromObject(block); + dinf.DataClassName = block.GetClassName(); + dinf.DataSetType = block.GetDataObjectType(); + this.AddInformation(dinf, true); + block.Delete(); + } + } + + } + + public void CopyFromObject(vtkObject object) { + vtkDataObject dobj = null; + vtkInformation info = null; + // Handle the case where the a vtkAlgorithmOutput is passed instead of + // the data object. vtkSMPart uses vtkAlgorithmOutput. + if (!(object instanceof vtkDataObject)) { + if (object instanceof vtkAlgorithmOutput) { + vtkAlgorithmOutput algOutput = (vtkAlgorithmOutput) object; + vtkAlgorithm producer = algOutput.GetProducer(); + if (producer != null && producer.GetClassName().equals("vtkPVNullSource")) { + // Don't gather any data information from the hypothetical + // null source. + return; + } + + if (producer.IsA("vtkPVPostFilter") == 0) { + algOutput = producer.GetInputConnection(0, 0); + } + info = producer.GetOutputPortInformation(this.PortNumber); + dobj = producer.GetOutputDataObject(algOutput.GetIndex()); + + producer.Delete(); + algOutput.Delete(); + } else if (object instanceof vtkAlgorithm) { + vtkAlgorithm algo = (vtkAlgorithm) object; + // We don't use vtkAlgorithm::GetOutputDataObject() since that + // call a UpdateDataObject() pass, which may raise errors if the + // algo + // is not fully setup yet. + if (algo.GetClassName().equals("vtkPVNullSource")) { + // Don't gather any data information from the hypothetical + // null source. + return; + } + info = algo.GetExecutive().GetOutputInformation(this.PortNumber); + // if (!info || vtkDataObject::GetData(info) == NULL) + // { + // return; + // } + dobj = algo.GetOutputDataObject(this.PortNumber); + algo.Delete(); + } + } else { + dobj = (vtkDataObject) object; + } + + if (object instanceof vtkCompositeDataSet) { + vtkCompositeDataSet cds = (vtkCompositeDataSet) dobj; + this.CopyFromCompositeDataSet(cds); + this.CopyCommonMetaData(cds, info); + return; + } + + if (object instanceof vtkDataSet) { + vtkDataSet ds = (vtkDataSet) dobj; + this.CopyFromDataSet(ds); + this.CopyCommonMetaData(ds, info); + return; + } + + if (object instanceof vtkGenericDataSet) { + vtkGenericDataSet ads = (vtkGenericDataSet) dobj; + this.CopyFromGenericDataSet(ads); + this.CopyCommonMetaData(ads, info); + return; + } + + // vtkGraph* graph = vtkGraph::SafeDownCast(dobj); + // if( graph) + // { + // this.CopyFromGraph(graph); + // this.CopyCommonMetaData(dobj, info); + // return; + // } + // + // vtkTable* table = vtkTable::SafeDownCast(dobj); + // if (table) + // { + // this.CopyFromTable(table); + // this.CopyCommonMetaData(dobj, info); + // return; + // } + // + // vtkSelection* selection = vtkSelection::SafeDownCast(dobj); + // if (selection) + // { + // this.CopyFromSelection(selection); + // this.CopyCommonMetaData(dobj, info); + // return; + // } + // + // String cname = dobj.GetClassName(); + // vtkPVDataInformationHelper *dhelper = + // vtkPVDataInformation::FindHelper + // (cname); + // if (dhelper) + // { + // dhelper.CopyFromDataObject(this, dobj); + // this.CopyCommonMetaData(dobj, info); + // dhelper.Delete(); + // return; + // } + + // Because custom applications may implement their own data + // object types, this isn't an error condition - just + // display the name of the data object and return quietly. + this.DataClassName = dobj.GetClassName(); + this.CopyCommonMetaData(dobj, info); + } + + private void CopyFromCompositeDataSetInitialize(vtkCompositeDataSet data) { + this.Initialize(); + this.CompositeDataInformation.CopyFromObject(data); + } + + private void CopyFromCompositeDataSetFinalize(vtkCompositeDataSet data) { + this.CompositeDataClassName = data.GetClassName(); + this.CompositeDataSetType = data.GetDataObjectType(); + + if (this.DataSetType == -1) { + // This is a composite dataset with no non-empty leaf node. Set some + // data type (Look at BUG #7144). + this.DataClassName = "vtkDataSet"; + this.DataSetType = VTKConstants.VTK_DATA_SET; + } + } + + private void CopyFromCompositeDataSet(vtkCompositeDataSet data) { + this.CopyFromCompositeDataSetInitialize(data); + + int numDataSets = this.CompositeDataInformation.GetNumberOfChildren(); + if (this.CompositeDataInformation.GetDataIsMultiPiece()) { + } else { + for (int cc = 0; cc < numDataSets; cc++) { + VTKDataInformation childInfo = this.CompositeDataInformation.GetDataInformation(cc); + if (childInfo != null) { + this.AddInformation(childInfo, true); + } + } + } + + this.CopyFromCompositeDataSetFinalize(data); + + // AddInformation should have updated NumberOfDataSets correctly to + // count number of non-zero datasets. We don't need to fix it here. + // this.NumberOfDataSets = numDataSets; + } + + private void CopyCommonMetaData(vtkDataObject data, vtkInformation pinfo) { + // Gather some common stuff + // if (pinfo && + // pinfo.Has(vtkStreamingDemandDrivenPipeline::TIME_RANGE())) + // { + // double *times = + // pinfo.Get(vtkStreamingDemandDrivenPipeline::TIME_RANGE()); + // this.TimeSpan[0] = times[0]; + // this.TimeSpan[1] = times[1]; + // } + // + // this.SetTimeLabel( + // (pinfo && + // pinfo.Has(vtkStreamingDemandDrivenPipeline::TIME_LABEL_ANNOTATION())) + // ? + // pinfo.Get(vtkStreamingDemandDrivenPipeline::TIME_LABEL_ANNOTATION()) + // : NULL); + // + // vtkInformation *dinfo = data.GetInformation(); + // if (dinfo.Has(vtkDataObject::DATA_TIME_STEP())) + // { + // double time = dinfo.Get(vtkDataObject::DATA_TIME_STEP()); + // this.Time = time; + // this.HasTime = 1; + // } + } + + private void CopyFromDataSet(vtkDataSet data) { + int idx; + double[] bds = null; + int[] ext = null; + + this.DataClassName = data.GetClassName(); + this.DataSetType = data.GetDataObjectType(); + + this.NumberOfDataSets = 1; + + switch (this.DataSetType) { + case VTKConstants.VTK_IMAGE_DATA: + ext = ((vtkImageData) data).GetExtent(); + break; + case VTKConstants.VTK_STRUCTURED_GRID: + ext = ((vtkStructuredGrid) data).GetExtent(); + break; + case VTKConstants.VTK_RECTILINEAR_GRID: + ext = ((vtkRectilinearGrid) data).GetExtent(); + break; + case VTKConstants.VTK_UNIFORM_GRID: + ext = ((vtkUniformGrid) data).GetExtent(); + break; + case VTKConstants.VTK_UNSTRUCTURED_GRID: + case VTKConstants.VTK_POLY_DATA: + this.PolygonCount = data.GetNumberOfCells(); + break; + } + if (ext != null) { + for (idx = 0; idx < 6; ++idx) { + this.Extent[idx] = ext[idx]; + } + } + + this.NumberOfPoints = data.GetNumberOfPoints(); + if (this.NumberOfPoints == 0) { + return; + } + + // We do not want to get the number of dual cells from an octree + // because this triggers generation of connectivity arrays. + if (data.GetDataObjectType() != VTKConstants.VTK_HYPER_OCTREE) { + this.NumberOfCells = data.GetNumberOfCells(); + } + + bds = data.GetBounds(); + for (idx = 0; idx < 6; ++idx) { + this.Bounds[idx] = bds[idx]; + } + this.MemorySize = data.GetActualMemorySize(); + + if (data instanceof vtkPointSet) { + vtkPointSet ps = (vtkPointSet) data; + if (ps.GetPoints() != null) { + this.PointArrayInformation.CopyFromObject(ps.GetPoints().GetData()); + } + } + + // Copy Point Data information + this.PointDataInformation.CopyFromDataSetAttributes(data.GetPointData()); + + // Copy Cell Data information + this.CellDataInformation.CopyFromDataSetAttributes(data.GetCellData()); + + // Copy Field Data information, if any + vtkFieldData fd = data.GetFieldData(); + if (fd != null && fd.GetNumberOfArrays() > 0) { + this.FieldDataInformation.CopyFromFieldData(fd); + } + } + + private void CopyFromGenericDataSet(vtkGenericDataSet data) { + this.DataClassName = data.GetClassName(); + this.DataSetType = data.GetDataObjectType(); + + this.NumberOfDataSets = 1; + this.NumberOfPoints = data.GetNumberOfPoints(); + if (this.NumberOfPoints == 0) { + return; + } + // We do not want to get the number of dual cells from an octree + // because this triggers generation of connectivity arrays. + if (data.GetDataObjectType() != VTKConstants.VTK_HYPER_OCTREE) { + this.NumberOfCells = data.GetNumberOfCells(-1); + } + + data.GetBounds(this.Bounds); + + this.MemorySize = data.GetActualMemorySize(); + + switch (this.DataSetType) { + case VTKConstants.VTK_POLY_DATA: + this.PolygonCount = data.GetNumberOfCells(2); + break; + } + + // Copy Point Data information + this.PointDataInformation.CopyFromGenericAttributesOnPoints(data.GetAttributes()); + + // Copy Cell Data information + this.CellDataInformation.CopyFromGenericAttributesOnCells(data.GetAttributes()); + } + + public void AddInformation(VTKDataInformation info) { + this.AddInformation(info, false); + } + + private void AddInformation(VTKDataInformation info, boolean addingParts) { + if (info == null) { + System.err.println("Cound not cast object to data information."); + return; + } + + // if (!addingParts) { + // this.SetCompositeDataClassName(info.CompositeDataClassName); + // this.CompositeDataSetType = info.CompositeDataSetType; + // this.CompositeDataInformation.AddInformation(info.CompositeDataInformation); + // } + + if (info.NumberOfDataSets == 0) { + return; + } + + if (this.NumberOfPoints == 0 && this.NumberOfCells == 0 && this.NumberOfDataSets == 0) { + // Just copy the other array information. + this.DeepCopy(info, !addingParts); + return; + } + + // For data set, lets pick the common super class. + // This supports Heterogeneous collections. + // We need a new classification: Structured. + // This would allow extracting grid from mixed structured collections. + if (this.DataSetType != info.DataSetType) { // IsTypeOf method will not + // work here. Must be done + // manually. + if (this.DataSetType == VTKConstants.VTK_IMAGE_DATA || this.DataSetType == VTKConstants.VTK_RECTILINEAR_GRID || this.DataSetType == VTKConstants.VTK_DATA_SET || info.DataSetType == VTKConstants.VTK_IMAGE_DATA || info.DataSetType == VTKConstants.VTK_RECTILINEAR_GRID || info.DataSetType == VTKConstants.VTK_DATA_SET) { + this.DataSetType = VTKConstants.VTK_DATA_SET; + this.DataClassName = "vtkDataSet"; + } else { + if (this.DataSetType == VTKConstants.VTK_GENERIC_DATA_SET || info.DataSetType == VTKConstants.VTK_GENERIC_DATA_SET) { + this.DataSetType = VTKConstants.VTK_GENERIC_DATA_SET; + this.DataClassName = "vtkGenericDataSet"; + } else { + this.DataSetType = VTKConstants.VTK_POINT_SET; + this.DataClassName = "vtkPointSet"; + } + } + } + + // Empty data set? Ignore bounds, extent and array info. + if (info.NumberOfCells == 0 && info.NumberOfPoints == 0) { + return; + } + + // First the easy stuff. + this.NumberOfPoints += info.NumberOfPoints; + this.NumberOfCells += info.NumberOfCells; + this.MemorySize += info.MemorySize; + this.NumberOfRows += info.NumberOfRows; + + switch (this.DataSetType) { + case VTKConstants.VTK_POLY_DATA: + this.PolygonCount += info.NumberOfCells; + break; + } + if (addingParts) { + // Adding data information of parts + this.NumberOfDataSets += info.NumberOfDataSets; + } else { + // Adding data information of 1 part across processors + if (this.CompositeDataClassName != null) { + // Composite data blocks are not distributed across processors. + // Simply add their number. + this.NumberOfDataSets += info.NumberOfDataSets; + } else { + // Simple data blocks are distributed across processors, use + // the largest number (actually, NumberOfDataSets should always + // be 1 since the data information is for a part) + if (this.NumberOfDataSets < info.NumberOfDataSets) { + this.NumberOfDataSets = info.NumberOfDataSets; + } + } + } + + // Bounds are only a little harder. + double[] bds = info.Bounds; + for (int i = 0; i < 3; ++i) { + int j = i * 2; + if (bds[j] < this.Bounds[j]) { + this.Bounds[j] = bds[j]; + } + ++j; + if (bds[j] > this.Bounds[j]) { + this.Bounds[j] = bds[j]; + } + } + + // Extents are only a little harder. + int[] ext = info.Extent; + for (int i = 0; i < 3; ++i) { + int j = i * 2; + if (ext[j] < this.Extent[j]) { + this.Extent[j] = ext[j]; + } + ++j; + if (ext[j] > this.Extent[j]) { + this.Extent[j] = ext[j]; + } + } + + // Now for the messy part, all of the arrays. + this.PointArrayInformation.AddInformation(info.PointArrayInformation); + this.PointDataInformation.AddInformation(info.PointDataInformation); + this.CellDataInformation.AddInformation(info.CellDataInformation); + this.VertexDataInformation.AddInformation(info.VertexDataInformation); + this.EdgeDataInformation.AddInformation(info.EdgeDataInformation); + this.RowDataInformation.AddInformation(info.RowDataInformation); + this.FieldDataInformation.AddInformation(info.FieldDataInformation); + // this.GenericAttributesInformation.AddInformation(info.GetGenericAttributesInformation()); + + // double times = info.GetTimeSpan(); + // if (times[0] < this.TimeSpan[0]) { + // this.TimeSpan[0] = times[0]; + // } + // if (times[1] > this.TimeSpan[1]) { + // this.TimeSpan[1] = times[1]; + // } + // + // if (!this.HasTime && info.GetHasTime()) { + // this.Time = info.GetTime(); + // this.HasTime = 1; + // } + // + // this.SetTimeLabel(info.GetTimeLabel()); + } + + String GetPrettyDataTypeString() { + int dataType = this.DataSetType; + if (this.CompositeDataSetType >= 0) { + dataType = this.CompositeDataSetType; + } + + switch (dataType) { + case VTKConstants.VTK_POLY_DATA: + return "Polygonal Mesh"; + case VTKConstants.VTK_STRUCTURED_POINTS: + return "Image (Uniform Rectilinear Grid)"; + case VTKConstants.VTK_STRUCTURED_GRID: + return "Structured (Curvilinear) Grid"; + case VTKConstants.VTK_RECTILINEAR_GRID: + return "Rectilinear Grid"; + case VTKConstants.VTK_UNSTRUCTURED_GRID: + return "Unstructured Grid"; + case VTKConstants.VTK_PIECEWISE_FUNCTION: + return "Piecewise function"; + case VTKConstants.VTK_IMAGE_DATA: + return "Image (Uniform Rectilinear Grid)"; + case VTKConstants.VTK_DATA_OBJECT: + return "Data Object"; + case VTKConstants.VTK_DATA_SET: + return "Data Set"; + case VTKConstants.VTK_POINT_SET: + return "Point Set"; + case VTKConstants.VTK_UNIFORM_GRID: + return "Image (Uniform Rectilinear Grid) with blanking"; + case VTKConstants.VTK_COMPOSITE_DATA_SET: + return "Composite Dataset"; + case VTKConstants.VTK_MULTIGROUP_DATA_SET: + return "Multi-group Dataset"; + case VTKConstants.VTK_MULTIBLOCK_DATA_SET: + return "Multi-block Dataset"; + case VTKConstants.VTK_HIERARCHICAL_DATA_SET: + return "Hierarchical DataSet (Deprecated)"; + case VTKConstants.VTK_HIERARCHICAL_BOX_DATA_SET: + return "AMR Dataset (Deprecated)"; + case VTKConstants.VTK_NON_OVERLAPPING_AMR: + return "Non-Overlapping AMR Dataset"; + case VTKConstants.VTK_OVERLAPPING_AMR: + return "Overlapping AMR Dataset"; + case VTKConstants.VTK_GENERIC_DATA_SET: + return "Generic Dataset"; + case VTKConstants.VTK_HYPER_OCTREE: + return "Hyper-octree"; + case VTKConstants.VTK_HYPER_TREE_GRID: + return "Hyper-tree Grid"; + case VTKConstants.VTK_TEMPORAL_DATA_SET: + return "Temporal Dataset"; + case VTKConstants.VTK_TABLE: + return "Table"; + case VTKConstants.VTK_GRAPH: + return "Graph"; + case VTKConstants.VTK_TREE: + return "Tree"; + case VTKConstants.VTK_SELECTION: + return "Selection"; + case VTKConstants.VTK_DIRECTED_GRAPH: + return "Directed Graph"; + case VTKConstants.VTK_UNDIRECTED_GRAPH: + return "Undirected Graph"; + case VTKConstants.VTK_MULTIPIECE_DATA_SET: + return "Multi-piece Dataset"; + case VTKConstants.VTK_DIRECTED_ACYCLIC_GRAPH: + return "Directed Acyclic Graph"; + default: + // vtkPVDataInformationHelper *dhelper = + // vtkPVDataInformation::FindHelper + // (this.DataClassName); + // if (dhelper) + // { + // const char *namestr = dhelper.GetPrettyDataTypeString(); + // dhelper.Delete(); + // return namestr; + // } + } + + return "UnknownType"; + } + + int IsDataStructured() { + switch (this.DataSetType) { + case VTKConstants.VTK_IMAGE_DATA: + case VTKConstants.VTK_STRUCTURED_GRID: + case VTKConstants.VTK_RECTILINEAR_GRID: + case VTKConstants.VTK_UNIFORM_GRID: + case VTKConstants.VTK_GENERIC_DATA_SET: + return 1; + } + return 0; + } + + public void PrintSelf(PrintStream os) { + + os.println("PortNumber: " + this.PortNumber); + os.println("DataSetType: " + this.DataSetType); + os.println("CompositeDataSetType: " + this.CompositeDataSetType); + os.println("NumberOfPoints: " + this.NumberOfPoints); + os.println("NumberOfRows: " + this.NumberOfRows); + os.println("NumberOfCells: " + this.NumberOfCells); + os.println("NumberOfDataSets: " + this.NumberOfDataSets); + os.println("MemorySize: " + this.MemorySize); + os.println("PolygonCount: " + this.PolygonCount); + os.println("Bounds: " + this.Bounds[0] + ", " + this.Bounds[1] + ", " + this.Bounds[2] + ", " + this.Bounds[3] + ", " + this.Bounds[4] + ", " + this.Bounds[5]); + os.println("Extent: " + this.Extent[0] + ", " + this.Extent[1] + ", " + this.Extent[2] + ", " + this.Extent[3] + ", " + this.Extent[4] + ", " + this.Extent[5]); + + String indent = " "; + os.println("PointDataInformation "); + this.PointDataInformation.PrintSelf(os, indent); + os.println("CellDataInformation "); + this.CellDataInformation.PrintSelf(os, indent); + os.println("VertexDataInformation"); + this.VertexDataInformation.PrintSelf(os, indent); + os.println("EdgeDataInformation"); + this.EdgeDataInformation.PrintSelf(os, indent); + os.println("RowDataInformation"); + this.RowDataInformation.PrintSelf(os, indent); + os.println("FieldDataInformation "); + this.FieldDataInformation.PrintSelf(os, indent); + os.println("CompositeDataInformation "); + this.CompositeDataInformation.PrintSelf(os, indent); + os.println("PointArrayInformation "); + this.PointArrayInformation.PrintSelf(os, indent); + + os.println("DataClassName: " + (this.DataClassName != null ? this.DataClassName : "(none)")); + os.println("CompositeDataClassName: " + (this.CompositeDataClassName != null ? this.CompositeDataClassName : "(none)")); + + // os.println("TimeSpan: " + this.TimeSpan[0] + ", " + this.TimeSpan[1] + // ); + + if (this.TimeLabel != null) { + os.println("TimeLabel: " + this.TimeLabel); + } + } + + public int getCompositeDataSetType() { + return CompositeDataSetType; + } + + public int getDataSetType() { + return DataSetType; + } + + public int getNumberOfPoints() { + return NumberOfPoints; + } + + public int getNumberOfCells() { + return NumberOfCells; + } + + public int getNumberOfRows() { + return NumberOfRows; + } + + public int getMemorySize() { + return MemorySize; + } + + public int getPolygonCount() { + return PolygonCount; + } + + public double[] getBounds() { + return Bounds; + } + + public int[] getExtent() { + return Extent; + } + + public String getDataClassName() { + return DataClassName; + } + + public String getCompositeDataClassName() { + return CompositeDataClassName; + } + + public int getNumberOfDataSets() { + return NumberOfDataSets; + } + + // String GetDataSetTypeAsString() + // { + // if(this.DataSetType == -1) + // { + // return "UnknownType"; + // } + // else + // { + // return vtkDataObjectTypes::GetClassNameFromTypeId(this.DataSetType); + // } + // } + + // Need to do this manually. + // int DataSetTypeIsA(String type) { + // if (strcmp(type, "vtkDataObject") == 0) { // Every type is of type + // vtkDataObject. + // return 1; + // } + // if (strcmp(type, "vtkDataSet") == 0) { // Every type is of type + // vtkDataObject. + // if (this.DataSetType == VTK_POLY_DATA || this.DataSetType == + // VTK_STRUCTURED_GRID || this.DataSetType == VTK_UNSTRUCTURED_GRID || + // this.DataSetType == VTK_IMAGE_DATA || this.DataSetType == + // VTK_RECTILINEAR_GRID || this.DataSetType == VTK_UNSTRUCTURED_GRID || + // this.DataSetType == VTK_HYPER_TREE_GRID || this.DataSetType == + // VTK_STRUCTURED_POINTS) { + // return 1; + // } + // } + // if (strcmp(type, this.GetDataSetTypeAsString()) == 0) { // If class names + // are the same, then they are of the same type. + // return 1; + // } + // if (strcmp(type, "vtkPointSet") == 0) { + // if (this.DataSetType == VTK_POLY_DATA || this.DataSetType == + // VTK_STRUCTURED_GRID || this.DataSetType == VTK_UNSTRUCTURED_GRID) { + // return 1; + // } + // } + // if (strcmp(type, "vtkStructuredData") == 0) { + // if (this.DataSetType == VTK_IMAGE_DATA || this.DataSetType == + // VTK_STRUCTURED_GRID || this.DataSetType == VTK_RECTILINEAR_GRID) { + // return 1; + // } + // } + // + // return 0; + // } + + // VTKDataInformation GetDataInformationForCompositeIndex(int index) + // { + // if (index == 0) + // { + // (*index)--; + // return this; + // } + // + // (*index)--; + // return + // this.CompositeDataInformation.GetDataInformationForCompositeIndex(index); + // } + + // void CopyToStream(vtkClientServerStream* css) + // { + // css.Reset(); + // *css << vtkClientServerStream::Reply; + // *css << this.DataClassName + // << this.DataSetType + // << this.NumberOfDataSets + // << this.NumberOfPoints + // << this.NumberOfCells + // << this.NumberOfRows + // << this.MemorySize + // << this.PolygonCount + // << this.Time + // << this.HasTime + // << this.TimeLabel + // << vtkClientServerStream::InsertArray(this.Bounds, 6) + // << vtkClientServerStream::InsertArray(this.Extent, 6); + // + // size_t length; + // const unsigned char* data; + // vtkClientServerStream dcss; + // + // this.PointArrayInformation.CopyToStream(&dcss); + // dcss.GetData(&data, &length); + // *css << vtkClientServerStream::InsertArray(data, + // static_cast(length)); + // + // dcss.Reset(); + // + // this.PointDataInformation.CopyToStream(&dcss); + // dcss.GetData(&data, &length); + // *css << vtkClientServerStream::InsertArray(data, + // static_cast(length)); + // + // dcss.Reset(); + // + // this.CellDataInformation.CopyToStream(&dcss); + // dcss.GetData(&data, &length); + // *css << vtkClientServerStream::InsertArray(data, + // static_cast(length)); + // + // dcss.Reset(); + // + // this.VertexDataInformation.CopyToStream(&dcss); + // dcss.GetData(&data, &length); + // *css << vtkClientServerStream::InsertArray(data, + // static_cast(length)); + // + // dcss.Reset(); + // + // this.EdgeDataInformation.CopyToStream(&dcss); + // dcss.GetData(&data, &length); + // *css << vtkClientServerStream::InsertArray(data, + // static_cast(length)); + // + // dcss.Reset(); + // + // this.RowDataInformation.CopyToStream(&dcss); + // dcss.GetData(&data, &length); + // *css << vtkClientServerStream::InsertArray(data, + // static_cast(length)); + // + // *css << this.CompositeDataClassName; + // *css << this.CompositeDataSetType; + // + // dcss.Reset(); + // + // this.CompositeDataInformation.CopyToStream(&dcss); + // dcss.GetData(&data, &length); + // *css << vtkClientServerStream::InsertArray(data, + // static_cast(length)); + // + // dcss.Reset(); + // + // this.FieldDataInformation.CopyToStream(&dcss); + // dcss.GetData(&data, &length); + // *css << vtkClientServerStream::InsertArray(data, + // static_cast(length)); + // + // *css << vtkClientServerStream::InsertArray(this.TimeSpan, 2); + // + // *css << vtkClientServerStream::End; + // } + + // void CopyFromStream(const vtkClientServerStream* css) + // { + // CSS_ARGUMENT_BEGIN(); + // + // const char* dataclassname = 0; + // if (!CSS_GET_NEXT_ARGUMENT(css, 0, &dataclassname)) + // { + // vtkErrorMacro("Error parsing class name of data."); + // return; + // } + // this.SetDataClassName(dataclassname); + // + // if (!CSS_GET_NEXT_ARGUMENT(css, 0, &this.DataSetType)) + // { + // vtkErrorMacro("Error parsing data set type."); + // return; + // } + // if (!CSS_GET_NEXT_ARGUMENT(css, 0, &this.NumberOfDataSets)) + // { + // vtkErrorMacro("Error parsing number of datasets."); + // return; + // } + // if (!CSS_GET_NEXT_ARGUMENT(css, 0, &this.NumberOfPoints)) + // { + // vtkErrorMacro("Error parsing number of points."); + // return; + // } + // if (!CSS_GET_NEXT_ARGUMENT(css, 0, &this.NumberOfCells)) + // { + // vtkErrorMacro("Error parsing number of cells."); + // return; + // } + // if (!CSS_GET_NEXT_ARGUMENT(css, 0, &this.NumberOfRows)) + // { + // vtkErrorMacro("Error parsing number of cells."); + // return; + // } + // if(!CSS_GET_NEXT_ARGUMENT(css, 0, &this.MemorySize)) + // { + // vtkErrorMacro("Error parsing memory size."); + // return; + // } + // if(!CSS_GET_NEXT_ARGUMENT(css, 0, &this.PolygonCount)) + // { + // vtkErrorMacro("Error parsing memory size."); + // return; + // } + // if(!CSS_GET_NEXT_ARGUMENT(css, 0, &this.Time)) + // { + // vtkErrorMacro("Error parsing Time."); + // return; + // } + // if(!CSS_GET_NEXT_ARGUMENT(css, 0, &this.HasTime)) + // { + // vtkErrorMacro("Error parsing has-time."); + // return; + // } + // const char* timeLabel = 0; + // if (!CSS_GET_NEXT_ARGUMENT(css, 0, &timeLabel)) + // { + // vtkErrorMacro("Error parsing time label."); + // return; + // } + // this.SetTimeLabel(timeLabel); + // if(!CSS_GET_NEXT_ARGUMENT2(css, 0, this.Bounds, 6)) + // { + // vtkErrorMacro("Error parsing bounds."); + // return; + // } + // if(!CSS_GET_NEXT_ARGUMENT2(css, 0, this.Extent, 6)) + // { + // vtkErrorMacro("Error parsing extent."); + // return; + // } + // + // vtkTypeUInt32 length; + // std::vector data; + // vtkClientServerStream dcss; + // + // // Point array information. + // if(!css.GetArgumentLength(0, CSS_GET_CUR_INDEX(), &length)) + // { + // vtkErrorMacro("Error parsing length of point data information."); + // return; + // } + // data.resize(length); + // if(!css.GetArgument(0, CSS_GET_CUR_INDEX(), &*data.begin(), length)) + // { + // vtkErrorMacro("Error parsing point data information."); + // return; + // } + // dcss.SetData(&*data.begin(), length); + // this.PointArrayInformation.CopyFromStream(&dcss); + // CSS_GET_CUR_INDEX()++; + // + // // Point data array information. + // if(!css.GetArgumentLength(0, CSS_GET_CUR_INDEX(), &length)) + // { + // vtkErrorMacro("Error parsing length of point data information."); + // return; + // } + // data.resize(length); + // if(!css.GetArgument(0, CSS_GET_CUR_INDEX(), &*data.begin(), length)) + // { + // vtkErrorMacro("Error parsing point data information."); + // return; + // } + // dcss.SetData(&*data.begin(), length); + // this.PointDataInformation.CopyFromStream(&dcss); + // CSS_GET_CUR_INDEX()++; + // + // // Cell data array information. + // if(!css.GetArgumentLength(0, CSS_GET_CUR_INDEX(), &length)) + // { + // vtkErrorMacro("Error parsing length of cell data information."); + // return; + // } + // data.resize(length); + // if(!css.GetArgument(0, CSS_GET_CUR_INDEX(), &*data.begin(), length)) + // { + // vtkErrorMacro("Error parsing cell data information."); + // return; + // } + // dcss.SetData(&*data.begin(), length); + // this.CellDataInformation.CopyFromStream(&dcss); + // CSS_GET_CUR_INDEX()++; + // + // // Vertex data array information. + // if(!css.GetArgumentLength(0, CSS_GET_CUR_INDEX(), &length)) + // { + // vtkErrorMacro("Error parsing length of cell data information."); + // return; + // } + // data.resize(length); + // if(!css.GetArgument(0, CSS_GET_CUR_INDEX(), &*data.begin(), length)) + // { + // vtkErrorMacro("Error parsing cell data information."); + // return; + // } + // dcss.SetData(&*data.begin(), length); + // this.VertexDataInformation.CopyFromStream(&dcss); + // CSS_GET_CUR_INDEX()++; + // + // // Edge data array information. + // if(!css.GetArgumentLength(0, CSS_GET_CUR_INDEX(), &length)) + // { + // vtkErrorMacro("Error parsing length of cell data information."); + // return; + // } + // data.resize(length); + // if(!css.GetArgument(0, CSS_GET_CUR_INDEX(), &*data.begin(), length)) + // { + // vtkErrorMacro("Error parsing cell data information."); + // return; + // } + // dcss.SetData(&*data.begin(), length); + // this.EdgeDataInformation.CopyFromStream(&dcss); + // CSS_GET_CUR_INDEX()++; + // + // // Row data array information. + // if(!css.GetArgumentLength(0, CSS_GET_CUR_INDEX(), &length)) + // { + // vtkErrorMacro("Error parsing length of cell data information."); + // return; + // } + // data.resize(length); + // if(!css.GetArgument(0, CSS_GET_CUR_INDEX(), &*data.begin(), length)) + // { + // vtkErrorMacro("Error parsing cell data information."); + // return; + // } + // dcss.SetData(&*data.begin(), length); + // this.RowDataInformation.CopyFromStream(&dcss); + // CSS_GET_CUR_INDEX()++; + // + // const char* compositedataclassname = 0; + // if(!CSS_GET_NEXT_ARGUMENT(css, 0, &compositedataclassname)) + // { + // vtkErrorMacro("Error parsing class name of data."); + // return; + // } + // this.SetCompositeDataClassName(compositedataclassname); + // + // if(!CSS_GET_NEXT_ARGUMENT(css, 0, &this.CompositeDataSetType)) + // { + // vtkErrorMacro("Error parsing data set type."); + // return; + // } + // + // // Composite data information. + // if(!css.GetArgumentLength(0, CSS_GET_CUR_INDEX(), &length)) + // { + // vtkErrorMacro("Error parsing length of cell data information."); + // return; + // } + // data.resize(length); + // if(!css.GetArgument(0, CSS_GET_CUR_INDEX(), &*data.begin(), length)) + // { + // vtkErrorMacro("Error parsing cell data information."); + // return; + // } + // dcss.SetData(&*data.begin(), length); + // if (dcss.GetNumberOfMessages() > 0) + // { + // this.CompositeDataInformation.CopyFromStream(&dcss); + // } + // else + // { + // this.CompositeDataInformation.Initialize(); + // } + // CSS_GET_CUR_INDEX()++; + // + // // Field data array information. + // if(!css.GetArgumentLength(0, CSS_GET_CUR_INDEX(), &length)) + // { + // vtkErrorMacro("Error parsing length of field data information."); + // return; + // } + // + // data.resize(length); + // if(!css.GetArgument(0, CSS_GET_CUR_INDEX(), &*data.begin(), length)) + // { + // vtkErrorMacro("Error parsing field data information."); + // return; + // } + // dcss.SetData(&*data.begin(), length); + // this.FieldDataInformation.CopyFromStream(&dcss); + // CSS_GET_CUR_INDEX()++; + // + // if(!CSS_GET_NEXT_ARGUMENT2(css, 0, this.TimeSpan, 2)) + // { + // vtkErrorMacro("Error parsing timespan."); + // return; + // } + // + // CSS_ARGUMENT_END(); + // } + + // void SetSortArrays(boolean sort) { + // this.PointDataInformation.SetSortArrays(sort); + // this.CellDataInformation.SetSortArrays(sort); + // this.FieldDataInformation.SetSortArrays(sort); + // } + + // vtkPVDataSetAttributesInformation GetAttributeInformation(int + // fieldAssociation) + // { + // switch (fieldAssociation) + // { + // case vtkDataObject::FIELD_ASSOCIATION_POINTS: + // return this.PointDataInformation; + // + // case vtkDataObject::FIELD_ASSOCIATION_CELLS: + // return this.CellDataInformation; + // + // case vtkDataObject::FIELD_ASSOCIATION_VERTICES: + // return this.VertexDataInformation; + // + // case vtkDataObject::FIELD_ASSOCIATION_EDGES: + // return this.EdgeDataInformation; + // + // case vtkDataObject::FIELD_ASSOCIATION_ROWS: + // return this.RowDataInformation; + // + // case vtkDataObject::FIELD_ASSOCIATION_NONE: + // return this.FieldDataInformation; + // } + // + // return 0; + // } + + // DO NOT USE THIS METHOD, THE ITERATOR HAS MEMORY LEAK PROBLEMS + // public void AddFromCompositeDataSet(vtkCompositeDataSet data) { + // vtkCompositeDataIterator iter = data.NewIterator(); + // int counter = 0; + // for (iter.InitTraversal(); iter.IsDoneWithTraversal() == 0; + // iter.GoToNextItem()) { + // System.out.println("VTKDataInformation.AddFromCompositeDataSet() " + + // counter++); + // // vtkDataObject dobj = iter.GetCurrentDataObject(); + // // if (dobj != null) { + // // VTKDataInformation dinf = new VTKDataInformation(); + // // dinf.CopyFromObject(dobj); + // // dinf.DataClassName = dobj.GetClassName(); + // // dinf.DataSetType = dobj.GetDataObjectType(); + // // this.AddInformation(dinf, true); + // // } + // // dobj.Delete(); + // } + // iter.Delete(); + // } + // void CopyFromSelection(vtkSelection data) { + // this.SetDataClassName(data.GetClassName()); + // this.DataSetType = data.GetDataObjectType(); + // this.NumberOfDataSets = 1; + // + // this.Bounds[0] = this.Bounds[2] = this.Bounds[4] = VTK_DOUBLE_MAX; + // this.Bounds[1] = this.Bounds[3] = this.Bounds[5] = -VTK_DOUBLE_MAX; + // + // this.MemorySize = data.GetActualMemorySize(); + // this.NumberOfCells = 0; + // this.NumberOfPoints = 0; + // + // // Copy Point Data information + // this.PointDataInformation.CopyFromFieldData(data.GetFieldData()); + // } + + // void CopyFromGraph(vtkGraph data) { + // this.SetDataClassName(data.GetClassName()); + // this.DataSetType = data.GetDataObjectType(); + // this.NumberOfDataSets = 1; + // + // this.Bounds[0] = this.Bounds[2] = this.Bounds[4] = VTK_DOUBLE_MAX; + // this.Bounds[1] = this.Bounds[3] = this.Bounds[5] = -VTK_DOUBLE_MAX; + // + // if (data.GetPoints()) + // data.GetPoints().GetBounds(this.Bounds); + // + // this.MemorySize = data.GetActualMemorySize(); + // this.NumberOfCells = data.GetNumberOfEdges(); + // this.NumberOfPoints = data.GetNumberOfVertices(); + // this.NumberOfRows = 0; + // + // this.VertexDataInformation.CopyFromFieldData(data.GetVertexData()); + // this.EdgeDataInformation.CopyFromFieldData(data.GetEdgeData()); + // } + + // void CopyFromTable(vtkTable data) { + // this.SetDataClassName(data.GetClassName()); + // this.DataSetType = data.GetDataObjectType(); + // this.NumberOfDataSets = 1; + // + // this.Bounds[0] = this.Bounds[2] = this.Bounds[4] = VTK_DOUBLE_MAX; + // this.Bounds[1] = this.Bounds[3] = this.Bounds[5] = -VTK_DOUBLE_MAX; + // + // this.MemorySize = data.GetActualMemorySize(); + // this.NumberOfCells = data.GetNumberOfRows() * data.GetNumberOfColumns(); + // this.NumberOfPoints = 0; + // this.NumberOfRows = data.GetNumberOfRows(); + // + // this.RowDataInformation.CopyFromFieldData(data.GetRowData()); + // } + +} diff --git a/src/eu/engys/vtk/info/VTKDataSetAttributesInformation.java b/src/eu/engys/vtk/info/VTKDataSetAttributesInformation.java new file mode 100644 index 0000000..ca0d46f --- /dev/null +++ b/src/eu/engys/vtk/info/VTKDataSetAttributesInformation.java @@ -0,0 +1,371 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.info; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import vtk.vtkAbstractArray; +import vtk.vtkDataSetAttributes; +import vtk.vtkFieldData; +import vtk.vtkGenericAttribute; +import vtk.vtkGenericAttributeCollection; + +public class VTKDataSetAttributesInformation { + + private static final int NUM_ATTRIBUTES = 8; + private List ArrayInformation; + private boolean SortArrays; + private int[] AttributeIndices = new int[NUM_ATTRIBUTES]; + + // ---------------------------------------------------------------------------- + public VTKDataSetAttributesInformation() { + this.ArrayInformation = new ArrayList<>(); + for (int idx = 0; idx < NUM_ATTRIBUTES; ++idx) { + this.AttributeIndices[idx] = -1; + } + this.SortArrays = true; + } + + // ---------------------------------------------------------------------------- + void PrintSelf(PrintStream os, String indent) { + + int num = this.GetNumberOfArrays(); + os.println(indent+"ArrayInformation, number of arrays: " + num); + for (int idx = 0; idx < num; ++idx) { + this.ArrayInformation.get(idx).PrintSelf(os, indent+indent); + } + os.println(indent+"SortArrays: " + this.SortArrays); + } + + // ---------------------------------------------------------------------------- + void Initialize() { + this.ArrayInformation.clear(); + for (int idx = 0; idx < NUM_ATTRIBUTES; ++idx) { + this.AttributeIndices[idx] = -1; + } + } + + // ---------------------------------------------------------------------------- + void DeepCopy(VTKDataSetAttributesInformation dataInfo) { + + // Copy array information. + this.ArrayInformation.clear(); + int num = dataInfo.GetNumberOfArrays(); + for (int idx = 0; idx < num; ++idx) { + VTKArrayInformation arrayInfo = dataInfo.ArrayInformation.get(idx); + VTKArrayInformation newArrayInfo = new VTKArrayInformation(); + newArrayInfo.DeepCopy(arrayInfo); + this.ArrayInformation.add(newArrayInfo); + } + // Now the default attributes. + for (int idx = 0; idx < NUM_ATTRIBUTES; ++idx) { + this.AttributeIndices[idx] = dataInfo.AttributeIndices[idx]; + } + } + + // ---------------------------------------------------------------------------- + void CopyFromFieldData(vtkFieldData da) { + // Clear array information. + this.ArrayInformation.clear(); + for (int idx = 0; idx < NUM_ATTRIBUTES; ++idx) { + this.AttributeIndices[idx] = -1; + } + + // Copy Field Data + int num = da.GetNumberOfArrays(); + for (int idx = 0; idx < num; ++idx) { + vtkAbstractArray array = da.GetAbstractArray(idx); + if (array.GetName() != null) { + VTKArrayInformation info = new VTKArrayInformation(); + info.CopyFromObject(array); + this.ArrayInformation.add(info); + } + } + } + + class SortedArray implements Comparable { + + public int arrayIndx; + public String arrayName; + + @Override + public int compareTo(SortedArray o) { + return arrayName.compareTo(o.arrayName); + } + + } + + // ---------------------------------------------------------------------------- + void CopyFromDataSetAttributes(vtkDataSetAttributes da) { + // Clear array information. + this.ArrayInformation.clear(); + for (int idx = 0; idx < NUM_ATTRIBUTES; ++idx) { + this.AttributeIndices[idx] = -1; + } + + // Copy Point Data + int num = da.GetNumberOfArrays(); + + // sort the arrays alphabetically + List sortArrays = new ArrayList<>(); + sortArrays.clear(); + + if (num > 0) { + for (int i = 0; i < num; i++) { + SortedArray sa = new SortedArray(); + sa.arrayIndx = i; + sa.arrayName = da.GetArrayName(i) != null ? da.GetArrayName(i) : ""; + + sortArrays.add(i, sa); + } + + if (this.SortArrays) { + Collections.sort(sortArrays); + } + } + + int infoArrayIndex = 0; + for (SortedArray sa : sortArrays) { + int arrayIndx = sa.arrayIndx; + vtkAbstractArray array = da.GetAbstractArray(arrayIndx); + + if (array.GetName() != null && !array.GetName().equals("vtkGhostLevels") && !array.GetName().equals("vtkOriginalCellIds") && !array.GetName().equals("vtkOriginalPointIds")) { + int attribute = da.IsArrayAnAttribute(arrayIndx); + VTKArrayInformation info = new VTKArrayInformation(); + info.CopyFromObject(array); + this.ArrayInformation.add(info); + // Record default attributes. + if (attribute > -1) { + this.AttributeIndices[attribute] = infoArrayIndex; + } + ++infoArrayIndex; + } + } + + sortArrays.clear(); + } + + private static final int vtkPointCentered = 0; + private static final int vtkCellCentered = 1; + private static final int vtkBoundaryCentered = 2; + + // ---------------------------------------------------------------------------- + void CopyFromGenericAttributesOnPoints(vtkGenericAttributeCollection da) { + + // Clear array information. + this.ArrayInformation.clear(); + for (int idx = 0; idx < 5; ++idx) { + this.AttributeIndices[idx] = -1; + } + + // Copy Point Data + int num = da.GetNumberOfAttributes(); + for (int idx = 0; idx < num; ++idx) { + vtkGenericAttribute array = da.GetAttribute(idx); + if (array.GetCentering() == vtkPointCentered) { + if (array.GetName() != null && (!array.GetName().equals("vtkGhostLevels"))) { + VTKGenericAttributeInformation info = new VTKGenericAttributeInformation(); + info.CopyFromObject(array); + this.ArrayInformation.add(info); + } + } + } + } + + // ---------------------------------------------------------------------------- + void CopyFromGenericAttributesOnCells(vtkGenericAttributeCollection da) { + + // Clear array information. + this.ArrayInformation.clear(); + for (int idx = 0; idx < 5; ++idx) { + this.AttributeIndices[idx] = -1; + } + + // Copy Cell Data + int num = da.GetNumberOfAttributes(); + for (int idx = 0; idx < num; ++idx) { + vtkGenericAttribute array = da.GetAttribute(idx); + if (array.GetCentering() == vtkCellCentered) { + if (array.GetName() != null && (!array.GetName().equals("vtkGhostLevels"))) { + VTKGenericAttributeInformation info = new VTKGenericAttributeInformation(); + info.CopyFromObject(array); + this.ArrayInformation.add(info); + } + } + } + } + + // ---------------------------------------------------------------------------- + void AddInformation(VTKDataSetAttributesInformation info) { + int num1 = this.GetNumberOfArrays(); + int num2 = info.GetNumberOfArrays(); + int[] newAttributeIndices = new int[NUM_ATTRIBUTES]; + + for (int idx1 = 0; idx1 < NUM_ATTRIBUTES; idx1++) { + newAttributeIndices[idx1] = -1; + } + + // First add ranges from all common arrays + for (int idx1 = 0; idx1 < num1; idx1++) { + boolean found = false; + VTKArrayInformation ai1 = this.ArrayInformation.get(idx1); + for (int idx2 = 0; idx2 < num2; idx2++) { + VTKArrayInformation ai2 = info.ArrayInformation.get(idx2); + if (ai1.Compare(ai2)) { + // Take union of range. + ai1.AddRanges(ai2); + found = true; + // Record default attributes. + int attribute1 = this.IsArrayAnAttribute(idx1); + int attribute2 = info.IsArrayAnAttribute(idx2); + if (attribute1 > -1 && attribute1 == attribute2) { + newAttributeIndices[attribute1] = idx1; + } + break; + } + } + if (!found) { + ai1.IsPartial = true; + } + } + + for (int idx1 = 0; idx1 < NUM_ATTRIBUTES; idx1++) { + this.AttributeIndices[idx1] = newAttributeIndices[idx1]; + } + + // Now add arrays that don't exist + for (int idx2 = 0; idx2 < num2; idx2++) { + VTKArrayInformation ai2 = info.ArrayInformation.get(idx2); + boolean found = false; + for (int idx1 = 0; idx1 < this.GetNumberOfArrays(); idx1++) { + VTKArrayInformation ai1 = this.ArrayInformation.get(idx1); + if (ai1.Compare(ai2)) { + found = true; + break; + } + } + if (!found) { + ai2.IsPartial = true; + this.ArrayInformation.add(ai2); + int attribute = info.IsArrayAnAttribute(idx2); + if (attribute > -1 && this.AttributeIndices[attribute] == -1) { + this.AttributeIndices[attribute] = idx2; + } + } + } + } + + // ---------------------------------------------------------------------------- + // void AddInformation(vtkPVInformation info) + // { + // vtkPVDataSetAttributesInformation* p = + // vtkPVDataSetAttributesInformation::SafeDownCast(info); + // if(p) + // { + // this.AddInformation(p); + // } + // else + // { + // vtkErrorMacro("AddInformation called with object of type " + // << (info? info.GetClassName():"")); + // } + // } + + // ---------------------------------------------------------------------------- + void AddInformation(vtkDataSetAttributes da) { + VTKDataSetAttributesInformation info = new VTKDataSetAttributesInformation(); + info.CopyFromDataSetAttributes(da); + this.AddInformation(info); + } + + // ---------------------------------------------------------------------------- + int IsArrayAnAttribute(int arrayIndex) { + int i; + + for (i = 0; i < NUM_ATTRIBUTES; ++i) { + if (this.AttributeIndices[i] == arrayIndex) { + return i; + } + } + return -1; + } + + // ---------------------------------------------------------------------------- + VTKArrayInformation GetAttributeInformation(int attributeType) { + int arrayIdx = this.AttributeIndices[attributeType]; + + if (arrayIdx < 0) { + return null; + } + return this.ArrayInformation.get(arrayIdx); + } + + // ---------------------------------------------------------------------------- + int GetNumberOfArrays() { + return this.ArrayInformation.size(); + } + + // ---------------------------------------------------------------------------- + // int GetMaximumNumberOfTuples() + // { + // VTKArrayInformation info; + // int maxNumVals = 0; + // + // this.ArrayInformation.InitTraversal(); + // while ( (info = static_cast(this.ArrayInformation.GetNextItemAsObject())) ) + // { + // maxNumVals = info.GetNumberOfTuples() > maxNumVals ? info.GetNumberOfTuples() : maxNumVals; + // } + // + // return maxNumVals; + // } + + // ---------------------------------------------------------------------------- + // vtkPVArrayInformation GetArrayInformation(String name) + // { + // vtkPVArrayInformation info; + // + // if (name == NULL) + // { + // return NULL; + // } + // + // this.ArrayInformation.InitTraversal(); + // while ( (info = static_cast(this.ArrayInformation.GetNextItemAsObject())) ) + // { + // if (strcmp(info.GetName(), name) == 0) + // { + // return info; + // } + // } + // return NULL; + // } + +} diff --git a/src/eu/engys/vtk/info/VTKGenericAttributeInformation.java b/src/eu/engys/vtk/info/VTKGenericAttributeInformation.java new file mode 100644 index 0000000..e10c473 --- /dev/null +++ b/src/eu/engys/vtk/info/VTKGenericAttributeInformation.java @@ -0,0 +1,54 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.info; + +import vtk.vtkGenericAttribute; + +public class VTKGenericAttributeInformation extends VTKArrayInformation { + + //---------------------------------------------------------------------------- + void CopyFromObject(vtkGenericAttribute array) + { + + this.Name = array.GetName(); + this.DataType = array.GetComponentType(); + this.NumberOfComponents = array.GetNumberOfComponents(); + + if (this.NumberOfComponents > 1) { + this.Ranges = new double[this.NumberOfComponents+1][2]; + // First store range of vector magnitude. + array.GetRange(-1,this.Ranges[0]); + for (int idx = 0; idx < this.NumberOfComponents; idx++) { + array.GetRange(idx, this.Ranges[idx + 1]); + } + } else { + this.Ranges = new double[1][2]; + array.GetRange(0,this.Ranges[0]); + } + } + +} diff --git a/src/eu/engys/vtk/widgets/AxesWidget.java b/src/eu/engys/vtk/widgets/AxesWidget.java new file mode 100644 index 0000000..30ffc35 --- /dev/null +++ b/src/eu/engys/vtk/widgets/AxesWidget.java @@ -0,0 +1,67 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import vtk.vtkAxesActor; +import vtk.vtkCaptionActor2D; +import vtk.vtkOrientationMarkerWidget; +import eu.engys.gui.view3D.RenderPanel; + +public class AxesWidget { + + private vtkAxesActor axes; + private vtkOrientationMarkerWidget widget; + + public AxesWidget(RenderPanel renderPanel) { + axes = new vtkAxesActor(); + + setAxisProperty(axes.GetXAxisCaptionActor2D()); + setAxisProperty(axes.GetYAxisCaptionActor2D()); + setAxisProperty(axes.GetZAxisCaptionActor2D()); + + widget = new vtkOrientationMarkerWidget(); + renderPanel.getInteractor().addObserver(widget); + widget.SetOutlineColor(0.9300, 0.5700, 0.1300); + widget.SetOrientationMarker(axes); + widget.SetViewport(0, 0, 0.25, 0.25); + widget.EnabledOn(); + widget.InteractiveOff(); + + } + + private void setAxisProperty(vtkCaptionActor2D axis) { + axis.GetTextActor().GetTextProperty().ShadowOff(); + axis.GetTextActor().GetTextProperty().SetFontFamilyToArial(); + axis.GetTextActor().GetTextProperty().ItalicOff(); + axis.GetTextActor().GetTextProperty().BoldOff(); + axis.GetTextActor().GetTextProperty().SetColor(0, 0, 0); + } + + public void clear() { + } + +} diff --git a/src/eu/engys/vtk/widgets/AxisWidget.java b/src/eu/engys/vtk/widgets/AxisWidget.java new file mode 100644 index 0000000..bb29c71 --- /dev/null +++ b/src/eu/engys/vtk/widgets/AxisWidget.java @@ -0,0 +1,217 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.vecmath.Vector3d; + +import vtk.vtkArrowSource; +import vtk.vtkHandleWidget; +import vtk.vtkMatrix4x4; +import vtk.vtkPolygonalHandleRepresentation3D; +import vtk.vtkTransform; +import vtk.vtkTransformPolyDataFilter; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.ui.textfields.DoubleField; + +public class AxisWidget { + + private final class PointFieldListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + changePosition(); + renderPanel.renderLater(); + } + } + } + + private RenderPanel renderPanel; + private PropertyChangeListener listener; + private DoubleField[] currentCenter = null; + private DoubleField[] currentNormal = null; + private vtkHandleWidget widget; + private vtkPolygonalHandleRepresentation3D representation; + private vtkArrowSource arrowSource; + + public AxisWidget(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + + arrowSource = new vtkArrowSource(); + arrowSource.SetShaftResolution(24); // default = 6 + arrowSource.SetTipResolution(36); // default = 6 + arrowSource.Update(); + + vtkTransform transform = new vtkTransform(); + transform.RotateZ(-90); + transform.Update(); + + vtkTransformPolyDataFilter transformPD = new vtkTransformPolyDataFilter(); + transformPD.SetTransform(transform); + transformPD.SetInputData(arrowSource.GetOutput()); + transformPD.Update(); + + representation = new vtkPolygonalHandleRepresentation3D(); + representation.SetHandle(transformPD.GetOutput()); + representation.GetProperty().SetColor(0, 1, 1); + representation.DragableOff(); + representation.PickableOff(); + representation.ActiveRepresentationOff();// MuDeMe! + + widget = new vtkHandleWidget(); + renderPanel.getInteractor().addObserver(widget); + widget.SetRepresentation(representation); + widget.ManagesCursorOff(); + widget.ProcessEventsOff();// MuDeMe! + + listener = new PointFieldListener(); + } + + public void clear() { + removeListener(); + renderPanel.lock(); + widget.EnabledOff(); + widget.Delete(); + currentCenter = null; + currentNormal = null; + renderPanel.unlock(); + renderPanel.renderLater(); + } + + public void showAxis(DoubleField[] center, DoubleField[] normal, EventActionType action) { + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + widget.EnabledOff(); + removeListener(); + currentCenter = null; + currentNormal = null; + } else if (action.equals(EventActionType.SHOW)) { + removeListener(); + currentCenter = center; + currentNormal = normal; + changePosition(); + widget.EnabledOn(); + addListener(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void changePosition() { + if (isValid()) { + double[] p1 = new double[] { currentCenter[0].getDoubleValue(), currentCenter[1].getDoubleValue(), currentCenter[2].getDoubleValue() }; + double[] p2 = new double[] { currentCenter[0].getDoubleValue() + currentNormal[0].getDoubleValue(), currentCenter[1].getDoubleValue() + currentNormal[1].getDoubleValue(), currentCenter[2].getDoubleValue() + currentNormal[2].getDoubleValue() }; + transformArrow(p1, p2); + } + } + + private boolean isValid() { + return currentCenter != null && currentCenter[0].getValue() != null && currentCenter[1].getValue() != null && currentCenter[2].getValue() != null; + } + + private void transformArrow(double[] startPoint, double[] endPoint) { + // Compute a basis + Vector3d normalizedX = new Vector3d(); + Vector3d normalizedY = new Vector3d(); + Vector3d normalizedZ = new Vector3d(); + + // The X axis is a vector from start to end + normalizedX.setX(endPoint[0] - startPoint[0]); + normalizedX.setY(endPoint[1] - startPoint[1]); + normalizedX.setZ(endPoint[2] - startPoint[2]); + + double length = normalizedX.length(); + normalizedX.normalize(); + + // The Z axis is an arbitrary vector cross X + Vector3d arbitrary = new Vector3d(1, 1, 1); + + normalizedZ.cross(normalizedX, arbitrary); + normalizedZ.normalize(); + + // The Y axis is Z cross X + normalizedY.cross(normalizedZ, normalizedX); + + vtkMatrix4x4 matrix = new vtkMatrix4x4(); + + // Create the direction cosine matrix + matrix.Identity(); + matrix.SetElement(0, 0, normalizedX.getX()); + matrix.SetElement(0, 1, normalizedY.getX()); + matrix.SetElement(0, 2, normalizedZ.getX()); + matrix.SetElement(1, 0, normalizedX.getY()); + matrix.SetElement(1, 1, normalizedY.getY()); + matrix.SetElement(1, 2, normalizedZ.getY()); + matrix.SetElement(2, 0, normalizedX.getZ()); + matrix.SetElement(2, 1, normalizedY.getZ()); + matrix.SetElement(2, 2, normalizedZ.getZ()); + + // Apply the transforms + vtkTransform transform = new vtkTransform(); + transform.Translate(startPoint); + transform.Concatenate(matrix); + transform.Scale(length, length, length); + transform.Update(); + + // Transform the polydata + vtkTransformPolyDataFilter transformPD = new vtkTransformPolyDataFilter(); + transformPD.SetTransform(transform); + transformPD.SetInputData(arrowSource.GetOutput()); + transformPD.Update(); + + representation.SetHandle(transformPD.GetOutput()); + } + + private void addListener() { + if (isValid()) { + currentCenter[0].addPropertyChangeListener(listener); + currentCenter[1].addPropertyChangeListener(listener); + currentCenter[2].addPropertyChangeListener(listener); + } + if (currentNormal != null) { + currentNormal[0].addPropertyChangeListener(listener); + currentNormal[1].addPropertyChangeListener(listener); + currentNormal[2].addPropertyChangeListener(listener); + } + } + + private void removeListener() { + if (isValid()) { + currentCenter[0].removePropertyChangeListener(listener); + currentCenter[1].removePropertyChangeListener(listener); + currentCenter[2].removePropertyChangeListener(listener); + } + if (currentNormal != null) { + currentNormal[0].removePropertyChangeListener(listener); + currentNormal[1].removePropertyChangeListener(listener); + currentNormal[2].removePropertyChangeListener(listener); + } + } +} diff --git a/src/eu/engys/vtk/widgets/AxisWidgetManager.java b/src/eu/engys/vtk/widgets/AxisWidgetManager.java new file mode 100644 index 0000000..78bf95d --- /dev/null +++ b/src/eu/engys/vtk/widgets/AxisWidgetManager.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import java.util.HashMap; +import java.util.Map; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.vtk.VTKRenderPanel; + +public class AxisWidgetManager { + + private String key = "pippo"; + + private Map widgetMap = new HashMap<>(); + private VTKRenderPanel vtkRendererPanel; + + public AxisWidgetManager(VTKRenderPanel vtkRendererPanel) { + this.vtkRendererPanel = vtkRendererPanel; + } + + public void clear() { + for (AxisWidget w : widgetMap.values()) { + w.clear(); + } + widgetMap.clear(); + } + + public void showPoint(DoubleField[] center, DoubleField[] normal, EventActionType action) { + if (action.equals(EventActionType.REMOVE)) { + if (widgetMap.containsKey(key)) { + AxisWidget w = widgetMap.remove(key); + w.clear(); + } + } else { + if (!widgetMap.containsKey(key)) { + AxisWidget widget = new AxisWidget(vtkRendererPanel); + widgetMap.put(key, widget); + } + AxisWidget axisWidget = widgetMap.get(key); + axisWidget.showAxis(center, normal, action); + } + } + +} diff --git a/src/eu/engys/vtk/widgets/CORWidget.java b/src/eu/engys/vtk/widgets/CORWidget.java new file mode 100644 index 0000000..dbf88a2 --- /dev/null +++ b/src/eu/engys/vtk/widgets/CORWidget.java @@ -0,0 +1,125 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import vtk.vtkActor; +import vtk.vtkAssembly; +import vtk.vtkLineSource; +import vtk.vtkPolyDataMapper; +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.vtk.VTKRenderPanel; + +public class CORWidget { + + private VTKRenderPanel vtkRendererPanel; + private vtkActor lineX; + private vtkActor lineY; + private vtkActor lineZ; + private vtkAssembly cor; + + public CORWidget(VTKRenderPanel vtkRendererPanel) { + this.vtkRendererPanel = vtkRendererPanel; + cor = new vtkAssembly(); + + lineX = getLine(new double[] {-1, 0, 0}, new double[] {1,0,0}, 1, 1,0,0); + lineY = getLine(new double[] { 0,-1, 0}, new double[] {0,1,0}, 1, 0,1,0); + lineZ = getLine(new double[] { 0, 0,-1}, new double[] {0,0,1}, 1, 0,0,1); + + cor.AddPart(lineX); + cor.AddPart(lineY); + cor.AddPart(lineZ); + cor.UseBoundsOff(); + } + + private vtkActor getLine(double[] p1, double[] p2, float gr, int r, int g, int b) { + + vtkLineSource line = new vtkLineSource(); + + line.SetPoint1(p1[0], p1[1], p1[2]); + line.SetPoint2(p2[0], p2[1], p2[2]); + + + vtkPolyDataMapper mapper = new vtkPolyDataMapper(); + mapper.SetInputData(line.GetOutput()); + + vtkActor axes = new vtkActor(); + + axes.SetMapper(mapper); + axes.GetProperty().SetColor(r, g, b); + axes.GetProperty().SetLineWidth(gr); + + line.Delete(); + mapper.Delete(); + + return axes; + } + + private void updateLine(vtkActor line, double[] start, double[] end) { + //System.out.println("CORWidget.updateLine() start: "+Arrays.toString(start)+", end: "+Arrays.toString(end)); + vtkLineSource source = new vtkLineSource(); + source.SetPoint1(start); + source.SetPoint2(end); + source.Update(); + + vtkPolyDataMapper mapper = (vtkPolyDataMapper) line.GetMapper(); + mapper.SetInputData(source.GetOutput()); + mapper.Update(); + } + + public void update(BoundingBox bb) { + double[] center = vtkRendererPanel.GetRenderer().GetActiveCamera().GetFocalPoint(); + +// System.out.println("CORWidget.update() W: " + bb.getWidth() + ", H: "+bb.getHeight()); +// System.out.println("CORWidget.update() CENTER: " + Arrays.toString(center)); + double deltaX = (bb.getXmax() - bb.getXmin()) / 4; + double deltaY = (bb.getYmax() - bb.getYmin()) / 4; + double deltaZ = (bb.getZmax() - bb.getZmin()) / 4; + + double[] start = new double[] { center[0]-deltaX, center[1], center[2] }; + double[] end = new double[] { center[0]+deltaX, center[1], center[2] }; + updateLine(lineX, start, end); + + start = new double[] { center[0], center[1]-deltaY, center[2] }; + end = new double[] { center[0], center[1]+deltaY, center[2] }; + updateLine(lineY, start, end); + + start = new double[] { center[0], center[1], center[2]-deltaZ }; + end = new double[] { center[0], center[1], center[2]+deltaZ }; + updateLine(lineZ, start, end); + + cor.Modified(); + } + + public void clear() { + + } + + public void on() { +// vtkRendererPanel.addActor(cor); + } + +} diff --git a/src/eu/engys/vtk/widgets/ExtractSelectionWidget.java b/src/eu/engys/vtk/widgets/ExtractSelectionWidget.java new file mode 100644 index 0000000..594595f --- /dev/null +++ b/src/eu/engys/vtk/widgets/ExtractSelectionWidget.java @@ -0,0 +1,223 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkHandleWidget; +import vtk.vtkPolyData; +import vtk.vtkPolygonalHandleRepresentation3D; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.view3D.CellPicker; +import eu.engys.gui.view3D.PickInfo; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.gui.view3D.Selection; +import eu.engys.gui.view3D.Selection.SelectionType; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.vtk.actions.ExtractSelection; + +public class ExtractSelectionWidget implements CellPicker { + + private static final Logger logger = LoggerFactory.getLogger(ExtractSelectionWidget.class); + + private static final double[] COLOR = new double[] { 0.8, 0.0, 0.0 }; + + private RenderPanel renderPanel; + private vtkHandleWidget widget; + + private vtkPolygonalHandleRepresentation3D representation; + + private Selection currentSelection; + private SelectionListener listener; + + public ExtractSelectionWidget(RenderPanel renderPanel, ProgressMonitor monitor) { + this.renderPanel = renderPanel; + this.listener = new SelectionListener(); + } + + public void activateSelection(Selection selection, EventActionType action) { + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + hide(); + } else if (action.equals(EventActionType.SHOW)) { + this.currentSelection = selection; + show(); + } else if (action.equals(EventActionType.REMOVE)) { + clearSelection(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void hide() { + if (widget != null) { + renderPanel.lowRenderingOn(); + widget.Off(); + removeListener(); + currentSelection = null; + representation.SetHandle(new vtkPolyData()); + selectionBoxOff(); + renderPanel.getPickManager().pickForActors(); + renderPanel.getPickManager().unregisterPickerForCells(this); + } + } + + private void show() { + renderPanel.lowRenderingOff(); + renderPanel.getPickManager().pickForCells(); + renderPanel.getPickManager().registerPickerForCells(this); + if (widget == null) { + createWidget(); + } + + if (currentSelection.getType() == SelectionType.AREA) { + selectionBoxOn(); + } else { + selectionBoxOff(); + } + + widget.On(); + addListener(); + } + + private void createWidget() { + representation = new vtkPolygonalHandleRepresentation3D(); + representation.GetProperty().SetColor(COLOR); + // representation.GetProperty().LightingOff(); + + representation.GetSelectedProperty().SetColor(COLOR); + representation.DragableOff(); + representation.PickableOff(); + representation.ActiveRepresentationOff();// MuDeMe! + + widget = new vtkHandleWidget(); + renderPanel.getInteractor().addObserver(widget); + widget.SetRepresentation(representation); + + // widget.AllowHandleResizeOff(); + // widget.EnableAxisConstraintOff(); + // widget.EnabledOff(); + // widget.ManagesCursorOff(); + widget.ProcessEventsOff();// MuDeMe! + // widget.RemoveAllObservers(); + + } + + private void addListener() { + if (currentSelection != null) { + currentSelection.addPropertyChangeListener(listener); + } + } + + private void removeListener() { + if (currentSelection != null) { + currentSelection.removePropertyChangeListener(listener); + } + } + + @Override + public void pick(PickInfo pi) { + removeListener(); + + ExtractSelection extract = new ExtractSelection(); + extract.setSelection(currentSelection); + extract.execute(pi); + + if (representation.GetHandle() != null && representation.GetHandle().GetNumberOfCells() == 0) { + moveSelectionOnTop(); + } + representation.SetHandle(currentSelection.getSelectionData()); + renderPanel.renderLater(); + + addListener(); + } + + public void clear() { + widget = null; + representation = null; + } + + public void selectionBoxOn() { + renderPanel.getInteractor().setStyleToArea(); + } + + public void selectionBoxOff() { + renderPanel.getInteractor().setStyleToDefault(); + } + + private void moveSelectionOnTop() { + renderPanel.lock(); + widget.Off(); + widget.On(); + renderPanel.unlock(); + } + + private void clearSelection() { + if (currentSelection != null) { + currentSelection.setIdList(null); + } + if (representation != null) { + representation.SetHandle(new vtkPolyData()); + renderPanel.renderLater(); + } + } + + public Selection getSelection() { + return currentSelection; + } + + public class SelectionListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getSource() instanceof Selection) { + Selection selection = (Selection) evt.getSource(); + if (evt.getPropertyName().equals("type")) { + switch (selection.getType()) { + case CELL: + selectionBoxOff(); + break; + case AREA: + selectionBoxOn(); + break; + case FEATURE: + selectionBoxOff(); + break; + + default: + break; + } + } else if (evt.getPropertyName().equals("dataSet")) { + currentSelection.setDataSet(selection.getDataSet()); + } + } + } + } + +} diff --git a/src/eu/engys/vtk/widgets/LayersCoverageWidget.java b/src/eu/engys/vtk/widgets/LayersCoverageWidget.java new file mode 100644 index 0000000..c7e87f2 --- /dev/null +++ b/src/eu/engys/vtk/widgets/LayersCoverageWidget.java @@ -0,0 +1,223 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets; + +import java.awt.Component; +import java.awt.GridLayout; +import java.io.File; +import java.text.DecimalFormat; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingConstants; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkLookupTable; +import vtk.vtkPolyData; +import vtk.vtkPolyDataReader; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.core.project.Model; +import eu.engys.core.project.mesh.FieldItem; +import eu.engys.core.project.mesh.FieldItem.DataType; +import eu.engys.gui.view3D.Actor; +import eu.engys.gui.view3D.LayerInfo; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.gui.view3D.Representation; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.util.ui.checkboxtree.VisibleItem; +import eu.engys.util.ui.textfields.AdaptativeFormat; +import eu.engys.vtk.VTKColors; +import eu.engys.vtk.VTKRangeCalculator; +import eu.engys.vtk.actors.DefaultActor; + +public class LayersCoverageWidget { + + class vtkPolyDataWidget { + + private RenderPanel renderPanel; + private Actor actor; + private vtkLookupTable lut; + + public vtkPolyDataWidget(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + + vtkPolyDataReader reader = new vtkPolyDataReader(); + reader.ReadAllFieldsOn(); + reader.ReadAllScalarsOn(); + reader.SetFileName(new File(model.getProject().getBaseDir(), LAYER_INFO_VTK).getAbsolutePath()); + reader.Update(); + + final vtkPolyData layerInfo = reader.GetOutput(); + + this.actor = new DefaultActor("LayersInfo") { + { + newActor(layerInfo, true); + } + @Override + public VisibleItem getVisibleItem() { + return null; + } + @Override + public void setRepresentation(Representation representation) { + super.setRepresentation(Representation.SURFACE); + } + }; + } + + public void update(FieldItem field) { + new VTKRangeCalculator(field).calculateRange_Automatically_For(actor); + lut = new vtkLookupTable(); + VTKColors.applyTypeToLookupTable(field, lut); + this.actor.setScalarColors(lut, field); + } + + private void On() { + renderPanel.addActor(actor); + } + + private void Off() { + renderPanel.removeActor(actor); + } + + public vtkLookupTable getLut() { + return lut; + } + + public void Delete() { + renderPanel.removeActor(actor); + actor.deleteActor(); + lut.Delete(); + } + } + + private static final String LAYER_INFO_VTK = "layerInfo.vtk"; + private static final Logger logger = LoggerFactory.getLogger(LayersCoverageWidget.class); + + private final Model model; + private final RenderPanel renderPanel; + private final ProgressMonitor monitor; + + private vtkPolyDataWidget widget; + + private JPanel colorBar; + private LayerInfo layerInfo; + + public LayersCoverageWidget(Model model, RenderPanel renderPanel, ProgressMonitor monitor) { + this.model = model; + this.renderPanel = renderPanel; + this.monitor = monitor; + } + + public void activateLayersCoverage(LayerInfo layerInfo, JPanel colorBar, EventActionType action) { + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + if (this.colorBar != null) { + this.colorBar.removeAll(); + } + hide(); + } else if (action.equals(EventActionType.SHOW)) { + if (this.colorBar != null) { + this.colorBar.removeAll(); + } + this.colorBar = colorBar; + this.layerInfo = layerInfo; + show(); + } else if (action.equals(EventActionType.REMOVE)) { + clear(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void hide() { + if (widget != null) { + widget.Off(); + } + } + + private void show() { + if (widget == null) { + createWidget(); + } + + updateWidget(); + + widget.On(); + } + + private void updateWidget() { + FieldItem field = new FieldItem(layerInfo.getKey(), DataType.CELL, -1); + if (widget != null) { + widget.update(field); + } + if (colorBar != null) { + colorBar.removeAll(); + colorBar.setLayout(new GridLayout(1, 0)); +// colorBar.setLayout(new FlowLayout(SwingConstants.LEFT, 2, 1)); + double[] range = field.getRange(); + if (layerInfo.isDiscrete()) { + for (int i = (int) range[0]; i<= (int) range[1]; i++) { + colorBar.add(getLabelForValue(i, INT_FORMATTER.format(i))); + } + } else { + colorBar.add(getLabelForValue(range[0], DOUBLE_FORMATTER.format(range[0]))); + colorBar.add(getLabelForValue(range[1], DOUBLE_FORMATTER.format(range[1]))); + } + colorBar.revalidate(); + colorBar.repaint(); + } + } + + private static final AdaptativeFormat DOUBLE_FORMATTER = new AdaptativeFormat(new DecimalFormat("0.0##"), new DecimalFormat("0.0##E0"), 3); + private static final DecimalFormat INT_FORMATTER = new DecimalFormat("0"); + + private Component getLabelForValue(double value, String text) { + double[] color = new double[3]; + JLabel label = new JLabel(text); + label.setHorizontalAlignment(SwingConstants.CENTER); + label.setOpaque(true); + widget.getLut().GetColor(value, color); + label.setBackground(VTKColors.toSwing(color)); + label.setForeground(VTKColors.inverse(color)); + return label; + } + + private void createWidget() { + widget = new vtkPolyDataWidget(renderPanel); + } + + public void clear() { + renderPanel.lock(); + if (widget != null) { + widget.Delete(); + } + widget = null; + renderPanel.unlock(); + } + +} diff --git a/src/eu/engys/vtk/widgets/LogoWidget.java b/src/eu/engys/vtk/widgets/LogoWidget.java new file mode 100644 index 0000000..c492c34 --- /dev/null +++ b/src/eu/engys/vtk/widgets/LogoWidget.java @@ -0,0 +1,119 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import java.awt.Dimension; +import java.nio.file.Path; +import java.nio.file.Paths; + +import vtk.vtkGenericRenderWindowInteractor; +import vtk.vtkImageData; +import vtk.vtkLogoRepresentation; +import vtk.vtkLogoWidget; +import vtk.vtkPNGReader; +import eu.engys.gui.view3D.Interactor; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.ApplicationInfo; + +public class LogoWidget { + + private RenderPanel renderPanel; + private vtkLogoWidget logoWidget; + private vtkLogoRepresentation logoRepresentation; + private vtkImageData imageData; + + public LogoWidget(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + this.imageData = createImageData(); + vtkLogoRepresentation logoRepresentation = createRepresentation(); + createWidget(logoRepresentation); + logoWidget.On(); + } + + private void createWidget(vtkLogoRepresentation logoRepresentation) { + logoWidget = new vtkLogoWidget(); + logoWidget.SetRepresentation(logoRepresentation); + logoWidget.ResizableOff(); + logoWidget.ProcessEventsOff(); + logoWidget.SelectableOff(); + + renderPanel.getInteractor().addObserver(logoWidget); + } + + private vtkLogoRepresentation createRepresentation() { + logoRepresentation = new vtkLogoRepresentation(); + logoRepresentation.SetImage(imageData); + + logoRepresentation.DragableOff(); + logoRepresentation.PickableOff(); + logoRepresentation.SetShowBorderToOff(); + logoRepresentation.ProportionalResizeOff(); + logoRepresentation.GetImageProperty().SetDisplayLocationToBackground(); + logoRepresentation.GetImageProperty().SetOpacity(0.7); + logoRepresentation.GetBorderProperty().SetOpacity(0); + logoRepresentation.VisibilityOn(); + + return logoRepresentation; + } + + private void placeRepresentation(Dimension size) { + logoRepresentation.GetPositionCoordinate().SetCoordinateSystemToDisplay(); + logoRepresentation.GetPosition2Coordinate().SetCoordinateSystemToDisplay(); + double imageWidth = imageData.GetBounds()[1]; + double imageHeight = imageData.GetBounds()[3]; + + double bottomLeftCornerX = size.width - imageWidth - 40; + double bottomLeftCornerY = 40; + double topRightCornerX = imageWidth + 1; + double topRightCornerY = imageHeight + 1; + + logoRepresentation.SetPosition(bottomLeftCornerX, bottomLeftCornerY); + logoRepresentation.SetPosition2(topRightCornerX, topRightCornerY); + + renderPanel.lock(); + final Interactor interactor = renderPanel.getInteractor(); + if (interactor instanceof vtkGenericRenderWindowInteractor) { + vtkGenericRenderWindowInteractor iren = (vtkGenericRenderWindowInteractor) interactor; + iren.LeftButtonPressEvent(); + iren.LeftButtonReleaseEvent(); + } + renderPanel.unlock(); + } + + private vtkImageData createImageData() { + vtkPNGReader reader = new vtkPNGReader(); + Path fileName = Paths.get(ApplicationInfo.getRootPath(), "img", ApplicationInfo.getVendor() + ".png"); + reader.SetFileName(fileName.toString()); + reader.Update(); + return reader.GetOutput(); + } + + public void update(Dimension size) { + placeRepresentation(size); + } + +} diff --git a/src/eu/engys/vtk/widgets/MinMaxPointWidget.java b/src/eu/engys/vtk/widgets/MinMaxPointWidget.java new file mode 100644 index 0000000..b06d6de --- /dev/null +++ b/src/eu/engys/vtk/widgets/MinMaxPointWidget.java @@ -0,0 +1,117 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import javax.vecmath.Point3d; + +import vtk.vtkHandleWidget; +import vtk.vtkSphereHandleRepresentation; +import eu.engys.gui.events.view3D.VolumeReportVisibilityEvent.Kind; +import eu.engys.gui.view3D.RenderPanel; + +public class MinMaxPointWidget { + + private RenderPanel renderPanel; + private vtkHandleWidget minWidget; + private vtkHandleWidget maxWidget; + private Point3d minPoint; + private Point3d maxPoint; + + public MinMaxPointWidget(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + minWidget = createHandleWidget(new double[] { 0, 0, 1 }); + maxWidget = createHandleWidget(new double[] { 1, 0, 0 }); + } + + private vtkHandleWidget createHandleWidget(double[] color) { + + vtkSphereHandleRepresentation rep = new vtkSphereHandleRepresentation(); + rep.GetProperty().SetColor(color); + rep.GetProperty().SetLineWidth(1.0); + rep.GetSelectedProperty().SetColor(0.1, 0.1, 0.1); + rep.PickableOff(); + rep.DragableOff(); + // rep.ConstrainedOff(); + // rep.TranslationModeOff(); + + vtkHandleWidget widget = new vtkHandleWidget(); + widget.EnableAxisConstraintOff(); + widget.SetRepresentation(rep); + widget.EnabledOff(); + + renderPanel.getInteractor().addObserver(widget); + + return widget; + } + + public void clear() { + minWidget.EnabledOff(); + maxWidget.EnabledOff(); + minWidget.Delete(); + maxWidget.Delete(); + renderPanel.renderLater(); + } + + public void showPoint(Kind kind) { + if (kind.isMin() && minWidget.GetEnabled() == 0) { + minWidget.EnabledOn(); + renderPanel.renderLater(); + } else if (kind.isMax() && maxWidget.GetEnabled() == 0) { + maxWidget.EnabledOn(); + renderPanel.renderLater(); + } + updateCoordinates(); + } + + public void hidePoint(Kind kind) { + if (kind.isMin() && minWidget.GetEnabled() == 1) { + minWidget.EnabledOff(); + renderPanel.renderLater(); + } else if (kind.isMax() && maxWidget.GetEnabled() == 1) { + maxWidget.EnabledOff(); + renderPanel.renderLater(); + } + } + + public void setPoints(Point3d minPoint, Point3d maxPoint) { + this.minPoint = minPoint; + this.maxPoint = maxPoint; + updateCoordinates(); + } + + private void updateCoordinates() { + if (minWidget.GetEnabled() == 1 && minPoint != null) { + ((vtkSphereHandleRepresentation) minWidget.GetRepresentation()).SetWorldPosition(new double[] { minPoint.getX(), minPoint.getY(), minPoint.getZ() }); + renderPanel.renderLater(); + } + if (maxWidget.GetEnabled() == 1 && maxPoint != null) { + ((vtkSphereHandleRepresentation) maxWidget.GetRepresentation()).SetWorldPosition(new double[] { maxPoint.getX(), maxPoint.getY(), maxPoint.getZ() }); + renderPanel.renderLater(); + } + } + +} diff --git a/src/eu/engys/vtk/widgets/MinMaxPointWidgetManager.java b/src/eu/engys/vtk/widgets/MinMaxPointWidgetManager.java new file mode 100644 index 0000000..ff44365 --- /dev/null +++ b/src/eu/engys/vtk/widgets/MinMaxPointWidgetManager.java @@ -0,0 +1,74 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import java.util.HashMap; +import java.util.Map; + +import javax.vecmath.Point3d; + +import eu.engys.gui.events.view3D.VolumeReportVisibilityEvent.Kind; +import eu.engys.vtk.VTKRenderPanel; + +public class MinMaxPointWidgetManager { + + private Map widgetMap = new HashMap<>(); + private VTKRenderPanel vtkRendererPanel; + + public MinMaxPointWidgetManager(VTKRenderPanel vtkRendererPanel) { + this.vtkRendererPanel = vtkRendererPanel; + } + + public void clear() { + for (MinMaxPointWidget w : widgetMap.values()) { + w.clear(); + } + widgetMap.clear(); + } + + public void setPointsVisible(String key, Kind kind, boolean visible) { + if(visible){ + getPointWidget(key).showPoint(kind); + } else { + getPointWidget(key).hidePoint(kind); + } + } + + public void updateCoordinates(Point3d minPoint, Point3d maxPoint, String key) { + MinMaxPointWidget pointWidget = getPointWidget(key); + pointWidget.setPoints(minPoint, maxPoint); + } + + private MinMaxPointWidget getPointWidget(String key) { + if (!widgetMap.containsKey(key)) { + MinMaxPointWidget widget = new MinMaxPointWidget(vtkRendererPanel); + widgetMap.put(key, widget); + } + return widgetMap.get(key); + } + +} diff --git a/src/eu/engys/vtk/widgets/PlaneDisplayWidget.java b/src/eu/engys/vtk/widgets/PlaneDisplayWidget.java new file mode 100644 index 0000000..be8a497 --- /dev/null +++ b/src/eu/engys/vtk/widgets/PlaneDisplayWidget.java @@ -0,0 +1,113 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets; + +import vtk.vtkHandleWidget; +import vtk.vtkPlaneSource; +import vtk.vtkPolygonalHandleRepresentation3D; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.ui.textfields.DoubleField; + +public class PlaneDisplayWidget { + + private RenderPanel renderPanel; + private vtkHandleWidget widget; + private vtkPolygonalHandleRepresentation3D representation; + private DoubleField[] currentOrigin = null; + private DoubleField[] currentNormal = null; + + public PlaneDisplayWidget(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + } + + public void showPlane(DoubleField[] origin, DoubleField[] normal, EventActionType action, double diagonal) { + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + if(widget != null){ + widget.Off(); + currentOrigin = null; + currentNormal = null; + } + } else if (action.equals(EventActionType.SHOW)) { + if(widget == null){ + createWidget(); + } + currentOrigin = origin; + currentNormal = normal; + changePosition(diagonal); + widget.On(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void createWidget() { + widget = new vtkHandleWidget(); + + representation = new vtkPolygonalHandleRepresentation3D(); + representation.GetProperty().SetColor(1, 1, 1); + representation.GetSelectedProperty().SetColor(1, 1, 1); + representation.DragableOff(); + representation.PickableOff(); + representation.ActiveRepresentationOff(); +// rep.SetWorldPosition(new double[] { 0.0, 0.0, 0.0 }); + + widget.SetRepresentation(representation); + widget.EnableAxisConstraintOff(); + widget.ProcessEventsOff(); + + renderPanel.getInteractor().addObserver(widget); + } + + + private void changePosition(double diagonal) { + double value = Double.isInfinite(diagonal) ? 1 : diagonal > 0 ? diagonal : 1; + + vtkPlaneSource planeSource = new vtkPlaneSource(); + planeSource.SetOrigin(0, 0, 0); + planeSource.SetPoint1(value, 0, 0); + planeSource.SetPoint2(0, value, 0); + planeSource.SetCenter(currentOrigin[0].getDoubleValue(), currentOrigin[1].getDoubleValue(), currentOrigin[2].getDoubleValue()); + planeSource.SetNormal(currentNormal[0].getDoubleValue(), currentNormal[1].getDoubleValue(), currentNormal[2].getDoubleValue()); + planeSource.Update(); + + representation.SetHandle(planeSource.GetOutput()); + } + + public void clear() { + renderPanel.lock(); + if(widget != null){ + widget.EnabledOff(); + widget.Delete(); + widget = null; + } + currentOrigin = null; + currentNormal = null; + renderPanel.unlock(); + renderPanel.renderLater(); + } +} diff --git a/src/eu/engys/vtk/widgets/PlaneWidget.java b/src/eu/engys/vtk/widgets/PlaneWidget.java new file mode 100644 index 0000000..cfbbbbc --- /dev/null +++ b/src/eu/engys/vtk/widgets/PlaneWidget.java @@ -0,0 +1,171 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import vtk.vtkPlaneWidget; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.ui.textfields.DoubleField; + +public class PlaneWidget { + + private RenderPanel renderPanel; + private vtkPlaneWidget widget; + private PropertyChangeListener listener; + private DoubleField[] currentOrigin = null; + private DoubleField[] currentNormal = null; + + public PlaneWidget(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + listener = new PlaneFieldListener(); + } + + public void showPlane(DoubleField[] origin, DoubleField[] normal, EventActionType action, double diagonal) { + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + if(widget != null){ + widget.Off(); + removeListener(); + currentOrigin = null; + currentNormal = null; + } + } else if (action.equals(EventActionType.SHOW)) { + removeListener(); + if(widget == null){ + createWidget(diagonal); + } + currentOrigin = origin; + currentNormal = normal; + changePosition(); + widget.On(); + addListener(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void createWidget(double diagonal) { + widget = new vtkPlaneWidget(); + widget.SetHandleSize(1); + widget.SetRepresentationToSurface(); + widget.AddObserver("EndInteractionEvent", this, "handleEndInteraction"); + + widget.SetOrigin(0, 0, 0); + widget.SetPoint1(diagonal, 0, 0); + widget.SetPoint2(0, diagonal, 0); + +// widget.SetHandleSize(3); +// widget.SetPlaceFactor(1); +// widget.PlaceWidget(); +// widget.SetResolution(1); +// widget.GetPlaneProperty().SetColor(VTKColors.GREEN); +// widget.GetPlaneProperty().SetOpacity(0.7); +// widget.GetPlaneProperty().EdgeVisibilityOn(); + + renderPanel.getInteractor().addObserver(widget); + } + + public void clear() { + removeListener(); + renderPanel.lock(); + if(widget != null){ + widget.EnabledOff(); + widget.Delete(); + widget = null; + } + currentOrigin = null; + currentNormal = null; + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void changePosition() { + if (currentOrigin != null) { + widget.SetCenter(new double[] { currentOrigin[0].getDoubleValue(), currentOrigin[1].getDoubleValue(), currentOrigin[2].getDoubleValue() }); + } + if (currentNormal != null) { + widget.SetNormal(new double[] { currentNormal[0].getDoubleValue(), currentNormal[1].getDoubleValue(), currentNormal[2].getDoubleValue() }); + } + } + + private void addListener() { + if (currentOrigin != null) { + currentOrigin[0].addPropertyChangeListener(listener); + currentOrigin[1].addPropertyChangeListener(listener); + currentOrigin[2].addPropertyChangeListener(listener); + } + if (currentNormal != null) { + currentNormal[0].addPropertyChangeListener(listener); + currentNormal[1].addPropertyChangeListener(listener); + currentNormal[2].addPropertyChangeListener(listener); + } + } + + private void removeListener() { + if (currentOrigin != null) { + currentOrigin[0].removePropertyChangeListener(listener); + currentOrigin[1].removePropertyChangeListener(listener); + currentOrigin[2].removePropertyChangeListener(listener); + } + if (currentNormal != null) { + currentNormal[0].removePropertyChangeListener(listener); + currentNormal[1].removePropertyChangeListener(listener); + currentNormal[2].removePropertyChangeListener(listener); + } + } + + void handleEndInteraction() { + removeListener(); + if (currentOrigin != null) { + double[] position = widget.GetCenter(); + currentOrigin[0].setDoubleValue(position[0]); + currentOrigin[1].setDoubleValue(position[1]); + currentOrigin[2].setDoubleValue(position[2]); + } + if (currentNormal != null) { + double[] position = widget.GetNormal(); + currentNormal[0].setDoubleValue(position[0]); + currentNormal[1].setDoubleValue(position[1]); + currentNormal[2].setDoubleValue(position[2]); + } + addListener(); + } + + private final class PlaneFieldListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + changePosition(); + renderPanel.Render(); + } + } + } + +} diff --git a/src/eu/engys/vtk/widgets/PointWidget.java b/src/eu/engys/vtk/widgets/PointWidget.java new file mode 100644 index 0000000..d463171 --- /dev/null +++ b/src/eu/engys/vtk/widgets/PointWidget.java @@ -0,0 +1,139 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import java.awt.Color; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import vtk.vtkHandleWidget; +import vtk.vtkSphereHandleRepresentation; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.ui.textfields.DoubleField; + +public class PointWidget { + + private final class PointFieldListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + changePosition(); + renderPanel.renderLater(); + } + } + } + + private RenderPanel renderPanel; + private vtkSphereHandleRepresentation rep; + private vtkHandleWidget hwidget; + private PropertyChangeListener listener; + private DoubleField[] currentPoint = null; + + public PointWidget(RenderPanel renderPanel, Color color) { + this.renderPanel = renderPanel; + hwidget = new vtkHandleWidget(); + + renderPanel.getInteractor().addObserver(hwidget); + + rep = new vtkSphereHandleRepresentation(); + hwidget.SetRepresentation(rep); + hwidget.EnableAxisConstraintOff(); + hwidget.AddObserver("EndInteractionEvent", this, "handleEndInteraction"); + + rep.SetWorldPosition(new double[] { 0.0, 0.0, 0.0 }); + + float[] colorRGB = new float[3]; + color.getRGBColorComponents(colorRGB); + rep.GetProperty().SetColor(colorRGB[0], colorRGB[1], colorRGB[2]); + + rep.GetProperty().SetLineWidth(1.0); + rep.GetSelectedProperty().SetColor(0.1, 0.1, 0.1); + + listener = new PointFieldListener(); + } + + public void clear() { + removeListener(); + renderPanel.lock(); + hwidget.EnabledOff(); + hwidget.Delete(); + currentPoint = null; + renderPanel.unlock(); + renderPanel.renderLater(); + } + + public void showPoint(DoubleField[] point, EventActionType action) { + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + hwidget.EnabledOff(); + removeListener(); + currentPoint = null; + } else if (action.equals(EventActionType.SHOW)) { + removeListener(); + hwidget.EnabledOn(); + currentPoint = point; + changePosition(); + addListener(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void changePosition() { + if (currentPoint != null) { + rep.SetWorldPosition(new double[] { currentPoint[0].getDoubleValue(), currentPoint[1].getDoubleValue(), currentPoint[2].getDoubleValue() }); + } + } + + private void addListener() { + if (currentPoint != null) { + currentPoint[0].addPropertyChangeListener(listener); + currentPoint[1].addPropertyChangeListener(listener); + currentPoint[2].addPropertyChangeListener(listener); + } + } + + private void removeListener() { + if (currentPoint != null) { + currentPoint[0].removePropertyChangeListener(listener); + currentPoint[1].removePropertyChangeListener(listener); + currentPoint[2].removePropertyChangeListener(listener); + } + } + + void handleEndInteraction() { + removeListener(); + if (currentPoint != null) { + double[] position = rep.GetWorldPosition(); + currentPoint[0].setDoubleValue(position[0]); + currentPoint[1].setDoubleValue(position[1]); + currentPoint[2].setDoubleValue(position[2]); + } + addListener(); + } +} diff --git a/src/eu/engys/vtk/widgets/PointWidgetManager.java b/src/eu/engys/vtk/widgets/PointWidgetManager.java new file mode 100644 index 0000000..349096c --- /dev/null +++ b/src/eu/engys/vtk/widgets/PointWidgetManager.java @@ -0,0 +1,69 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets; + +import java.awt.Color; +import java.util.HashMap; +import java.util.Map; + +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.util.ui.textfields.DoubleField; +import eu.engys.vtk.VTKRenderPanel; + +public class PointWidgetManager { + + private Map widgetMap = new HashMap<>(); + private VTKRenderPanel vtkRendererPanel; + + public PointWidgetManager(VTKRenderPanel vtkRendererPanel) { + this.vtkRendererPanel = vtkRendererPanel; + } + + public void clear() { + for (PointWidget w : widgetMap.values()) { + w.clear(); + } + widgetMap.clear(); + } + + public void showPoint(DoubleField[] point, String key, EventActionType action, Color color) { + if (action.equals(EventActionType.REMOVE)) { + if (widgetMap.containsKey(key)) { + PointWidget w = widgetMap.remove(key); + w.clear(); + } + } else { + if (!widgetMap.containsKey(key)) { + PointWidget widget = new PointWidget(vtkRendererPanel, color); + widgetMap.put(key, widget); + } + PointWidget pointWidget = widgetMap.get(key); + pointWidget.showPoint(point, action); + } + } + +} diff --git a/src/eu/engys/vtk/widgets/QualityWidget.java b/src/eu/engys/vtk/widgets/QualityWidget.java new file mode 100644 index 0000000..3835127 --- /dev/null +++ b/src/eu/engys/vtk/widgets/QualityWidget.java @@ -0,0 +1,223 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets; + +import java.awt.Color; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import vtk.vtkHandleWidget; +import vtk.vtkPolyData; +import vtk.vtkPolygonalHandleRepresentation3D; +import vtk.vtkThreshold; +import vtk.vtkUnstructuredGrid; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.core.project.Model; +import eu.engys.gui.view3D.QualityInfo; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.progress.ProgressMonitor; +import eu.engys.vtk.VTKColors; +import eu.engys.vtk.VTKOpenFOAMDataset; +import eu.engys.vtk.VTKUtil; + +public class QualityWidget { + + public class QualityListener implements PropertyChangeListener{ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("threshold")) { + if (evt.getSource() instanceof QualityInfo) { + updateWidget(); + } + } + } + } + + private static final Logger logger = LoggerFactory.getLogger(QualityWidget.class); + + private static final int FIELD_ASSOCIATION_CELLS = 1; + + private final Model model; + private final RenderPanel renderPanel; + private final ProgressMonitor monitor; + + private vtkHandleWidget widget; + private vtkPolygonalHandleRepresentation3D representation; + private QualityListener listener; + + private QualityInfo currentQualityInfo; + + public QualityWidget(Model model, RenderPanel renderPanel, ProgressMonitor monitor) { + this.model = model; + this.renderPanel = renderPanel; + this.monitor = monitor; + this.listener = new QualityListener(); + } + + public void activateQualityField(QualityInfo qualityInfo, EventActionType action) { + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + hide(); + } else if (action.equals(EventActionType.SHOW)) { + this.currentQualityInfo = qualityInfo; + show(); + } else if (action.equals(EventActionType.REMOVE)) { + clearSelection(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void hide() { + if (widget != null) { + widget.Off(); + removeListener(); + currentQualityInfo = null; + representation.SetHandle(new vtkPolyData()); + } + } + + private void show() { + if (widget == null) { + createWidget(); + } + + updateWidget(); + + widget.On(); + addListener(); + } + + private void setColor(Color color) { + double[] d = VTKColors.toVTK(color); + representation.GetProperty().SetColor(d); + representation.GetSelectedProperty().SetColor(d); + } + + private void createWidget() { + representation = new vtkPolygonalHandleRepresentation3D(); +// representation.GetProperty().LightingOff(); + + representation.DragableOff(); + representation.PickableOff(); + representation.ActiveRepresentationOff();//MuDeMe! + + widget = new vtkHandleWidget(); + renderPanel.getInteractor().addObserver(widget); + widget.SetRepresentation(representation); + +// widget.AllowHandleResizeOff(); +// widget.EnableAxisConstraintOff(); +// widget.EnabledOff(); +// widget.ManagesCursorOff(); + widget.ProcessEventsOff();//MuDeMe! +// widget.RemoveAllObservers(); + + } + + private vtkUnstructuredGrid internalMesh; + + private void updateWidget() { + if (internalMesh == null) { + loadInternalMesh(); + } + + setColor(currentQualityInfo.getColor()); + + vtkThreshold threshold = new vtkThreshold(); +// threshold.SetAttributeModeToUseCellData(); + threshold.SetInputData(internalMesh); +// threshold.AllScalarsOff(); + + switch (currentQualityInfo.getMeasure().getTest()) { + case MORE_THAN: + threshold.ThresholdByLower(currentQualityInfo.getThreshold()); + break; + case LESS_THAN: + threshold.ThresholdByUpper(currentQualityInfo.getThreshold()); + break; + default: + System.err.println("ERROR: Threshold not set!"); + break; + } + + threshold.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", currentQualityInfo.getMeasure().getFieldName()); + threshold.Update(); + + vtkPolyData dataSet = VTKUtil.geometryFilter(threshold.GetOutput()); + + representation.SetHandle(dataSet); + renderPanel.renderLater(); + } + + private void loadInternalMesh() { + monitor.start("Loading internal mesh", false, new Runnable() { + @Override + public void run() { + VTKOpenFOAMDataset dataset = new VTKOpenFOAMDataset(model, monitor); + dataset.loadInternalMesh(0); + + monitor.info("-> Internal Mesh Actor"); + internalMesh = VTKOpenFOAMDataset.shallowCopy(dataset.getInternalMeshDataset()); + + dataset.clear(); + monitor.end(); + } + }); + } + + private void addListener() { + if (currentQualityInfo != null && !currentQualityInfo.isListenedBy(listener)) { + currentQualityInfo.addPropertyChangeListener(listener); + } + } + + private void removeListener() { + if (currentQualityInfo != null && currentQualityInfo.isListenedBy(listener)) { + currentQualityInfo.removePropertyChangeListener(listener); + } + } + + public void clear() { + widget = null; + representation = null; + } + + private void clearSelection() { + if (representation != null) { + representation.SetHandle(new vtkPolyData()); + renderPanel.renderLater(); + } + } + + public QualityInfo getQualityInfo() { + return currentQualityInfo; + } + +} diff --git a/src/eu/engys/vtk/widgets/fake/FakeClipperWidget.java b/src/eu/engys/vtk/widgets/fake/FakeClipperWidget.java new file mode 100644 index 0000000..366778b --- /dev/null +++ b/src/eu/engys/vtk/widgets/fake/FakeClipperWidget.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets.fake; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractButton; +import javax.swing.Icon; +import javax.swing.JToolBar; + +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class FakeClipperWidget extends FakeWidget { + + private static final Icon ICON = ResourcesUtil.getIcon("3d.widget.plane.icon"); + + @Override + public void populate(JToolBar toolbar) { + AbstractButton button = UiUtil.createToolBarButton(new ViewAction(ICON, TOOLTIP) { + + @Override + public void actionPerformed(ActionEvent e) { + } + }); + button.setEnabled(false); + components.add(button); + toolbar.add(button); + } + +} diff --git a/src/eu/engys/vtk/widgets/fake/FakeExportImageWidget.java b/src/eu/engys/vtk/widgets/fake/FakeExportImageWidget.java new file mode 100644 index 0000000..4d41e16 --- /dev/null +++ b/src/eu/engys/vtk/widgets/fake/FakeExportImageWidget.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets.fake; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractButton; +import javax.swing.Icon; +import javax.swing.JToolBar; + +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class FakeExportImageWidget extends FakeWidget { + + private static final Icon ICON = ResourcesUtil.getIcon("3d.widget.export.icon"); + + @Override + public void populate(JToolBar toolbar) { + AbstractButton button = UiUtil.createToolBarButton(new ViewAction(ICON, TOOLTIP) { + + @Override + public void actionPerformed(ActionEvent e) { + } + }); + button.setEnabled(false); + components.add(button); + toolbar.add(button); + } + +} diff --git a/src/eu/engys/vtk/widgets/fake/FakeFieldsWidget.java b/src/eu/engys/vtk/widgets/fake/FakeFieldsWidget.java new file mode 100644 index 0000000..d972c6d --- /dev/null +++ b/src/eu/engys/vtk/widgets/fake/FakeFieldsWidget.java @@ -0,0 +1,64 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets.fake; + +import static eu.engys.util.ui.UiUtil.createToolBarComboButton; + +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.JComboBox; +import javax.swing.JToolBar; + +import eu.engys.core.project.mesh.FieldItem; + +public class FakeFieldsWidget extends FakeWidget { + + private static final String PROTOTYPE = "UWater-Magnitude-Icon"; + + @Override + public void populate(JToolBar toolbar) { + toolbar.addSeparator(); + JComboBox fieldsCombo = createToolBarComboButton(getFieldsActions(new ArrayList()), TOOLTIP, PROTOTYPE, false, true); + fieldsCombo.setEnabled(false); + components.add(fieldsCombo); + toolbar.add(fieldsCombo); + } + + public List getFieldsActions(List fieldItems) { + List actions = new ArrayList<>(); + actions.add(new AbstractAction(FieldItem.SOLID) { + + @Override + public void actionPerformed(ActionEvent e) { + } + }); + return actions; + } +} diff --git a/src/eu/engys/vtk/widgets/fake/FakeRulerWidget.java b/src/eu/engys/vtk/widgets/fake/FakeRulerWidget.java new file mode 100644 index 0000000..7213305 --- /dev/null +++ b/src/eu/engys/vtk/widgets/fake/FakeRulerWidget.java @@ -0,0 +1,55 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets.fake; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractButton; +import javax.swing.Icon; +import javax.swing.JToolBar; + +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class FakeRulerWidget extends FakeWidget { + + private static final Icon ICON = ResourcesUtil.getIcon("3d.widget.ruler.icon"); + + @Override + public void populate(JToolBar toolbar) { + AbstractButton button = UiUtil.createToolBarButton(new ViewAction(ICON, TOOLTIP) { + + @Override + public void actionPerformed(ActionEvent e) { + } + }); + button.setEnabled(false); + components.add(button); + toolbar.add(button); + } + +} diff --git a/src/eu/engys/vtk/widgets/fake/FakeScalarBarWidget.java b/src/eu/engys/vtk/widgets/fake/FakeScalarBarWidget.java new file mode 100644 index 0000000..41c37cb --- /dev/null +++ b/src/eu/engys/vtk/widgets/fake/FakeScalarBarWidget.java @@ -0,0 +1,70 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets.fake; + +import java.awt.event.ActionEvent; + +import javax.swing.Icon; +import javax.swing.JToggleButton; +import javax.swing.JToolBar; + +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class FakeScalarBarWidget extends FakeWidget { + + private static final Icon SCALAR_BAR_ICON = ResourcesUtil.getIcon("3d.widget.scalarbar.icon"); + private static final Icon EDIT_SCALAR_BAR_ICON = ResourcesUtil.getIcon("3d.widget.editscalarbar.icon"); + + @Override + public void populate(JToolBar toolbar) { + JToggleButton showButton = UiUtil.createToolBarToggleButton(showAction, true); + JToggleButton editButton = UiUtil.createToolBarToggleButton(editAction, true); + + showButton.setEnabled(false); + editButton.setEnabled(false); + + components.add(showButton); + components.add(editButton); + + toolbar.add(showButton); + toolbar.add(editButton); + + } + + private ViewAction showAction = new ViewAction(null, SCALAR_BAR_ICON, TOOLTIP, false) { + @Override + public void actionPerformed(ActionEvent e) { + } + }; + + private ViewAction editAction = new ViewAction(null, EDIT_SCALAR_BAR_ICON, TOOLTIP, false) { + @Override + public void actionPerformed(ActionEvent e) { + } + }; +} diff --git a/src/eu/engys/vtk/widgets/fake/FakeSelectionWidget.java b/src/eu/engys/vtk/widgets/fake/FakeSelectionWidget.java new file mode 100644 index 0000000..6d882e8 --- /dev/null +++ b/src/eu/engys/vtk/widgets/fake/FakeSelectionWidget.java @@ -0,0 +1,56 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets.fake; + +import java.awt.event.ActionEvent; + +import javax.swing.Icon; +import javax.swing.JToggleButton; +import javax.swing.JToolBar; + +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class FakeSelectionWidget extends FakeWidget { + + private static final Icon ICON = ResourcesUtil.getIcon("3d.widget.feature.icon"); + + @Override + public void populate(JToolBar toolbar) { + JToggleButton button = UiUtil.createToolBarToggleButton(action, true); + button.setEnabled(false); + toolbar.add(button); + components.add(button); + } + + private ViewAction action = new ViewAction(ICON, TOOLTIP) { + @Override + public void actionPerformed(ActionEvent e) { + } + }; + +} diff --git a/src/eu/engys/vtk/widgets/fake/FakeTimeStepsWidget.java b/src/eu/engys/vtk/widgets/fake/FakeTimeStepsWidget.java new file mode 100644 index 0000000..aee6d61 --- /dev/null +++ b/src/eu/engys/vtk/widgets/fake/FakeTimeStepsWidget.java @@ -0,0 +1,114 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets.fake; + +import static eu.engys.util.ui.UiUtil.createToolBarComboButton; + +import java.awt.event.ActionEvent; +import java.util.Collections; + +import javax.swing.AbstractButton; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.JComboBox; +import javax.swing.JToolBar; + +import eu.engys.util.ui.ResourcesUtil; +import eu.engys.util.ui.UiUtil; +import eu.engys.util.ui.ViewAction; + +public class FakeTimeStepsWidget extends FakeWidget { + + private static final String PROTOTYPE = "12345.67"; + + public static final String[] COMPONENTS = new String[] { "Magnitude", "X", "Y", "Z" }; + + public static final Icon PREV_ICON = ResourcesUtil.getIcon("3d.widget.times.prev.icon"); + public static final Icon NEXT_ICON = ResourcesUtil.getIcon("3d.widget.times.next.icon"); + public static final Icon FIRST_ICON = ResourcesUtil.getIcon("3d.widget.times.first.icon"); + public static final Icon LAST_ICON = ResourcesUtil.getIcon("3d.widget.times.last.icon"); + public static final Icon REFRESH_ICON = ResourcesUtil.getIcon("3d.widget.times.refresh.icon"); + + private Action NEXT_STEP = new ViewAction(null, NEXT_ICON, TOOLTIP, false) { + @Override + public void actionPerformed(ActionEvent e) { + } + }; + private Action PREVIOUS_STEP = new ViewAction(null, PREV_ICON, TOOLTIP, false) { + @Override + public void actionPerformed(ActionEvent e) { + } + }; + private Action FIRST_STEP = new ViewAction(null, FIRST_ICON, TOOLTIP, false) { + @Override + public void actionPerformed(ActionEvent e) { + } + }; + private Action LAST_STEP = new ViewAction(null, LAST_ICON, TOOLTIP, false) { + @Override + public void actionPerformed(ActionEvent e) { + } + }; + private Action REFRESH = new ViewAction(null, REFRESH_ICON, TOOLTIP, false) { + @Override + public void actionPerformed(ActionEvent e) { + } + }; + + @Override + public void populate(JToolBar toolbar) { + JComboBox timesCombo = createToolBarComboButton(Collections. emptyList(), TOOLTIP, PROTOTYPE, true, true); + AbstractButton firstButton = UiUtil.createToolBarButton(FIRST_STEP); + AbstractButton previousButton = UiUtil.createToolBarButton(PREVIOUS_STEP); + AbstractButton nextButton = UiUtil.createToolBarButton(NEXT_STEP); + AbstractButton lastButton = UiUtil.createToolBarButton(LAST_STEP); + AbstractButton refreshButton = UiUtil.createToolBarButton(REFRESH); + + timesCombo.setEnabled(false); + firstButton.setEnabled(false); + previousButton.setEnabled(false); + nextButton.setEnabled(false); + lastButton.setEnabled(false); + refreshButton.setEnabled(false); + + toolbar.addSeparator(); + toolbar.add(timesCombo); + toolbar.add(firstButton); + toolbar.add(previousButton); + toolbar.add(nextButton); + toolbar.add(lastButton); + toolbar.add(refreshButton); + toolbar.addSeparator(); + + components.add(timesCombo); + components.add(firstButton); + components.add(previousButton); + components.add(nextButton); + components.add(lastButton); + components.add(refreshButton); + } + +} diff --git a/src/eu/engys/vtk/widgets/fake/FakeWidget.java b/src/eu/engys/vtk/widgets/fake/FakeWidget.java new file mode 100644 index 0000000..dd3fbd6 --- /dev/null +++ b/src/eu/engys/vtk/widgets/fake/FakeWidget.java @@ -0,0 +1,118 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + +package eu.engys.vtk.widgets.fake; + +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JComponent; + +import eu.engys.gui.view3D.CanvasPanel; +import eu.engys.gui.view3D.widget.Widget; +import eu.engys.gui.view3D.widget.WidgetComponent; + +public abstract class FakeWidget implements Widget { + + protected static final String TOOLTIP = "To enable this feature please contact: info@engys.com"; + + protected List components = new ArrayList(); + + @Override + public void populate(CanvasPanel view3d) { + } + + @Override + public boolean canShow() { + return false; + } + + @Override + public void show() { + disableAll(); + } + + @Override + public void hide() { + disableAll(); + } + + @Override + public void clear() { + disableAll(); + } + + @Override + public void stop() { + disableAll(); + } + + @Override + public WidgetComponent getWidgetComponent() { + return null; + } + + @Override + public void load() { + disableAll(); + } + + @Override + public void applyContext() { + disableAll(); + } + + @Override + public void handleFieldChanged() { + disableAll(); + } + + @Override + public void handleTimeStepChanged() { + disableAll(); + } + + @Override + public void handleNewTimeStepsRead() { + disableAll(); + } + +// @Override +// public void handleInitializeFieldsStarted() { +// disableAll(); +// } +// +// @Override +// public void handleInitializeFieldsFinished() { +// disableAll(); +// } + + private void disableAll() { + for (JComponent c : components) { + c.setEnabled(false); + } + } + +} diff --git a/src/eu/engys/vtk/widgets/panels/BoundingBoxBar.java b/src/eu/engys/vtk/widgets/panels/BoundingBoxBar.java new file mode 100644 index 0000000..1db2b3a --- /dev/null +++ b/src/eu/engys/vtk/widgets/panels/BoundingBoxBar.java @@ -0,0 +1,120 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets.panels; + +import java.awt.Color; +import java.awt.FlowLayout; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +import eu.engys.core.project.geometry.BoundingBox; +import eu.engys.gui.view3D.CanvasPanel; +import eu.engys.util.Symbols; +import eu.engys.util.plaf.ILookAndFeel; + +public class BoundingBoxBar extends JPanel { + + private JLabel xlabel; + private JLabel ylabel; + private JLabel zlabel; + private CanvasPanel view3D; + + public BoundingBoxBar(CanvasPanel view3D, ILookAndFeel laf) { + super(new FlowLayout(FlowLayout.LEFT)); + this.view3D = view3D; + this.xlabel = new JLabel(); + this.ylabel = new JLabel(); + this.zlabel = new JLabel(); + xlabel.setForeground(Color.RED.darker()); + ylabel.setForeground(Color.GREEN.darker()); + zlabel.setForeground(Color.BLUE.darker()); + add(xlabel); + add(ylabel); + add(zlabel); + +// setOpaque(true); +// double[] color = laf.get3DColor1(); +// setBackground(new Color((float) color[0], (float) color[1], (float) color[2])); + } + +// @Override +// protected void paintComponent(Graphics g) { +// Dimension size = getSize(); +// g.setColor(getBackground()); +// g.fillRect(0, 0, size.width, size.height); +// } + + public BoundingBox update() { + BoundingBox box = view3D.computeBoundingBox(true); + if (isEmpty(box)) { + box = new BoundingBox(0, 0, 0, 0, 0, 0); + } + + String formattedXmin = getFormattedNumber(box.getXmin()); + String formattedYmin = getFormattedNumber(box.getYmin()); + String formattedZmin = getFormattedNumber(box.getZmin()); + + String formattedXmax = getFormattedNumber(box.getXmax()); + String formattedYmax = getFormattedNumber(box.getYmax()); + String formattedZmax = getFormattedNumber(box.getZmax()); + + String formattedXDifference = getFormattedNumber((box.getXmax() - box.getXmin())); + String formattedYDifference = getFormattedNumber((box.getYmax() - box.getYmin())); + String formattedZDifference = getFormattedNumber((box.getZmax() - box.getZmin())); + + String xLabelText = String.format(Locale.US, "X [%s , %s] delta %s", formattedXmin, formattedXmax, formattedXDifference).replace("delta", Symbols.DELTA); + String yLabelText = String.format(Locale.US, "Y [%s , %s] delta %s", formattedYmin, formattedYmax, formattedYDifference).replace("delta", Symbols.DELTA); + String zLabelText = String.format(Locale.US, "Z [%s , %s] delta %s", formattedZmin, formattedZmax, formattedZDifference).replace("delta", Symbols.DELTA); + + xlabel.setText(xLabelText); + ylabel.setText(yLabelText); + zlabel.setText(zLabelText); + + return box; + } + + private boolean isEmpty(BoundingBox box) { + boolean xok = box.getXmin() == Double.MAX_VALUE && box.getXmax() == -Double.MAX_VALUE; + boolean yok = box.getYmin() == Double.MAX_VALUE && box.getYmax() == -Double.MAX_VALUE; + boolean zok = box.getZmin() == Double.MAX_VALUE && box.getZmax() == -Double.MAX_VALUE; + return xok && yok && zok; + } + + private String getFormattedNumber(double d) { + DecimalFormat formatter = null; + if (String.valueOf(d).length() > 6) { + formatter = new DecimalFormat("0.00E0", new DecimalFormatSymbols(Locale.US)); + } else { + formatter = new DecimalFormat("#,###,##0.0##############", new DecimalFormatSymbols(Locale.US)); + } + return formatter.format(d); + } +} diff --git a/src/eu/engys/vtk/widgets/shapes/BoxWidget.java b/src/eu/engys/vtk/widgets/shapes/BoxWidget.java new file mode 100644 index 0000000..5313015 --- /dev/null +++ b/src/eu/engys/vtk/widgets/shapes/BoxWidget.java @@ -0,0 +1,192 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets.shapes; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import vtk.vtkActor; +import vtk.vtkBoxRepresentation; +import vtk.vtkBoxWidget2; +import vtk.vtkTransform; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.ui.textfields.DoubleField; + +public class BoxWidget { + + private RenderPanel renderPanel; + private vtkBoxWidget2 widget; + private vtkActor actor; + private BoxFieldListener listener; + private DoubleField[] currentPoint1 = null; + private DoubleField[] currentPoint2 = null; + + public BoxWidget(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + listener = new BoxFieldListener(); + } + + final Runnable callback = new Runnable() { + vtkTransform trasform = new vtkTransform(); + + public void run() { + if (actor != null) { + vtkBoxRepresentation rep = (vtkBoxRepresentation) widget.GetRepresentation(); + rep.GetTransform(trasform); + actor.SetUserTransform(trasform); + } + + removeListener(); + double[] position = widget.GetRepresentation().GetBounds(); + if (currentPoint1 != null) { + currentPoint1[0].setDoubleValue(position[0]); + currentPoint1[1].setDoubleValue(position[2]); + currentPoint1[2].setDoubleValue(position[4]); + } + if (currentPoint2 != null) { + currentPoint2[0].setDoubleValue(position[1]); + currentPoint2[1].setDoubleValue(position[3]); + currentPoint2[2].setDoubleValue(position[5]); + } + addListener(); + } + }; + + public void showBox(vtkActor actor, DoubleField[] point1, DoubleField[] point2, EventActionType action) { + this.actor = actor; + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + if (widget != null) { + widget.Off(); + removeListener(); + currentPoint1 = null; + currentPoint2 = null; + } + } else if (action.equals(EventActionType.SHOW)) { + removeListener(); + if (widget == null) { + createWidget(); + } + widget.On(); + currentPoint1 = point1; + currentPoint2 = point2; + changePosition(); + addListener(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void createWidget() { + final vtkBoxRepresentation representation = new vtkBoxRepresentation(); + representation.SetPlaceFactor(1); + if (actor != null) { + representation.PlaceWidget(actor.GetBounds()); + } else { + representation.PlaceWidget(new double[]{ 0.0,1.0,0.0,1.0,0.0,1.0}); + } + + widget = new vtkBoxWidget2(); + renderPanel.getInteractor().addObserver(widget); + widget.AddObserver("EndInteractionEvent", callback, "run"); + + widget.SetRepresentation(representation); + widget.RotationEnabledOff(); + } + + public void clear() { + removeListener(); + renderPanel.lock(); + if (widget != null) { +// widget.RemoveAllObservers(); + widget.EnabledOff(); + widget.Delete(); + widget = null; + } + currentPoint1 = null; + currentPoint2 = null; + renderPanel.unlock(); + renderPanel.renderLater(); + } + + public void hideWidget() { + clear(); + } + + private void changePosition() { + if (currentPoint1 != null && currentPoint2 != null) { + double minX = currentPoint1[0].getDoubleValue(); + double maxX = currentPoint2[0].getDoubleValue(); + + double minY = currentPoint1[1].getDoubleValue(); + double maxY = currentPoint2[1].getDoubleValue(); + + double minZ = currentPoint1[2].getDoubleValue(); + double maxZ = currentPoint2[2].getDoubleValue(); + + ((vtkBoxRepresentation) widget.GetRepresentation()).PlaceWidget(new double[] { minX, maxX, minY, maxY, minZ, maxZ }); + } + } + + private void addListener() { + if (currentPoint1 != null) { + currentPoint1[0].addPropertyChangeListener(listener); + currentPoint1[1].addPropertyChangeListener(listener); + currentPoint1[2].addPropertyChangeListener(listener); + } + if (currentPoint2 != null) { + currentPoint2[0].addPropertyChangeListener(listener); + currentPoint2[1].addPropertyChangeListener(listener); + currentPoint2[2].addPropertyChangeListener(listener); + } + } + + private void removeListener() { + if (currentPoint1 != null) { + currentPoint1[0].removePropertyChangeListener(listener); + currentPoint1[1].removePropertyChangeListener(listener); + currentPoint1[2].removePropertyChangeListener(listener); + } + if (currentPoint2 != null) { + currentPoint2[0].removePropertyChangeListener(listener); + currentPoint2[1].removePropertyChangeListener(listener); + currentPoint2[2].removePropertyChangeListener(listener); + } + } + + private final class BoxFieldListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + changePosition(); + renderPanel.renderLater(); + } + } + } + +} diff --git a/src/eu/engys/vtk/widgets/shapes/CylinderWidget.java b/src/eu/engys/vtk/widgets/shapes/CylinderWidget.java new file mode 100644 index 0000000..d53a666 --- /dev/null +++ b/src/eu/engys/vtk/widgets/shapes/CylinderWidget.java @@ -0,0 +1,207 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets.shapes; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import vtk.vtkActor; +import vtk.vtkBoxRepresentation; +import vtk.vtkBoxWidget2; +import vtk.vtkLineSource; +import vtk.vtkTransform; +import vtk.vtkTubeFilter; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.ui.textfields.DoubleField; + +public class CylinderWidget { + + private RenderPanel renderPanel; + + private vtkBoxWidget2 widget; + private vtkActor actor; + private BoxFieldListener listener; + private DoubleField[] currentPoint1 = null; + private DoubleField[] currentPoint2 = null; + private DoubleField currentRadius = null; + + public CylinderWidget(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + listener = new BoxFieldListener(); + } + + final Runnable callback = new Runnable() { + vtkTransform transform = new vtkTransform(); + + public void run() { + if (actor != null) { + vtkBoxRepresentation rep = (vtkBoxRepresentation) widget.GetRepresentation(); + rep.GetTransform(transform); + actor.SetUserTransform(transform); + + vtkTubeFilter tubeFilter = (vtkTubeFilter) actor.GetMapper().GetInputConnection(0, 0).GetProducer(); + vtkLineSource cyl = (vtkLineSource) tubeFilter.GetInputConnection(0, 0).GetProducer(); + + double[] tPoint1 = transform.TransformVector(cyl.GetPoint1()); + double[] tPoint2 = transform.TransformVector(cyl.GetPoint2()); + + double[] center = transform.GetPosition(); + + double radius = 0; + // How to find it??? + + removeListener(); + if (currentPoint1 != null) { + currentPoint1[0].setDoubleValue(tPoint1[0] + center[0]); + currentPoint1[1].setDoubleValue(tPoint1[1] + center[1]); + currentPoint1[2].setDoubleValue(tPoint1[2] + center[2]); + } + if (currentPoint2 != null) { + currentPoint2[0].setDoubleValue(tPoint2[0] + center[0]); + currentPoint2[1].setDoubleValue(tPoint2[1] + center[1]); + currentPoint2[2].setDoubleValue(tPoint2[2] + center[2]); + } + if (currentRadius != null) { + currentRadius.setDoubleValue(radius); + } + + addListener(); + } + } + }; + + public void showWidget(vtkActor actor, DoubleField[] point1, DoubleField[] point2, DoubleField radius, EventActionType action) { + this.actor = actor; + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + if (widget != null) { + widget.Off(); + removeListener(); + currentPoint1 = null; + currentPoint2 = null; + currentRadius = null; + } + } else if (action.equals(EventActionType.SHOW)) { + removeListener(); + if (widget == null) { + createWidget(); + } + widget.On(); + currentPoint1 = point1; + currentPoint2 = point2; + currentRadius = radius; + changePosition(); + addListener(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void createWidget() { + final vtkBoxRepresentation representation = new vtkBoxRepresentation(); + representation.SetPlaceFactor(1); + representation.PlaceWidget(actor.GetBounds()); + + widget = new vtkBoxWidget2(); + widget.RemoveAllObservers(); + widget.AddObserver("EndInteractionEvent", callback, "run"); + + renderPanel.getInteractor().addObserver(widget); + + widget.SetRepresentation(representation); + } + + public void clear() { + removeListener(); + renderPanel.lock(); + if (widget != null) { + widget.EnabledOff(); + widget.Delete(); + widget = null; + } + currentPoint1 = null; + currentPoint2 = null; + currentRadius = null; + renderPanel.unlock(); + renderPanel.renderLater(); + } + + public void hideWidget() { + clear(); + } + + private void changePosition() { + // If you change the coordinates from the GeometriesPanelBuilder it + // doesn't work great + ((vtkBoxRepresentation) widget.GetRepresentation()).PlaceWidget(actor.GetBounds()); + renderPanel.Render(); + } + + private void addListener() { + if (currentPoint1 != null) { + currentPoint1[0].addPropertyChangeListener(listener); + currentPoint1[1].addPropertyChangeListener(listener); + currentPoint1[2].addPropertyChangeListener(listener); + } + if (currentPoint2 != null) { + currentPoint2[0].addPropertyChangeListener(listener); + currentPoint2[1].addPropertyChangeListener(listener); + currentPoint2[2].addPropertyChangeListener(listener); + } + if (currentRadius != null) { + currentRadius.addPropertyChangeListener(listener); + } + } + + private void removeListener() { + if (currentPoint1 != null) { + currentPoint1[0].removePropertyChangeListener(listener); + currentPoint1[1].removePropertyChangeListener(listener); + currentPoint1[2].removePropertyChangeListener(listener); + } + if (currentPoint2 != null) { + currentPoint2[0].removePropertyChangeListener(listener); + currentPoint2[1].removePropertyChangeListener(listener); + currentPoint2[2].removePropertyChangeListener(listener); + } + if (currentRadius != null) { + currentRadius.removePropertyChangeListener(listener); + } + } + + private final class BoxFieldListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + changePosition(); + renderPanel.Render(); + } + } + } + +} diff --git a/src/eu/engys/vtk/widgets/shapes/SphereWidget.java b/src/eu/engys/vtk/widgets/shapes/SphereWidget.java new file mode 100644 index 0000000..034da8a --- /dev/null +++ b/src/eu/engys/vtk/widgets/shapes/SphereWidget.java @@ -0,0 +1,228 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package eu.engys.vtk.widgets.shapes; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import vtk.vtkActor; +import vtk.vtkBoxRepresentation; +import vtk.vtkBoxWidget2; +import vtk.vtkTransform; +import eu.engys.core.dictionary.model.EventActionType; +import eu.engys.gui.view3D.RenderPanel; +import eu.engys.util.ui.textfields.DoubleField; + +public class SphereWidget { + + private RenderPanel renderPanel; + private vtkBoxWidget2 widget; + private vtkActor actor; + private BoxFieldListener listener; + private DoubleField[] currentCenter = null; + private DoubleField currentRadius = null; + + public SphereWidget(RenderPanel renderPanel) { + this.renderPanel = renderPanel; + listener = new BoxFieldListener(); + } + + final Runnable callback = new Runnable() { + vtkTransform transform = new vtkTransform(); + + public void run() { + if (actor != null) { + vtkBoxRepresentation rep = (vtkBoxRepresentation) widget.GetRepresentation(); + rep.GetTransform(transform); + actor.SetUserTransform(transform); + } + + removeListener(); + double[] position = widget.GetRepresentation().GetBounds(); + + double x = (position[0] + position[1]) / 2; + double y = (position[2] + position[3]) / 2; + double z = (position[4] + position[5]) / 2; + + double diffX = Math.abs(position[0] - position[1]); + double diffY = Math.abs(position[2] - position[3]); + double diffZ = Math.abs(position[4] - position[5]); + + double radius = Math.min(diffX, Math.min(diffY, diffZ)) / 2; + + if (currentCenter != null) { + currentCenter[0].setDoubleValue(x); + currentCenter[1].setDoubleValue(y); + currentCenter[2].setDoubleValue(z); + } + if (currentRadius != null) { + currentRadius.setDoubleValue(radius); + } + addListener(); + } + }; + + final Runnable callback2 = new Runnable() { + vtkTransform transform = new vtkTransform(); + + public void run() { + if (actor != null) { + vtkBoxRepresentation rep = (vtkBoxRepresentation) widget.GetRepresentation(); + rep.GetTransform(transform); + + double[] scale = transform.GetScale(); + double[] position = transform.GetPosition(); + + double scaleX = scale[0]; + double scaleY = scale[1]; + double scaleZ = scale[2]; + + double max = Math.max(scaleX, Math.max(scaleY, scaleZ)); + + vtkTransform newT = new vtkTransform(); +// newT. + newT.Scale(max, max, max); + + rep.SetTransform(newT); + } + + } + }; + + public void showWidget(vtkActor actor, DoubleField[] center, DoubleField radius, EventActionType action) { + this.actor = actor; + renderPanel.lock(); + if (action.equals(EventActionType.HIDE)) { + if (widget != null) { + widget.Off(); + removeListener(); + currentCenter = null; + currentRadius = null; + } + } else if (action.equals(EventActionType.SHOW)) { + removeListener(); + if (widget == null) { + createWidget(); + } + widget.On(); + currentCenter = center; + currentRadius = radius; + changePosition(); + addListener(); + } + renderPanel.unlock(); + renderPanel.renderLater(); + } + + private void createWidget() { + final vtkBoxRepresentation representation = new vtkBoxRepresentation(); + representation.SetPlaceFactor(1); + representation.PlaceWidget(actor.GetBounds()); + + widget = new vtkBoxWidget2(); + widget.AddObserver("EndInteractionEvent", callback, "run"); + widget.AddObserver("InteractionEvent", callback2, "run"); + + widget.SetRepresentation(representation); + widget.RotationEnabledOff(); + + renderPanel.getInteractor().addObserver(widget); + } + + public void clear() { + removeListener(); + renderPanel.lock(); + if (widget != null) { + // widget.RemoveAllObservers(); + widget.EnabledOff(); + widget.Delete(); + widget = null; + } + currentCenter = null; + currentRadius = null; + renderPanel.unlock(); + renderPanel.renderLater(); + } + + public void hideWidget() { + clear(); + } + + private void changePosition() { + if (currentCenter != null && currentRadius != null) { + double x = currentCenter[0].getDoubleValue(); + double y = currentCenter[1].getDoubleValue(); + double z = currentCenter[2].getDoubleValue(); + + double radius = currentRadius.getDoubleValue(); + + double minX = x - radius; + double maxX = x + radius; + + double minY = y - radius; + double maxY = y + radius; + + double minZ = z - radius; + double maxZ = z + radius; + + ((vtkBoxRepresentation) widget.GetRepresentation()).PlaceWidget(new double[] { minX, maxX, minY, maxY, minZ, maxZ }); + } + } + + private void addListener() { + if (currentCenter != null) { + currentCenter[0].addPropertyChangeListener(listener); + currentCenter[1].addPropertyChangeListener(listener); + currentCenter[2].addPropertyChangeListener(listener); + } + if (currentRadius != null) { + currentRadius.addPropertyChangeListener(listener); + } + } + + private void removeListener() { + if (currentCenter != null) { + currentCenter[0].removePropertyChangeListener(listener); + currentCenter[1].removePropertyChangeListener(listener); + currentCenter[2].removePropertyChangeListener(listener); + } + if (currentRadius != null) { + currentRadius.removePropertyChangeListener(listener); + } + } + + private final class BoxFieldListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("value")) { + changePosition(); + renderPanel.Render(); + } + } + } + +} diff --git a/src/vtk/vtkPanel.java b/src/vtk/vtkPanel.java new file mode 100644 index 0000000..56d319a --- /dev/null +++ b/src/vtk/vtkPanel.java @@ -0,0 +1,194 @@ +/*--------------------------------*- Java -*---------------------------------*\ + | o | + | o o | HelyxOS: The Open Source GUI for OpenFOAM | + | o O o | Copyright (C) 2012-2016 ENGYS | + | o o | http://www.engys.com | + | o | | + |---------------------------------------------------------------------------| + | License | + | This file is part of HelyxOS. | + | | + | HelyxOS 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. | + | | + | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, | + | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +\*---------------------------------------------------------------------------*/ + + +package vtk; + +import java.awt.Canvas; +import java.awt.Graphics; + +public class vtkPanel extends Canvas { + + private static final long serialVersionUID = 1L; + + protected vtkRenderWindow rw; + protected vtkRenderer ren; + protected vtkRenderer sren; + protected int windowset = 0; + protected boolean rendering = false; + + public void dispose() { + rendering = true; + + ren.RemoveAllLights(); + ren.RemoveAllObservers(); +// ren.RemoveAllProps(); + ren.RemoveAllViewProps(); + + rw.RemoveRenderer(ren); + + ren.Delete(); + rw.Delete(); + + ren = null; + rw = null; + + vtkObject.JAVA_OBJECT_MANAGER.deleteAll(); + + rw = new vtkRenderWindow(); + ren = new vtkRenderer(); + + rw.AddRenderer(ren); + windowset = 0; + rendering = false; + } + + public void Delete() { + if (rendering) { + return; + } + rendering = true; + // We prevent any further rendering + + if (this.getParent() != null) { + this.getParent().remove(this); + } + // Free internal VTK objects + ren = null; + // On linux we prefer to have a memory leak instead of a crash + if (!rw.GetClassName().equals("vtkXOpenGLRenderWindow")) { + rw = null; + } else { + System.out.println("The renderwindow has been kept arount to prevent a crash"); + } + } + + protected native int RenderCreate(vtkRenderWindow id0); + + protected native int Lock(); + + protected native int UnLock(); + + public vtkPanel() { + this.rw = new vtkRenderWindow(); + this.ren = new vtkRenderer(); + this.sren = new vtkRenderer(); + + + ren.SetLayer(0); + ren.InteractiveOn(); + + sren.SetLayer(1); + sren.InteractiveOff(); + + rw.SetNumberOfLayers(2); + rw.AddRenderer(ren); + rw.AddRenderer(sren); + + sren.SetActiveCamera(ren.GetActiveCamera()); + } + + public vtkRenderer GetRenderer() { + return ren; + } + + public vtkRenderer GetSelectionRenderer() { + return sren; + } + + public vtkRenderWindow GetRenderWindow() { + return rw; + } + + public void addNotify() { + super.addNotify(); + windowset = 0; + rendering = false; + rw.SetForceMakeCurrent(); + repaint(); + } + + public void removeNotify() { + if(windowset == 0) { + super.removeNotify(); + return; + } + if(rw != null) + { + Lock(); + rw.Finalize(); + UnLock(); + windowset = 0; + } + rendering = true; + super.removeNotify(); + } + + public synchronized void Render() { + if (!rendering) { + rendering = true; + if (rw != null) { + if (windowset == 0) { + createBufferStrategy(2); + // set the window id + RenderCreate(rw); + Lock(); + rw.SetSize(getWidth(), getHeight()); + UnLock(); + windowset = 1; + } + Lock(); + rw.Render(); + UnLock(); + } + rendering = false; + } + } + + public boolean isWindowSet() { + return (this.windowset == 1); + } + + public void paint(Graphics g) { + this.Render(); + } + + public void update(Graphics g) { + paint(g); + } + + public void resetCameraClippingRange() { + Lock(); + ren.ResetCameraClippingRange(); + UnLock(); + } + + public void resetCamera() { + Lock(); + ren.ResetCamera(); + UnLock(); + } + +}