/** * ORIPA - Origami Pattern Editor * Copyright (C) 2005-2009 Jun Mitani http://mitani.cs.tsukuba.ac.jp/ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package oripa.view.estimation; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.vecmath.Vector2d; import oripa.Config; import oripa.fold.OriFace; import oripa.fold.OriVertex; import oripa.fold.OrigamiModel; import oripa.paint.core.LineSetting; import oripa.paint.core.PaintConfig; import oripa.value.OriLine; /** * A screen to show whether Maekawa theorem and Kawasaki theorem holds. * @author Koji * */ public class FoldabilityScreen extends JPanel implements ComponentListener { private boolean bDrawFaceID = false; private Image bufferImage; private Graphics2D bufferg; private double scale; private double transX; private double transY; // Temporary information when editing private ArrayList<Vector2d> tmpOutline = new ArrayList<>(); // Contour line in the edit private boolean dispGrid = true; // Affine transformation information private Dimension preSize; private AffineTransform affineTransform = new AffineTransform(); private ArrayList<Vector2d> crossPoints = new ArrayList<>(); private JPopupMenu popup = new JPopupMenu(); private JMenuItem popupItem_DivideFace = new JMenuItem("Face division"); private JMenuItem popupItem_FlipFace = new JMenuItem("Face Inversion"); private OrigamiModel origamiModel = null; private Collection<OriLine> creasePattern = null; // private FoldedModelInfo foldedModelInfo = null; FoldabilityScreen() { addComponentListener(this); scale = 1.5; setBackground(Color.white); popup.add(popupItem_DivideFace); popup.add(popupItem_FlipFace); preSize = getSize(); } public void showModel( OrigamiModel origamiModel, Collection<OriLine> creasePattern //, FoldedModelInfo foldedModelInfo ) { this.origamiModel = origamiModel; this.creasePattern = creasePattern; // this.foldedModelInfo = foldedModelInfo; this.setVisible(true); } public void drawModel(Graphics2D g2d) { if (origamiModel == null) { return; } List<OriFace> faces = origamiModel.getFaces(); List<OriVertex> vertices = origamiModel.getVertices(); for (OriFace face : faces) { g2d.setColor(new Color(255, 210, 210)); g2d.fill(face.preOutline); } g2d.setColor(Color.RED); for (OriVertex v : vertices) { if (v.hasProblem) { g2d.fill(new Rectangle2D.Double(v.preP.x - 8.0 / scale, v.preP.y - 8.0 / scale, 16.0 / scale, 16.0 / scale)); } } if (bDrawFaceID) { g2d.setColor(Color.BLACK); for (OriFace face : faces) { g2d.drawString("" + face.tmpInt, (int) face.getCenter().x, (int) face.getCenter().y); } } if (Config.FOR_STUDY) { g2d.setColor(new Color(255, 210, 220)); for (OriFace face : faces) { if (face.tmpInt2 == 0) { g2d.setColor(Color.RED); g2d.fill(face.preOutline); } else { g2d.setColor(face.color); } if (face.hasProblem) { g2d.setColor(Color.RED); } else { if (face.faceFront) { g2d.setColor(new Color(255, 200, 200)); } else { g2d.setColor(new Color(200, 200, 255)); } } g2d.fill(face.preOutline); } g2d.setColor(Color.BLACK); for (OriFace face : faces) { g2d.drawString("" + face.z_order, (int) face.getCenter().x, (int) face.getCenter().y); } g2d.setColor(Color.RED); for (OriVertex v : vertices) { if (v.hasProblem) { g2d.fill(new Rectangle2D.Double(v.p.x - 8.0 / scale, v.p.y - 8.0 / scale, 16.0 / scale, 16.0 / scale)); } } } } // To update the current AffineTransform private void updateAffineTransform() { affineTransform.setToIdentity(); affineTransform.translate(getWidth() * 0.5, getHeight() * 0.5); affineTransform.scale(scale, scale); affineTransform.translate(transX, transY); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); if (bufferImage == null) { bufferImage = createImage(getWidth(), getHeight()); bufferg = (Graphics2D) bufferImage.getGraphics(); updateAffineTransform(); preSize = getSize(); } bufferg.setTransform(new AffineTransform()); bufferg.setColor(Color.WHITE); bufferg.fillRect(0, 0, getWidth(), getHeight()); bufferg.setTransform(affineTransform); Graphics2D g2d = bufferg; g2d.setStroke(LineSetting.STROKE_VALLEY); g2d.setColor(Color.black); for (OriLine line : creasePattern) { switch (line.typeVal) { case OriLine.TYPE_NONE: if (!PaintConfig.dispAuxLines) { continue; } g2d.setColor(LineSetting.LINE_COLOR_AUX); g2d.setStroke(LineSetting.STROKE_CUT); break; case OriLine.TYPE_CUT: g2d.setColor(Color.BLACK); g2d.setStroke(LineSetting.STROKE_CUT); break; case OriLine.TYPE_RIDGE: if (!PaintConfig.dispMVLines) { continue; } g2d.setColor(LineSetting.LINE_COLOR_RIDGE); g2d.setStroke(LineSetting.STROKE_RIDGE); break; case OriLine.TYPE_VALLEY: if (!PaintConfig.dispMVLines) { continue; } g2d.setColor(LineSetting.LINE_COLOR_VALLEY); g2d.setStroke(LineSetting.STROKE_VALLEY); break; } g2d.draw(new Line2D.Double(line.p0.x, line.p0.y, line.p1.x, line.p1.y)); } // Drawing of the vertices List<OriVertex> vertices = origamiModel.getVertices(); for (OriVertex v : vertices) { double vertexDrawSize = 2.0; g2d.setColor(Color.BLACK); if (v.hasProblem) { vertexDrawSize = 5.0; g2d.setColor(Color.RED); } g2d.fill(new Rectangle2D.Double(v.preP.x - vertexDrawSize / scale, v.preP.y - vertexDrawSize / scale, vertexDrawSize * 2 / scale, vertexDrawSize * 2 / scale)); } for (Vector2d v : crossPoints) { g2d.setColor(Color.RED); g2d.fill(new Rectangle2D.Double(v.x - 5.0 / scale, v.y - 5.0 / scale, 10.0 / scale, 10.0 / scale)); } // Line connecting the pair of unsetled faces // if (Config.FOR_STUDY) { // List<OriFace> faces = origamiModel.getFaces(); // // int[][] overlapRelation = foldedModelInfo.getOverlapRelation(); // // if (overlapRelation != null) { // g2d.setStroke(LineSetting.STROKE_RIDGE); // g2d.setColor(Color.MAGENTA); // int size = faces.size(); // for (int i = 0; i < size; i++) { // for (int j = i + 1; j < size; j++) { // if (overlapRelation[i][j] == Doc.UNDEFINED) { // Vector2d v0 = faces.get(i).getCenter(); // Vector2d v1 = faces.get(j).getCenter(); // g2d.draw(new Line2D.Double(v0.x, v0.y, v1.x, v1.y)); // // } // } // } // } // } drawModel(g2d); g.drawImage(bufferImage, 0, 0, this); } public void setDispGrid(boolean dispGrid) { this.dispGrid = dispGrid; resetPickElements(); repaint(); } public void modeChanged() { repaint(); } public void resetPickElements() { crossPoints.clear(); tmpOutline.clear(); } @Override public void componentResized(ComponentEvent arg0) { if (getWidth() <= 0 || getHeight() <= 0) { return; } preSize = getSize(); // Update of the logical coordinates of the center of the screen transX = transX - preSize.width * 0.5 + getWidth() * 0.5; transY = transY - preSize.height * 0.5 + getHeight() * 0.5; // Updating the image buffer bufferImage = createImage(getWidth(), getHeight()); bufferg = (Graphics2D) bufferImage.getGraphics(); updateAffineTransform(); repaint(); } @Override public void componentMoved(ComponentEvent arg0) { // TODO Auto-generated method stub } @Override public void componentShown(ComponentEvent arg0) { // TODO Auto-generated method stub } @Override public void componentHidden(ComponentEvent arg0) { // TODO Auto-generated method stub } }