/**
*
*/
package cz.cuni.mff.peckam.java.origamist.model;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import cz.cuni.mff.peckam.java.origamist.math.Line2d;
import cz.cuni.mff.peckam.java.origamist.math.Segment3d;
import cz.cuni.mff.peckam.java.origamist.model.jaxb.Operations;
import cz.cuni.mff.peckam.java.origamist.modelstate.Direction;
import cz.cuni.mff.peckam.java.origamist.modelstate.LayerFilter;
import cz.cuni.mff.peckam.java.origamist.modelstate.ModelPoint;
import cz.cuni.mff.peckam.java.origamist.modelstate.ModelSegment;
import cz.cuni.mff.peckam.java.origamist.modelstate.ModelState;
import cz.cuni.mff.peckam.java.origamist.modelstate.arguments.LayersArgument;
import cz.cuni.mff.peckam.java.origamist.modelstate.arguments.LineArgument;
import cz.cuni.mff.peckam.java.origamist.modelstate.arguments.OperationArgument;
/**
* Valley or mountain fold and unfold.
*
* @author Martin Pecka
*/
public class FoldUnfoldOperation extends cz.cuni.mff.peckam.java.origamist.model.jaxb.FoldUnfoldOperation implements
HasSymmetricOperation
{
/** P1 is the center of rotation segment, P2 is the furthest rotated point in the last getModelState() call. */
protected Segment3d markerPosition = null;
@Override
public ModelState getModelState(ModelState previousState)
{
Direction dir = Direction.MOUNTAIN;
if (this.type == Operations.VALLEY_MOUNTAIN_FOLD_UNFOLD)
dir = dir.getOpposite();
previousState.setFurthestRotationSegment(getLine().toSegment2d());
previousState.makeFold(dir, getLine().getStart().toPoint2d(), getLine().getEnd().toPoint2d(), null,
new LayerFilter(layer), 0);
// TODO doesn't work because bendPaper() is skipped
ModelPoint furthest = previousState.getFurthestRotatedPointAroundSegment();
if (furthest != null)
markerPosition = new Segment3d(furthest, previousState.getFurthestRotationSegment().getNearestPoint(
furthest));
previousState.clearFurthestRotationSegment();
// workaround for bendPaper() not bending paper for 0° angle
ModelSegment seg = new ModelSegment(new Segment3d(previousState.locatePointFromPaperTo3D(getLine().getStart()
.toPoint2d()), previousState.locatePointFromPaperTo3D(getLine().getEnd().toPoint2d())), getLine()
.toSegment2d());
Vector3d normal = previousState.getSegmentNormal(seg);
Vector3d cross = new Vector3d();
cross.cross(seg.getVector(), normal);
cross.normalize();
cross.scale(0.15);
Point3d end = seg.getPointForParameter(0.5);
Point3d start = new Point3d(end);
start.sub(cross);
markerPosition = new Segment3d(start, end);
return previousState;
}
@Override
protected List<OperationArgument> initArguments()
{
List<OperationArgument> result = new ArrayList<OperationArgument>(3);
LineArgument line;
result.add(line = new LineArgument(true, "operation.argument.select.line"));
result.add(new LayersArgument(line, true, "operation.argument.select.layers"));
return result;
}
@Override
public Segment3d getMarkerPosition()
{
return markerPosition;
}
@Override
public String getL7dUserTip(OperationArgument argument)
{
String bundleKey = null;
if (argument == getArguments().get(0)) {
bundleKey = "fold.line.user.tip";
} else if (argument == getArguments().get(1)) {
bundleKey = "fold.layers.user.tip";
}
if (bundleKey != null)
return messages.getString(bundleKey);
else
return null;
}
@Override
public void fillFromArguments() throws IllegalStateException
{
super.fillFromArguments();
this.line = ((LineArgument) arguments.get(0)).getLine2D();
this.layer = ((LayersArgument) arguments.get(1)).getLayers();
}
@Override
public String toString()
{
return "FoldUnfoldOperation [" + type + ", layer=" + layer + ", line=" + line + "]";
}
@Override
public Operation getSymmetricOperation(Line2d symmetryAxis)
{
FoldUnfoldOperation result = new FoldUnfoldOperation();
result.type = this.type;
result.line = new Line2D(symmetryAxis.mirror(this.line.toLine2d()));
result.layer = new LinkedList<Integer>(this.layer);
return result;
}
}