/**
* 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.doc;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.vecmath.Vector2d;
import oripa.ORIPA;
import oripa.fold.FoldedModelInfo;
import oripa.fold.OriFace;
import oripa.fold.OriHalfedge;
import oripa.fold.OrigamiModel;
import oripa.geom.GeomUtil;
import oripa.paint.core.PaintConfig;
import oripa.paint.creasepattern.CreasePattern;
import oripa.paint.creasepattern.tool.LineAdder;
import oripa.resource.Constants;
import oripa.value.OriLine;
public class Doc {
// class PointComparatorX implements Comparator<Vector2d> {
//
// @Override
// public int compare(Vector2d v1, Vector2d v2) {
// if(v1.x == v2.x){
// return 0;
// }
// return v1.x > v2.x ? 1 : -1;
// }
// }
//
// class PointComparatorY implements Comparator<Vector2d> {
//
// @Override
// public int compare(Vector2d v1, Vector2d v2) {
// if(v1.y == v2.y){
// return 0;
// }
// return ((Vector2d) v1).y > ((Vector2d) v2).y ? 1 : -1;
// }
// }
//
// class FaceOrderComparator implements Comparator<OriFace> {
//
// @Override
// public int compare(OriFace f1, OriFace f2) {
// return f1.z_order > f2.z_order ? 1 : -1;
// }
// }
private double paperSize;
// Crease Pattern
private CreasePattern creasePattern = null;
private ArrayList<OriLine> crossLines = new ArrayList<OriLine>();
// Origami Model for Estimation
private OrigamiModel origamiModel = null;
// Folded Model Information (Result of Estimation)
private FoldedModelInfo foldedModelInfo = null;
final public static int NO_OVERLAP = 0;
final public static int UPPER = 1;
final public static int LOWER = 2;
final public static int UNDEFINED = 9;
// Project data
private String dataFilePath = "";
private String title;
private String editorName;
private String originalAuthorName;
private String reference;
public String memo;
private UndoManager<UndoInfo> undoManager = new UndoManager<>(30);
int debugCount = 0;
public Doc(){
initialize(Constants.DEFAULT_PAPER_SIZE);
}
public Doc(double size) {
initialize(size);
}
private void initialize(double size){
this.paperSize = size;
creasePattern = new CreasePattern(size);
OriLine l0 = new OriLine(-size / 2.0, -size / 2.0, size / 2.0, -size / 2.0, OriLine.TYPE_CUT);
OriLine l1 = new OriLine(size / 2.0, -size / 2.0, size / 2.0, size / 2.0, OriLine.TYPE_CUT);
OriLine l2 = new OriLine(size / 2.0, size / 2.0, -size / 2.0, size / 2.0, OriLine.TYPE_CUT);
OriLine l3 = new OriLine(-size / 2.0, size / 2.0, -size / 2.0, -size / 2.0, OriLine.TYPE_CUT);
creasePattern.add(l0);
creasePattern.add(l1);
creasePattern.add(l2);
creasePattern.add(l3);
origamiModel = new OrigamiModel(size);
foldedModelInfo = new FoldedModelInfo();
}
public void setDataFilePath(String path){
this.dataFilePath = path;
}
public String getDataFilePath(){
return dataFilePath;
}
public String getDataFileName(){
File file = new File(ORIPA.doc.dataFilePath);
String fileName = file.getName();
return fileName;
}
public UndoInfo createUndoInfo(){
UndoInfo undoInfo = new UndoInfo(creasePattern);
return undoInfo;
}
public void cacheUndoInfo(){
undoManager.setCache(createUndoInfo());
}
public void pushCachedUndoInfo(){
undoManager.pushCachedInfo();
}
public void pushUndoInfo() {
UndoInfo ui = new UndoInfo(creasePattern);
undoManager.push(ui);
}
public void pushUndoInfo(UndoInfo uinfo){
undoManager.push(uinfo);
}
public void loadUndoInfo() {
UndoInfo info = undoManager.pop();
if(info == null){
return;
}
creasePattern.clear();
creasePattern.addAll(info.getLines());
}
public boolean canUndo(){
return undoManager.canUndo();
}
public boolean isChanged(){
return undoManager.isChanged();
}
public void clearChanged(){
undoManager.clearChanged();
}
// public void CircleCopy(double cx, double cy, double angleDeg, int num) {
// ArrayList<OriLine> copiedLines = new ArrayList<OriLine>();
//
//
// oripa.geom.RectangleClipper clipper =
// new oripa.geom.RectangleClipper(
// -paperSize / 2, -paperSize / 2, paperSize / 2, paperSize / 2);
//
// double angle = angleDeg * Math.PI / 180.0;
//
// for (int i = 0; i < num; i++) {
// double angleRad = angle * (i + 1);
// for (OriLine l : creasePattern) {
// if (!l.selected) {
// continue;
// }
//
// OriLine cl = new OriLine(l);
// double tx0 = l.p0.x - cx;
// double ty0 = l.p0.y - cy;
// double tx1 = l.p1.x - cx;
// double ty1 = l.p1.y - cy;
//
// double ttx0 = tx0 * Math.cos(angleRad) - ty0 * Math.sin(angleRad);
// double tty0 = tx0 * Math.sin(angleRad) + ty0 * Math.cos(angleRad);
//
// double ttx1 = tx1 * Math.cos(angleRad) - ty1 * Math.sin(angleRad);
// double tty1 = tx1 * Math.sin(angleRad) + ty1 * Math.cos(angleRad);
//
// cl.p0.x = ttx0 + cx;
// cl.p0.y = tty0 + cy;
// cl.p1.x = ttx1 + cx;
// cl.p1.y = tty1 + cy;
//
// if (clipper.clip(cl)) {
// copiedLines.add(cl);
// }
// }
// }
// for (OriLine l : copiedLines) {
// addLine(l);
// }
//
// Painter painter = new Painter();
// painter.resetSelectedOriLines(creasePattern);
// }
// // v1-v2 is the symmetry line, v0-v1 is the sbject to be copied.
// // automatically generates possible rebouncing of the fold (used when Ctrl is pressed)
// public void addSymmetricLineAutoWalk(Vector2d v0, Vector2d v1, Vector2d v2, int stepCount, Vector2d startV) {
// stepCount++;
// if (stepCount > 36) {
// return;
// }
// Vector2d v3 = GeomUtil.getSymmetricPoint(v0, v1, v2);
// Ray ray = new Ray(v1, new Vector2d(v3.x - v1.x, v3.y - v1.y));
//
// double minDist = Double.MAX_VALUE;
// Vector2d bestPoint = null;
// OriLine bestLine = null;
// for (OriLine l : creasePattern) {
// Vector2d crossPoint = GeomUtil.getCrossPoint(ray, l.getSegment());
// if (crossPoint == null) {
// continue;
// }
// double distance = GeomUtil.Distance(crossPoint, v1);
// if (distance < CalculationResource.POINT_EPS) {
// continue;
// }
//
// if (distance < minDist) {
// minDist = distance;
// bestPoint = crossPoint;
// bestLine = l;
// }
// }
//
// if (bestPoint == null) {
// return;
// }
//
// addLine(new OriLine(v1, bestPoint, PaintConfig.inputLineType));
//
// if (GeomUtil.Distance(bestPoint, startV) < CalculationResource.POINT_EPS) {
// return;
// }
//
// addSymmetricLineAutoWalk(v1, bestPoint, bestLine.p0, stepCount, startV);
//
// }
public void addLine(OriLine inputLine) {
LineAdder lineAdder = new LineAdder();
lineAdder.addLine(inputLine, creasePattern);
}
public void setCrossLine(OriLine line) {
crossLines.clear();
List<OriFace> sortedFaces = origamiModel.getSortedFaces();
for (OriFace face : sortedFaces) {
ArrayList<Vector2d> vv = new ArrayList<Vector2d>();
int crossCount = 0;
for (OriHalfedge he : face.halfedges) {
OriLine l = new OriLine(he.positionForDisplay.x, he.positionForDisplay.y,
he.next.positionForDisplay.x, he.next.positionForDisplay.y, PaintConfig.inputLineType);
double params[] = new double[2];
boolean res = GeomUtil.getCrossPointParam(line.p0, line.p1, l.p0, l.p1, params);
if (res == true && params[0] > -0.001 && params[1] > -0.001 && params[0] < 1.001 && params[1] < 1.001) {
double param = params[1];
crossCount++;
Vector2d crossV = new Vector2d();
crossV.x = (1.0 - param) * he.vertex.preP.x + param * he.next.vertex.preP.x;
crossV.y = (1.0 - param) * he.vertex.preP.y + param * he.next.vertex.preP.y;
boolean isNewPoint = true;
for (Vector2d v2d : vv) {
if (GeomUtil.Distance(v2d, crossV) < 1) {
isNewPoint = false;
break;
}
}
if (isNewPoint) {
vv.add(crossV);
}
}
}
if (vv.size() >= 2) {
crossLines.add(new OriLine(vv.get(0), vv.get(1), PaintConfig.inputLineType));
}
}
}
public Collection<Vector2d> getVerticesAround(Vector2d v){
return creasePattern.getVerticesAround(v);
}
public Collection<Collection<Vector2d>> getVerticesArea(
double x, double y, double distance){
return creasePattern.getVerticesArea(x, y, distance);
}
public CreasePattern getCreasePattern(){
return creasePattern;
}
/**
* @return origamiModel
*/
public OrigamiModel getOrigamiModel() {
return origamiModel;
}
/**
* @param origamiModel origamiModel is set to this instance.
*/
public void setOrigamiModel(OrigamiModel origamiModel) {
this.origamiModel = origamiModel;
}
/**
* @return foldedModelInfo
*/
public FoldedModelInfo getFoldedModelInfo() {
return foldedModelInfo;
}
/**
* @param foldedModelInfo foldedModelInfo is set to this instance.
*/
public void setFoldedModelInfo(FoldedModelInfo foldedModelInfo) {
this.foldedModelInfo = foldedModelInfo;
}
//======================================================================
// Getter/Setter eventually unnecessary
/**
* @return crossLines
*/
public ArrayList<OriLine> getCrossLines() {
return crossLines;
}
/**
* @param crossLines crossLines is set to this instance.
*/
public void setCrossLines(ArrayList<OriLine> crossLines) {
this.crossLines = crossLines;
}
//-------------------------------------------------------------
// moved to OrigamiModel
// /**
// * @return faces
// */
// public List<OriFace> getFaces() {
// List<OriFace> faces = origamiModel.getFaces();
// return faces;
// }
//
// /**
// * @param faces faces is set to this instance.
// */
// public void setFaces(List<OriFace> faces) {
// origamiModel.setFaces(faces);
// }
//
// /**
// * @return edges
// */
// public List<OriEdge> getEdges() {
// List<OriEdge> edges = origamiModel.getEdges();
//
// return edges;
// }
//
//
// /**
// * @return vertices
// */
// public List<OriVertex> getVertices() {
// List<OriVertex> vertices = origamiModel.getVertices();
//
// return vertices;
// }
//
// /**
// * @param vertices vertices is set to this instance.
// */
// public void setVertices(List<OriVertex> vertices) {
// origamiModel.setVertices(vertices);;
// }
//
// /**
// * @param edges edges is set to this instance.
// */
// public void setEdges(ArrayList<OriEdge> edges) {
// origamiModel.setEdges(edges);
// }
//
// /**
// * @return isValidPattern
// */
// public boolean isValidPattern() {
//
// return origamiModel.isValidPattern();
// }
//
// /**
// * @param isValidPattern isValidPattern is set to this instance.
// */
// public void setValidPattern(boolean isValidPattern) {
// origamiModel.setValidPattern(isValidPattern);
// }
//
// /**
// * @return hasModel
// */
// public boolean hasModel() {
// return origamiModel.hasModel();
// }
//
//// /**
//// * @param hasModel hasModel is set to this instance.
//// */
//// public void setHasModel(boolean hasModel) {
//// this.hasModel = hasModel;
//// }
//
// /**
// * @return sortedFaces
// */
// public List<OriFace> getSortedFaces() {
// List<OriFace> sortedFaces = origamiModel.getSortedFaces();
// return sortedFaces;
// }
//
// /**
// * @param sortedFaces sortedFaces is set to this instance.
// */
// public void setSortedFaces(List<OriFace> sortedFaces) {
// origamiModel.setSortedFaces(sortedFaces);
// }
//
// /**
// * @return folded
// */
// public boolean isFolded() {
// return origamiModel.isFolded();
// }
//
// /**
// * @param folded folded is set to this instance.
// */
// public void setFolded(boolean folded) {
// origamiModel.setFolded(folded);
// }
//-------------------------------------------------------------
// /**
// * @return currentORmatIndex
// */
// public int getCurrentORmatIndex() {
// int currentORmatIndex = foldedModelInfo.getCurrentORmatIndex();
//
// return currentORmatIndex;
// }
//
// /**
// * @param currentORmatIndex currentORmatIndex is set to this instance.
// */
// public void setCurrentORmatIndex(int currentORmatIndex) {
// foldedModelInfo.setCurrentORmatIndex(currentORmatIndex);
// }
//
// /**
// * @return foldedBBoxLT
// */
// public Vector2d getFoldedBBoxLT() {
// return foldedModelInfo.getBoundBox().getLeftAndTop();
// }
//
//
// /**
// * @return foldedBBoxRB
// */
// public Vector2d getFoldedBBoxRB() {
// return foldedModelInfo.getBoundBox().getRightAndBottom();
// }
//
//
//
//
// /**
// * @return overlapRelation
// */
// public int[][] getOverlapRelation() {
// int[][] overlapRelation = foldedModelInfo.getOverlapRelation();
// return overlapRelation;
// }
//
// /**
// * @param overlapRelation overlapRelation is set to this instance.
// */
// public void setOverlapRelation(int[][] overlapRelation) {
// foldedModelInfo.setOverlapRelation(overlapRelation);
// }
//
// /**
// * @return foldableOverlapRelations
// */
// public List<int[][]> getFoldableOverlapRelations() {
// List<int[][]> foldableOverlapRelations = foldedModelInfo.getFoldableOverlapRelations();
//
// return foldableOverlapRelations;
// }
//
// /**
// * @param foldableOverlapRelations foldableOverlapRelations is set to this instance.
// */
// public void setFoldableOverlapRelations(
// List<int[][]> foldableOverlapRelations) {
//
// foldedModelInfo.setFoldableOverlapRelations(foldableOverlapRelations);
// }
/**
* @param size size is set to this instance.
*/
public void setPaperSize(double size) {
this.paperSize = size;
origamiModel.setPaperSize(size);
creasePattern.changePaperSize(size);
}
/**
* @return size
*/
public double getPaperSize() {
return paperSize;
}
/**
* @return title
*/
public String getTitle() {
return title;
}
/**
* @param title title is set to this instance.
*/
public void setTitle(String title) {
this.title = title;
}
/**
* @return editorName
*/
public String getEditorName() {
return editorName;
}
/**
* @param editorName editorName is set to this instance.
*/
public void setEditorName(String editorName) {
this.editorName = editorName;
}
/**
* @return originalAuthorName
*/
public String getOriginalAuthorName() {
return originalAuthorName;
}
/**
* @param originalAuthorName originalAuthorName is set to this instance.
*/
public void setOriginalAuthorName(String originalAuthorName) {
this.originalAuthorName = originalAuthorName;
}
/**
* @return memo
*/
public String getMemo() {
return memo;
}
/**
* @param memo memo is set to this instance.
*/
public void setMemo(String memo) {
this.memo = memo;
}
/**
* @return reference
*/
public String getReference() {
return reference;
}
/**
* @param reference reference is set to this instance.
*/
public void setReference(String reference) {
this.reference = reference;
}
}