/** * This file is part of VisiCut. * Copyright (C) 2011 - 2013 Thomas Oster <thomas.oster@rwth-aachen.de> * RWTH Aachen University - 52062 Aachen, Germany * * VisiCut is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VisiCut is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with VisiCut. If not, see <http://www.gnu.org/licenses/>. **/ /* * CamCalibrationDialog.java * * Created on 28.08.2011, 15:35:33 */ package com.t_oster.visicut.gui; import com.t_oster.liblasercut.LaserCutter; import com.t_oster.liblasercut.LaserJob; import com.t_oster.liblasercut.LaserProperty; import com.t_oster.liblasercut.VectorPart; import com.t_oster.liblasercut.platform.Util; import com.t_oster.visicut.VisicutModel; import com.t_oster.visicut.managers.LaserPropertyManager; import com.t_oster.visicut.misc.Helper; import com.t_oster.visicut.model.LaserDevice; import com.t_oster.visicut.model.VectorProfile; import com.t_oster.uicomponents.PlatformIcon; import java.awt.event.MouseWheelEvent; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.JOptionPane; /** * * @author Thomas Oster <thomas.oster@rwth-aachen.de> */ public class CamCalibrationDialog extends javax.swing.JDialog { protected String imageURL = null; /** * Get the value of imageURL * * @return the value of imageURL */ public String getImageURL() { return imageURL; } /** * Set the value of imageURL * * @param imageURL new value of imageURL */ public void setImageURL(String imageURL) { this.imageURL = imageURL; } protected BufferedImage backgroundImage = null; public static final String PROP_BACKGROUNDIMAGE = "backgroundImage"; private LaserDevice ld = VisicutModel.getInstance().getSelectedLaserDevice(); private Point2D.Double laserUpperLeft = new Point2D.Double(0.2d*ld.getLaserCutter().getBedWidth(), 0.2d*ld.getLaserCutter().getBedHeight()); private Point2D.Double laserLowerRight = new Point2D.Double(0.8d*ld.getLaserCutter().getBedWidth(), 0.8d*ld.getLaserCutter().getBedHeight()); /** * Get the value of backgroundImage * * @return the value of backgroundImage */ public BufferedImage getBackgroundImage() { return backgroundImage; } /** * Set the value of backgroundImage * * @param backgroundImage new value of backgroundImage */ public void setBackgroundImage(BufferedImage backgroundImage) { this.backgroundImage = backgroundImage; this.calibrationPanel1.setBackgroundImage(backgroundImage); //Check if a point is not in the Image (thus not reachable anymore) for (Point2D.Double p :this.calibrationPanel1.getPointList()) { if (p.x >= backgroundImage.getWidth() || p.y >= backgroundImage.getHeight()) { calibrationPanel1.setPointList(new Point2D.Double[]{ new Point2D.Double(20*backgroundImage.getWidth()/100,20*backgroundImage.getHeight()/100), new Point2D.Double(80*backgroundImage.getWidth()/100,80*backgroundImage.getHeight()/100) }); break; } } } protected AffineTransform currentTransformation = currentTransformation = AffineTransform.getScaleInstance(0.01, 0.01); public static final String PROP_CURRENTTRANSFORMATION = "currentTransformation"; private void refreshImagePoints() { Point2D.Double imageUpperLeft = (Point2D.Double) laserUpperLeft.clone(); Point2D.Double imageLowerRight = (Point2D.Double) laserLowerRight.clone(); if (this.getResultingTransformation() != null) { try { AffineTransform img2mm = this.getResultingTransformation(); AffineTransform mm2img = img2mm.createInverse(); mm2img.transform(imageUpperLeft, imageUpperLeft); mm2img.transform(imageLowerRight, imageLowerRight); this.calibrationPanel1.setPointList(new Point2D.Double[] { imageUpperLeft, imageLowerRight }); } catch (NoninvertibleTransformException ex) { Logger.getLogger(CamCalibrationDialog.class.getName()).log(Level.SEVERE, null, ex); } } } /** * Get the value of currentTransformation * * @return the value of currentTransformation */ public AffineTransform getCurrentTransformation() { Point2D.Double[] img = this.calibrationPanel1.getPointList(); return Helper.getTransform( new Rectangle2D.Double(img[0].x, img[0].y, img[1].x - img[0].x, img[1].y - img[0].y), new Rectangle2D.Double(laserUpperLeft.x, laserUpperLeft.y, laserLowerRight.x - laserUpperLeft.x, laserLowerRight.y - laserUpperLeft.y) ); } protected AffineTransform resultingTransformation = null; public static final String PROP_RESULTINGTRANSFORMATION = "resultingTransformation"; /** * Get the value of resultingTransformation * * @return the value of resultingTransformation */ public AffineTransform getResultingTransformation() { return resultingTransformation; } private VectorProfile profile = null; public void setVectorProfile(VectorProfile p) { this.profile = p; } /** * Set the value of resultingTransformation * * @param resultingTransformation new value of resultingTransformation */ public void setResultingTransformation(AffineTransform resultingTransformation) { AffineTransform oldResultingTransformation = this.resultingTransformation; this.resultingTransformation = resultingTransformation != null ? resultingTransformation : new AffineTransform(); firePropertyChange(PROP_RESULTINGTRANSFORMATION, oldResultingTransformation, resultingTransformation); this.refreshImagePoints(); } public CamCalibrationDialog() { this(null, true); } /** Creates new form CamCalibrationDialog */ public CamCalibrationDialog(java.awt.Frame parent, boolean modal) { super(parent, modal); initComponents(); LaserCutter lc = VisicutModel.getInstance().getSelectedLaserDevice().getLaserCutter(); this.calibrationPanel1.setAreaSize(new Point2D.Double(lc.getBedWidth(), lc.getBedHeight())); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { bindingGroup = new org.jdesktop.beansbinding.BindingGroup(); okButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); sendButton = new javax.swing.JButton(); captureButton = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); calibrationPanel1 = new com.t_oster.visicut.gui.beans.CalibrationPanel(); btZoomIn = new javax.swing.JButton(); btZoomOut = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("com/t_oster/visicut/gui/resources/CamCalibrationDialog"); // NOI18N setTitle(bundle.getString("TITLE")); // NOI18N setName("Form"); // NOI18N org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(com.t_oster.visicut.gui.VisicutApp.class).getContext().getResourceMap(CamCalibrationDialog.class); okButton.setText(resourceMap.getString("okButton.text")); // NOI18N okButton.setName("okButton"); // NOI18N okButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { okButtonActionPerformed(evt); } }); cancelButton.setText(resourceMap.getString("cancelButton.text")); // NOI18N cancelButton.setName("cancelButton"); // NOI18N cancelButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { cancelButtonActionPerformed(evt); } }); sendButton.setText(resourceMap.getString("sendButton.text")); // NOI18N sendButton.setName("sendButton"); // NOI18N sendButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { sendButtonActionPerformed(evt); } }); captureButton.setIcon(PlatformIcon.get(PlatformIcon.CAMERA)); captureButton.setText(resourceMap.getString("captureButton.text")); // NOI18N captureButton.setName("captureButton"); // NOI18N captureButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { captureButtonActionPerformed(evt); } }); jScrollPane1.setBorder(javax.swing.BorderFactory.createTitledBorder("Preview")); jScrollPane1.setName("jScrollPane1"); // NOI18N calibrationPanel1.setName("calibrationPanel1"); // NOI18N org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ, this, org.jdesktop.beansbinding.ELProperty.create("${laserCam.capturedImage}"), calibrationPanel1, org.jdesktop.beansbinding.BeanProperty.create("backgroundImage"), "CamImageToPanel"); bindingGroup.addBinding(binding); calibrationPanel1.addMouseWheelListener(new java.awt.event.MouseWheelListener() { public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt) { calibrationPanel1MouseWheelMoved(evt); } }); javax.swing.GroupLayout calibrationPanel1Layout = new javax.swing.GroupLayout(calibrationPanel1); calibrationPanel1.setLayout(calibrationPanel1Layout); calibrationPanel1Layout.setHorizontalGroup( calibrationPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 960, Short.MAX_VALUE) ); calibrationPanel1Layout.setVerticalGroup( calibrationPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 409, Short.MAX_VALUE) ); jScrollPane1.setViewportView(calibrationPanel1); btZoomIn.setIcon(PlatformIcon.get(PlatformIcon.ZOOM_IN)); btZoomIn.setText(resourceMap.getString("btZoomIn.text")); // NOI18N btZoomIn.setName("btZoomIn"); // NOI18N btZoomIn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btZoomInActionPerformed(evt); } }); btZoomOut.setIcon(PlatformIcon.get(PlatformIcon.ZOOM_OUT)); btZoomOut.setText(resourceMap.getString("btZoomOut.text")); // NOI18N btZoomOut.setName("btZoomOut"); // NOI18N btZoomOut.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btZoomOutActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(btZoomOut, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btZoomIn, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(captureButton) .addContainerGap()) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addComponent(sendButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(cancelButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 818, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(captureButton, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btZoomIn, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btZoomOut, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 448, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(okButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(cancelButton) .addComponent(sendButton)) .addGap(17, 17, 17)) ); bindingGroup.bind(); pack(); }// </editor-fold>//GEN-END:initComponents private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed this.setResultingTransformation(this.getCurrentTransformation()); this.setVisible(false); }//GEN-LAST:event_okButtonActionPerformed private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed this.refreshImagePoints(); this.setVisible(false); }//GEN-LAST:event_cancelButtonActionPerformed private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendButtonActionPerformed try { VisicutModel vm = VisicutModel.getInstance(); LaserDevice laserDevice = vm.getSelectedLaserDevice(); if (laserDevice == null) { throw new Exception(java.util.ResourceBundle.getBundle("com/t_oster/visicut/gui/resources/CamCalibrationDialog").getString("NO LASERCUTTER SELECTED")); } VectorPart vp = null; for (LaserProperty lp : LaserPropertyManager.getInstance().getLaserProperties(laserDevice, vm.getMaterial(), profile, vm.getMaterialThickness())) { if (vp == null) { vp = new VectorPart(lp, profile.getDPI()); } else { vp.setProperty(lp); } int size = (int) Util.mm2px(10, profile.getDPI()); for (Point2D p : new Point2D[] { laserUpperLeft, laserLowerRight }) { int x = (int) Util.mm2px(p.getX(), profile.getDPI()); int y = (int) Util.mm2px(p.getY(), profile.getDPI()); vp.moveto(x - size / 2, y); vp.lineto(x + size / 2, y); vp.moveto(x, y - size / 2); vp.lineto(x, y + size / 2); } } LaserJob job = new LaserJob(java.util.ResourceBundle.getBundle("com/t_oster/visicut/gui/resources/CamCalibrationDialog").getString("CALIBRATION"), java.util.ResourceBundle.getBundle("com/t_oster/visicut/gui/resources/CamCalibrationDialog").getString("VISICUT CALIBRATION PAGE"), "visicut"); job.addPart(vp); laserDevice.getLaserCutter().sendJob(job); JOptionPane.showMessageDialog(this, java.util.ResourceBundle.getBundle("com/t_oster/visicut/gui/resources/CamCalibrationDialog").getString("PLEASE PRESS 'START' ON THE LASERCUTTER")); } catch (Exception e) { JOptionPane.showMessageDialog(this, java.util.ResourceBundle.getBundle("com/t_oster/visicut/gui/resources/CamCalibrationDialog").getString("ERROR SENDING PAGE: ") + e.getLocalizedMessage(), java.util.ResourceBundle.getBundle("com/t_oster/visicut/gui/resources/CamCalibrationDialog").getString("ERROR"), JOptionPane.ERROR_MESSAGE); } }//GEN-LAST:event_sendButtonActionPerformed private void calibrationPanel1MouseWheelMoved(java.awt.event.MouseWheelEvent evt) {//GEN-FIRST:event_calibrationPanel1MouseWheelMoved if (evt.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { this.calibrationPanel1.setZoom(this.calibrationPanel1.getZoom() - (evt.getUnitsToScroll() * this.calibrationPanel1.getZoom() / 32)); } }//GEN-LAST:event_calibrationPanel1MouseWheelMoved private void captureButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_captureButtonActionPerformed new Thread() { @Override public void run() { CamCalibrationDialog.this.captureButton.setEnabled(false); try { URL src = new URL(imageURL); if (src != null) { BufferedImage back = ImageIO.read(src); CamCalibrationDialog.this.setBackgroundImage(back); } } catch (Exception ex) { JOptionPane.showMessageDialog(CamCalibrationDialog.this, java.util.ResourceBundle.getBundle("com/t_oster/visicut/gui/resources/CamCalibrationDialog").getString("ERROR LOADING IMAGE:") + ex.getLocalizedMessage(), java.util.ResourceBundle.getBundle("com/t_oster/visicut/gui/resources/CamCalibrationDialog").getString("ERROR"), JOptionPane.ERROR_MESSAGE); } CamCalibrationDialog.this.captureButton.setEnabled(true); } }.start(); }//GEN-LAST:event_captureButtonActionPerformed private void btZoomInActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btZoomInActionPerformed {//GEN-HEADEREND:event_btZoomInActionPerformed calibrationPanel1.setZoom(calibrationPanel1.getZoom() - (-2 * calibrationPanel1.getZoom() / 32)); }//GEN-LAST:event_btZoomInActionPerformed private void btZoomOutActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btZoomOutActionPerformed {//GEN-HEADEREND:event_btZoomOutActionPerformed calibrationPanel1.setZoom(calibrationPanel1.getZoom() - (2 * calibrationPanel1.getZoom() / 32)); }//GEN-LAST:event_btZoomOutActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btZoomIn; private javax.swing.JButton btZoomOut; private com.t_oster.visicut.gui.beans.CalibrationPanel calibrationPanel1; private javax.swing.JButton cancelButton; private javax.swing.JButton captureButton; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JButton okButton; private javax.swing.JButton sendButton; private org.jdesktop.beansbinding.BindingGroup bindingGroup; // End of variables declaration//GEN-END:variables }