* Bug #4731 fixed - lqr failed when the time domain of an input was a number.
+* Bug #4743 fixed - Invalid graphics with too big or too small values.
+
* Bug #5073 fixed - New parameter added in strtod function (decimal separator).
* Bug #5205 fixed - permute was slow for large hypermatrices.
}
/**
+ * Get the scale and translate factors corresponding to the displayed bounds
+ * @return the factors as a multidimensional array 2x3
+ */
+ public double[][] getScaleTranslateFactors() {
+ // For an axe scale and translate factors are
+ // such that scale*min+translate=-1 and scale*max+translate=+1
+ // With these factors, double data will be in interval [-1;1]
+
+ Double[] bounds = getMaximalDisplayedBounds();
+ double[][] f = new double[2][];
+
+ // scale factors
+ f[0] = new double[] {2 / (bounds[1] - bounds[0]),
+ 2 / (bounds[3] - bounds[2]),
+ 2 / (bounds[5] - bounds[4])
+ };
+
+ // translate factors
+ f[1] = new double[] { -(bounds[1] + bounds[0]) / (bounds[1] - bounds[0]), -(bounds[3] + bounds[2]) / (bounds[3] - bounds[2]), -(bounds[5] + bounds[4]) / (bounds[5] - bounds[4])};
+
+ return f;
+ }
+
+ public Double[] getCorrectedBounds() {
+ if (getZoomEnabled()) {
+ Double[] b = getZoomBox();
+ double[][] factors = getScaleTranslateFactors();
+
+ b[0] = b[0] * factors[0][0] + factors[1][0];
+ b[1] = b[1] * factors[0][0] + factors[1][0];
+ b[2] = b[2] * factors[0][1] + factors[1][1];
+ b[3] = b[3] * factors[0][1] + factors[1][1];
+ b[4] = b[4] * factors[0][2] + factors[1][2];
+ b[5] = b[5] * factors[0][2] + factors[1][2];
+
+ return b;
+ } else {
+ return new Double[] { -1., 1., -1., 1., -1., 1.};
+ }
+ }
+
+ /**
* Current displayed bounds getter.
* @return the current visible bounds of this axes.
*/
}
public Double[] getScale() {
- return scale;
+ return new Double[] {scale[0], scale[1]};
}
public void setScale(Double[] scale) {
}
public Double[] getTranslate() {
- return translate;
+ return new Double[] {translate[0], translate[1]};
}
public void setTranslate(Double[] translate) {
import org.scilab.forge.scirenderer.buffers.IndicesBuffer;
import org.scilab.modules.graphic_objects.MainDataLoader;
import org.scilab.modules.graphic_objects.ObjectRemovedException;
+import org.scilab.modules.graphic_objects.axes.Axes;
import org.scilab.modules.graphic_objects.graphicController.GraphicController;
+import org.scilab.modules.graphic_objects.graphicObject.GraphicObject;
import org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties;
import org.scilab.modules.renderer.JoGLView.util.BufferAllocation;
import org.scilab.modules.renderer.JoGLView.util.OutOfMemoryException;
/**
* @author Pierre Lando
- */
-public class DataManager {
+ */public class DataManager {
/**
* Set of properties that affect Fac3d data.
*/
private static final int DEFAULT_LOG_MASK = 0;
-
- private final Map<String, ElementsBuffer> vertexBufferMap = new HashMap<String, ElementsBuffer>();
+ private final Map<String, TransformedElementsBuffer> vertexBufferMap = new HashMap<String, TransformedElementsBuffer>();
private final Map<String, ElementsBuffer> normalBufferMap = new HashMap<String, ElementsBuffer>();
private final Map<String, ElementsBuffer> colorBufferMap = new ConcurrentHashMap<String, ElementsBuffer>();
private final Map<String, ElementsBuffer> texturesCoordinatesBufferMap = new HashMap<String, ElementsBuffer>();
* @throws ObjectRemovedException if the object is now longer present.
*/
public ElementsBuffer getVertexBuffer(String id) throws ObjectRemovedException, OutOfMemoryException {
+ GraphicObject currentObject = GraphicController.getController().getObjectFromId(id);
+ Axes axes = (Axes) GraphicController.getController().getObjectFromId(currentObject.getParentAxes());
+ double[][] factors = axes.getScaleTranslateFactors();
+
if (vertexBufferMap.containsKey(id)) {
- return vertexBufferMap.get(id);
- } else {
- ElementsBuffer vertexBuffer = canvas.getBuffersManager().createElementsBuffer();
- fillVertexBuffer(vertexBuffer, id);
- vertexBufferMap.put(id, vertexBuffer);
- return vertexBuffer;
+ TransformedElementsBuffer buf = vertexBufferMap.get(id);
+ if (buf.isSameFactors(factors)) {
+ return buf.getBuffer();
+ }
}
+
+ ElementsBuffer vertexBuffer = canvas.getBuffersManager().createElementsBuffer();
+ fillVertexBuffer(vertexBuffer, id, factors[0], factors[1]);
+ vertexBufferMap.put(id, new TransformedElementsBuffer(vertexBuffer, factors));
+
+ return vertexBuffer;
}
/**
* @throws OutOfMemoryException if there was not enough memory.
*/
private void updateChildrenVertexIndex(String id, int coordinateMask) throws ObjectRemovedException, OutOfMemoryException {
- ElementsBuffer vertexBuffer = vertexBufferMap.get(id);
- if (vertexBuffer != null) {
- updateVertexBuffer(vertexBuffer, id, coordinateMask);
+ GraphicObject currentObject = GraphicController.getController().getObjectFromId(id);
+ Axes axes = (Axes) GraphicController.getController().getObjectFromId(currentObject.getParentAxes());
+ double[][] factors = axes.getScaleTranslateFactors();
+
+ TransformedElementsBuffer buf = vertexBufferMap.get(id);
+ if (buf != null) {
+ updateVertexBuffer(buf.getBuffer(), id, coordinateMask, factors[0], factors[1]);
}
ElementsBuffer normalBuffer = normalBufferMap.get(id);
*/
public void dispose(String id) {
if (vertexBufferMap.containsKey(id)) {
- canvas.getBuffersManager().dispose(vertexBufferMap.get(id));
+ canvas.getBuffersManager().dispose(vertexBufferMap.get(id).getBuffer());
vertexBufferMap.remove(id);
}
* @throws ObjectRemovedException if the object is now longer present.
*/
private void fillBuffers(String id) throws ObjectRemovedException, OutOfMemoryException {
- ElementsBuffer vertexBuffer = vertexBufferMap.get(id);
- if (vertexBuffer != null) {
- fillVertexBuffer(vertexBuffer, id);
+ TransformedElementsBuffer buf = vertexBufferMap.get(id);
+ if (buf != null) {
+ fillVertexBuffer(buf.getBuffer(), id, buf.getScale(), buf.getTranslate());
}
ElementsBuffer colorBuffer = colorBufferMap.get(id);
}
}
- private void fillVertexBuffer(ElementsBuffer vertexBuffer, String id) throws ObjectRemovedException, OutOfMemoryException {
- fillVertexBuffer(vertexBuffer, id, 0x01 | 0x02 | 0x04 | 0x08);
+ private void fillVertexBuffer(ElementsBuffer vertexBuffer, String id, double[] scale, double[] translate) throws ObjectRemovedException, OutOfMemoryException {
+ fillVertexBuffer(vertexBuffer, id, 0x01 | 0x02 | 0x04 | 0x08, scale, translate);
}
- private void fillVertexBuffer(ElementsBuffer vertexBuffer, String id, int coordinateMask) throws ObjectRemovedException, OutOfMemoryException {
+ private void fillVertexBuffer(ElementsBuffer vertexBuffer, String id, int coordinateMask, double[] scale, double[] translate) throws ObjectRemovedException, OutOfMemoryException {
int logMask = MainDataLoader.getLogMask(id);
int length = MainDataLoader.getDataSize(id);
FloatBuffer data = BufferAllocation.newFloatBuffer(length * 4);
- MainDataLoader.fillVertices(id, data, 4, coordinateMask, DEFAULT_SCALE, DEFAULT_TRANSLATE, logMask);
+ MainDataLoader.fillVertices(id, data, 4, coordinateMask, scale, translate, logMask);
vertexBuffer.setData(data, 4);
}
normalBuffer.setData(data, 4);
}
- private void updateVertexBuffer(ElementsBuffer vertexBuffer, String id, int coordinateMask) throws ObjectRemovedException {
+ private void updateVertexBuffer(ElementsBuffer vertexBuffer, String id, int coordinateMask, double[] scale, double[] translate) throws ObjectRemovedException {
int logMask = MainDataLoader.getLogMask(id);
FloatBuffer data = vertexBuffer.getData();
- MainDataLoader.fillVertices(id, data, 4, coordinateMask, DEFAULT_SCALE, DEFAULT_TRANSLATE, logMask);
+ MainDataLoader.fillVertices(id, data, 4, coordinateMask, scale, translate, logMask);
vertexBuffer.setData(data, 4);
}
indexBuffer.setData(data);
}
+
+ private static class TransformedElementsBuffer {
+
+ ElementsBuffer buffer;
+ double[][] factors;
+
+ TransformedElementsBuffer(ElementsBuffer buffer, double[][] factors) {
+ this.buffer = buffer;
+ this.factors = factors;
+ }
+
+ ElementsBuffer getBuffer() {
+ return buffer;
+ }
+
+ double[] getScale() {
+ return factors[0];
+ }
+
+ double[] getTranslate() {
+ return factors[1];
+ }
+
+ boolean isSameFactors(final double[][] factors) {
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 3; j++) {
+ if (this.factors[i][j] != factors[i][j]) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+ }
}
drawingTools.draw(geometry, appearance);
} else {
TransformationStack modelViewStack = drawingTools.getTransformationManager().getModelViewStack();
+ double[][] factors = currentAxes.getScaleTranslateFactors();
Double[] scale = matplot.getScale();
Double[] translate = matplot.getTranslate();
+
+ scale[0] *= factors[0][0];
+ scale[1] *= factors[0][1];
+
+ translate[0] = translate[0] * factors[0][0] + factors[1][0];
+ translate[1] = translate[1] * factors[0][1] + factors[1][1];
+
Transformation t = TransformationFactory.getTranslateTransformation(translate[0], translate[1], 0);
Transformation t2 = TransformationFactory.getScaleTransformation(scale[0], scale[1], 1);
modelViewStack.pushRightMultiply(t);
addProjection(axes.getIdentifier(), currentProjection);
/* 2d view projection, to do: optimize computation */
- if (axes.getRotationAngles()[0] != 0 || axes.getRotationAngles()[1] != DEFAULT_THETA) {
+ if ((axes.getRotationAngles()[0] != 0 || axes.getRotationAngles()[1] != DEFAULT_THETA)) {
Transformation transformation2dView = computeBoxTransformation(axes, canvasDimension, true);
currentProjection = zoneProjection.rightTimes(transformation2dView);
currentProjection = currentProjection.rightTimes(dataTransformation);
* @throws DegenerateMatrixException if data bounds are not corrects.
*/
private Transformation computeDataTransformation(Axes axes) throws DegenerateMatrixException {
- Double[] bounds = axes.getDisplayedBounds();
-
// Reverse data if needed.
Transformation transformation = TransformationFactory.getScaleTransformation(
axes.getAxes()[0].getReverse() ? 1 : -1,
axes.getAxes()[2].getReverse() ? 1 : -1
);
- // Scale data.
- Transformation scaleTransformation = TransformationFactory.getScaleTransformation(
- 2.0 / (bounds[1] - bounds[0]),
- 2.0 / (bounds[3] - bounds[2]),
- 2.0 / (bounds[5] - bounds[4])
- );
- transformation = transformation.rightTimes(scaleTransformation);
-
-
- // Translate data.
- Transformation translateTransformation = TransformationFactory.getTranslateTransformation(
- -(bounds[0] + bounds[1]) / 2.0,
- -(bounds[2] + bounds[3]) / 2.0,
- -(bounds[4] + bounds[5]) / 2.0
- );
- transformation = transformation.rightTimes(translateTransformation);
+ if (axes.getZoomEnabled()) {
+ Double[] bounds = axes.getCorrectedBounds();
+
+ // Scale data.
+ Transformation scaleTransformation = TransformationFactory.getScaleTransformation(
+ 2.0 / (bounds[1] - bounds[0]),
+ 2.0 / (bounds[3] - bounds[2]),
+ 2.0 / (bounds[5] - bounds[4])
+ );
+ transformation = transformation.rightTimes(scaleTransformation);
+
+
+ // Translate data.
+ Transformation translateTransformation = TransformationFactory.getTranslateTransformation(
+ -(bounds[0] + bounds[1]) / 2.0,
+ -(bounds[2] + bounds[3]) / 2.0,
+ -(bounds[4] + bounds[5]) / 2.0
+ );
+ transformation = transformation.rightTimes(translateTransformation);
+
+ return transformation;
+ }
+
return transformation;
}
*/
private Transformation computeBoxTransformation(Axes axes, Dimension canvasDimension, boolean use2dView) throws DegenerateMatrixException {
Double[] bounds = axes.getDisplayedBounds();
-
double theta;
double tmpX;
* @param axes the given {@see Axes}.
*/
private void computeReversedBounds(Axes axes) {
- Double[] currentBounds = axes.getDisplayedBounds();
+ Double[] currentBounds = axes.getCorrectedBounds();
/* Reverse */
if (axes.getAxes()[0].getReverse()) {
* @returns the 2d view coordinates (3-element array).
*/
public static double[] compute2dViewCoordinates(Axes axes, double[] coordinates) {
+ // used in geom3d
+
DrawerVisitor currentVisitor = DrawerVisitor.getVisitor(axes.getParentFigure());
AxesDrawer axesDrawer;
Transformation projection;
Transformation projection2d;
-
- Vector3d point = new Vector3d(coordinates);
+ double[] coords = coordinates;
if (currentVisitor != null) {
Integer[] size = currentVisitor.getFigure().getAxesSize();
Dimension canvasDimension = new Dimension(size[0], size[1]);
+ double[][] factors = axes.getScaleTranslateFactors();
axesDrawer = currentVisitor.getAxesDrawer();
+ coords[0] = coords[0] * factors[0][0] + factors[1][0];
+ coords[1] = coords[1] * factors[0][1] + factors[1][1];
+ coords[2] = coords[2] * factors[0][2] + factors[1][2];
projection = axesDrawer.computeProjection(axes, currentVisitor.getDrawingTools(), canvasDimension, false);
projection2d = axesDrawer.computeProjection(axes, currentVisitor.getDrawingTools(), canvasDimension, true);
-
+ Vector3d point = new Vector3d(coords);
point = projection.project(point);
point = projection2d.unproject(point);
+
+ coords = point.getData();
+ coords[0] = (coords[0] - factors[1][0]) / factors[0][0];
+ coords[1] = (coords[1] - factors[1][1]) / factors[0][1];
+ coords[2] = (coords[2] - factors[1][2]) / factors[0][2];
}
- return new double[] {point.getX(), point.getY(), point.getZ()};
+ return coords;
}
/**
* @returns the pixel coordinates (2-element array: x, y).
*/
public static double[] computePixelFrom2dViewCoordinates(Axes axes, double[] coordinates) {
+ // used by xchange
+
DrawerVisitor currentVisitor = DrawerVisitor.getVisitor(axes.getParentFigure());
AxesDrawer axesDrawer;
double[] coords2dView = new double[] {0.0, 0.0, 0.0};
if (currentVisitor != null) {
Integer[] size = currentVisitor.getFigure().getAxesSize();
double height = (double) size[1];
+ double[][] factors = axes.getScaleTranslateFactors();
axesDrawer = currentVisitor.getAxesDrawer();
+ coords2dView[0] = coordinates[0] * factors[0][0] + factors[1][0];
+ coords2dView[1] = coordinates[1] * factors[0][1] + factors[1][1];
+ coords2dView[2] = coordinates[2] * factors[0][2] + factors[1][2];
Transformation projection2d = axesDrawer.getProjection2dView(axes.getIdentifier());
-
if (projection2d == null) {
updateAxesTransformation(axes);
projection2d = axesDrawer.getProjection2dView(axes.getIdentifier());
}
- Vector3d point = new Vector3d(coordinates);
+ Vector3d point = new Vector3d(coords2dView);
point = projection2d.project(point);
/* Convert the window coordinates to pixel coordinates, only y changes due to the differing y-axis convention */
coords2dView[0] = point.getX();
coords2dView[1] = height - point.getY();
+ coords2dView[2] = 0;
}
return coords2dView;
* @return coordinates the 2d view coordinates (3-element array: x, y, z).
*/
public static double[] compute2dViewFromPixelCoordinates(Axes axes, double[] coordinates) {
+ // used by xgetmouse and by xchange
+
DrawerVisitor currentVisitor;
AxesDrawer axesDrawer;
if (currentVisitor != null) {
Integer[] size = currentVisitor.getFigure().getAxesSize();
double height = (double) size[1];
+ double[][] factors = axes.getScaleTranslateFactors();
axesDrawer = currentVisitor.getAxesDrawer();
point = projection2d.unproject(point);
coords2dView = point.getData();
+
+ coords2dView[0] = (coords2dView[0] - factors[1][0]) / factors[0][0];
+ coords2dView[1] = (coords2dView[1] - factors[1][1]) / factors[0][1];
+ coords2dView[2] = (coords2dView[2] - factors[1][2]) / factors[0][2];
}
return coords2dView;
* against the Axes box planes.
*/
numPlanes = 6;
- Double[] bounds = parentAxes.getDisplayedBounds();
+ Double[] bounds = parentAxes.getCorrectedBounds();
for (int i = 0; i < numPlanes; i++) {
clipBounds[i] = bounds[i];
clipBounds[2] = clipBox[1] - clipBox[3];
clipBounds[3] = clipBox[1];
+ double[][] factors = parentAxes.getScaleTranslateFactors();
Double[] bounds = parentAxes.getMaximalDisplayedBounds();
/*
}
}
+ clipBounds[0] = clipBounds[0] * factors[0][0] + factors[1][0];
+ clipBounds[1] = clipBounds[1] * factors[0][0] + factors[1][0];
+ clipBounds[2] = clipBounds[2] * factors[0][1] + factors[1][1];
+ clipBounds[3] = clipBounds[3] * factors[0][1] + factors[1][1];
+
offsets[0] = CLIPPING_EPSILON * (clipBounds[1] - clipBounds[0]);
offsets[1] = CLIPPING_EPSILON * (clipBounds[3] - clipBounds[2]);
}
}
Transformation currentTransformation = drawingTools.getTransformationManager().getTransformation();
+
for (int i = 0 ; i < numPlanes; i++) {
ClippingPlane plane = drawingTools.getClippingManager().getClippingPlane(i);
plane.setTransformation(currentTransformation);
Transformation projection = drawingTools.getTransformationManager().getCanvasProjection();
- Vector3d textPosition = new Vector3d(text.getPosition());
-
String parentAxesId = text.getParentAxes();
Axes parentAxes = (Axes) GraphicController.getController().getObjectFromId(parentAxesId);
+ double[][] factors = parentAxes.getScaleTranslateFactors();
+ Double[] pos = text.getPosition();
+ pos[0] = pos[0] * factors[0][0] + factors[1][0];
+ pos[1] = pos[1] * factors[0][1] + factors[1][1];
+ pos[2] = pos[2] * factors[0][2] + factors[1][2];
+
+ Vector3d textPosition = new Vector3d(pos);
/* Compute the text box vectors and the text box to texture dimension ratios */
Vector3d[] textBoxVectors = computeTextBoxVectors(projection, text, texture.getDataProvider().getTextureSize(), parentAxes);
Vector3d[] textBoxVectors = new Vector3d[2];
+ double[][] factors = parentAxes.getScaleTranslateFactors();
+ Double[] pos = text.getPosition();
+ pos[0] = pos[0] * factors[0][0] + factors[1][0];
+ pos[1] = pos[1] * factors[0][1] + factors[1][1];
+ pos[2] = pos[2] * factors[0][2] + factors[1][2];
+
/* The text position vector before logarithmic scaling */
- Vector3d unscaledTextPosition = new Vector3d(text.getPosition());
+ Vector3d unscaledTextPosition = new Vector3d(pos);
boolean[] logFlags = new boolean[] {parentAxes.getXAxisLogFlag(), parentAxes.getYAxisLogFlag(), parentAxes.getZAxisLogFlag()};
protected Vector3d[] computeTextPosition(Transformation projection, Text text, Vector3d[] textBoxVectors, Dimension spriteDim) throws DegenerateMatrixException {
Vector3d[] cornerPositions = new Vector3d[2];
- Vector3d textPosition = new Vector3d(text.getPosition());
-
String parentAxesId = text.getParentAxes();
Axes parentAxes = (Axes) GraphicController.getController().getObjectFromId(parentAxesId);
+ double[][] factors = parentAxes.getScaleTranslateFactors();
+ Double[] pos = text.getPosition();
+ pos[0] = pos[0] * factors[0][0] + factors[1][0];
+ pos[1] = pos[1] * factors[0][1] + factors[1][1];
+ pos[2] = pos[2] * factors[0][2] + factors[1][2];
+
+ Vector3d textPosition = new Vector3d(pos);
/* Apply logarithmic scaling */
boolean[] logFlags = new boolean[] {parentAxes.getXAxisLogFlag(), parentAxes.getYAxisLogFlag(), parentAxes.getZAxisLogFlag()};
textPosition = ScaleUtils.applyLogScale(textPosition, logFlags);
-
textPosition = projection.project(textPosition);
cornerPositions[0] = new Vector3d(textPosition);
Vector3d[] corners = currentVisitor.getTextManager().computeCorners(currentProj, projCorners, parentAxes);
Double[] coordinates = currentVisitor.getTextManager().cornersToCoordinateArray(corners);
+ double[][] factors = parentAxes.getScaleTranslateFactors();
+ coordinates[0] = (coordinates[0] - factors[1][0]) / factors[0][0];
+ coordinates[1] = (coordinates[1] - factors[1][1]) / factors[0][1];
+ coordinates[2] = (coordinates[2] - factors[1][2]) / factors[0][2];
+ coordinates[3] = (coordinates[3] - factors[1][0]) / factors[0][0];
+ coordinates[4] = (coordinates[4] - factors[1][1]) / factors[0][1];
+ coordinates[5] = (coordinates[5] - factors[1][2]) / factors[0][2];
+ coordinates[6] = (coordinates[6] - factors[1][0]) / factors[0][0];
+ coordinates[7] = (coordinates[7] - factors[1][1]) / factors[0][1];
+ coordinates[8] = (coordinates[8] - factors[1][2]) / factors[0][2];
+ coordinates[9] = (coordinates[9] - factors[1][0]) / factors[0][0];
+ coordinates[10] = (coordinates[10] - factors[1][1]) / factors[0][1];
+ coordinates[11] = (coordinates[11] - factors[1][2]) / factors[0][2];
+
/* Set the computed coordinates */
text.setCorners(coordinates);