Bug 13022 fixed: Vectorial export did not clip large segments 58/13058/2
Calixte DENIZET [Thu, 31 Oct 2013 16:03:05 +0000 (17:03 +0100)]
Change-Id: I4db03f4109d24fb297a70fd6b32fb20b627f8953

scilab/CHANGES_5.5.X
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/implementation/g2d/motor/AbstractDrawable3DObject.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/implementation/g2d/motor/Motor3D.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/implementation/g2d/motor/PolyLine.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/implementation/g2d/motor/Segment.java
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/implementation/g2d/motor/Triangle.java

index 2766b75..f723c27 100644 (file)
@@ -101,6 +101,8 @@ Scilab Bug Fixes
 
 * Bug #13015 fixed - Computation of Efficiency inner variable improved in optim_ga.
 
+* Bug #13022 fixed - Vectorial export did not clip large segments.
+
 * Bug #13032 fixed - Fixed CMATVIEW help example and created one for CMAT3D.
 
 * Bug #13036 fixed - Help page associated to history browser was wrong.
index fdda155..a503c07 100644 (file)
@@ -13,7 +13,9 @@ package org.scilab.forge.scirenderer.implementation.g2d.motor;
 
 import java.awt.Color;
 import java.awt.Graphics2D;
+import java.awt.Shape;
 import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -43,6 +45,7 @@ public abstract class AbstractDrawable3DObject {
     protected boolean marked;
     protected boolean marked2;
     protected Boolean degenerated;
+    protected double[] clip = new double[] {Double.NaN, Double.NaN, Double.NaN, Double.NaN};
 
     /**
      * Default constructor
@@ -65,6 +68,46 @@ public abstract class AbstractDrawable3DObject {
     }
 
     /**
+     * Create a clip rect for 2D view according to clipping planes passed as arguments
+     * @param v the clipping plane equation
+     */
+    void makeClip(double[] v) {
+        if (v[1] == 0) {
+            double x = -v[3] / v[0];
+            if (Double.isNaN(clip[0])) {
+                clip[0] = x;
+            } else if (clip[0] > x) {
+                clip[1] = clip[0];
+                clip[0] = x;
+            } else {
+                clip[1] = x;
+            }
+        } else {
+            double y = -v[3] / v[1];
+            if (Double.isNaN(clip[2])) {
+                clip[2] = y;
+            } else if (clip[2] > y) {
+                clip[3] = clip[2];
+                clip[2] = y;
+            } else {
+                clip[3] = y;
+            }
+        }
+    }
+
+    /**
+     * Get the clipping shape (for 2D view)
+     * @return the clipping shape
+     */
+    Shape getClip() {
+        if (!Double.isNaN(clip[0]) && !Double.isNaN(clip[1]) && !Double.isNaN(clip[2]) && !Double.isNaN(clip[3])) {
+            return new Rectangle2D.Double(clip[0], clip[2], clip[1] - clip[0], clip[3] - clip[2]);
+        }
+
+        return null;
+    }
+
+    /**
      * Get the bounding box
      * @return the bounding box
      */
index a90b5bc..3d2267b 100644 (file)
@@ -375,7 +375,7 @@ public class Motor3D {
                         v = new Vector3d[] {verticesArray[i], verticesArray[i + 1]};
                         c = new Color[] {colorsArray[i], colorsArray[i + 1]};
                         try {
-                            add(new Segment(v, c, G2DStroke.getStroke(appearance, cumLength)));
+                            add(new Segment(v, c, G2DStroke.getStroke(appearance, cumLength), false));
                             cumLength += Segment.getLength(v);
                         } catch (InvalidPolygonException e) {
                             cumLength = 0;
@@ -394,7 +394,7 @@ public class Motor3D {
                         v = new Vector3d[] {verticesArray[i], verticesArray[i + 1]};
                         c = new Color[] {colorsArray[i], colorsArray[i + 1]};
                         try {
-                            add(new Segment(v, c, G2DStroke.getStroke(appearance, cumLength)));
+                            add(new Segment(v, c, G2DStroke.getStroke(appearance, cumLength), false));
                             cumLength += Segment.getLength(v);
                         } catch (InvalidPolygonException e) {
                             cumLength = 0;
@@ -404,7 +404,7 @@ public class Motor3D {
                     v = new Vector3d[] {verticesArray[n], verticesArray[0]};
                     c = new Color[] {colorsArray[n], colorsArray[0]};
                     try {
-                        add(new Segment(v, c, G2DStroke.getStroke(appearance, cumLength)));
+                        add(new Segment(v, c, G2DStroke.getStroke(appearance, cumLength), false));
                     } catch (InvalidPolygonException e) { }
                 }
                 break;
@@ -414,7 +414,7 @@ public class Motor3D {
                     v = new Vector3d[] {verticesArray[i], verticesArray[i + 1]};
                     c = new Color[] {colorsArray[i], colorsArray[i + 1]};
                     try {
-                        add(new Segment(v, c, G2DStroke.getStroke(appearance, 0)));
+                        add(new Segment(v, c, G2DStroke.getStroke(appearance, 0), is2DView()));
                     } catch (InvalidPolygonException e) { }
                 }
                 break;
@@ -580,7 +580,7 @@ public class Motor3D {
         float[] vertexTransf = lightManager.getVertexTransform();
         float[] normalTransf = lightManager.getNormalTransform();
         //for transformed vertices camera is at origin.
-        Vector3f camera = new Vector3f(0.f, 0.f ,0.f);
+        Vector3f camera = new Vector3f(0.f, 0.f , 0.f);
         Vector3f[] vertexArray = LightHelper.getIndexedVector3f(vertices, index, G2DElementsBuffer.ELEMENT_SIZE, vertexTransf);
         Vector3f[] normalArray = LightHelper.getIndexedVector3f(normals, index, G2DElementsBuffer.ELEMENT_SIZE, normalTransf);
 
@@ -594,7 +594,9 @@ public class Motor3D {
         for (int i = 0; i < lightManager.getLightNumber(); ++i) {
             G2DLight l = (G2DLight)lightManager.getLight(i);
 
-            if (l == null || !l.isEnable()) continue;
+            if (l == null || !l.isEnable()) {
+                continue;
+            }
 
             outColors = LightHelper.applyLight(l, mat, camera, vertexArray, normalArray, colors, outColors, vertexTransf, !first);
             first = false;
index f3016b0..7faeb08 100644 (file)
@@ -12,6 +12,7 @@
 package org.scilab.forge.scirenderer.implementation.g2d.motor;
 
 import java.awt.Color;
+import java.awt.Shape;
 import java.awt.Stroke;
 import java.awt.geom.Line2D;
 import java.awt.geom.Path2D;
@@ -99,29 +100,36 @@ public class PolyLine extends ConvexObject {
      */
     public List<ConvexObject> breakObject(Vector4d v) {
         final double[] vv = v.getData();
-        final Vector3d np = new Vector3d(vv);
         final List<ConvexObject> list = new ArrayList<ConvexObject>(1);
 
-        int pos = 0;
-        boolean prev = false;
-
-        for (int i = 0; i < vertices.length; i++) {
-            final boolean b = isBehind(vertices[i], np, vv[3]);
-            if (b && !prev) {
-                pos = i;
-                prev = true;
-            } else if (!b && prev) {
-                prev = false;
+        // Since PolyLine are only used in 2D it is useless to check when z != 0
+        if (vv[2] == 0) {
+            final Vector3d np = new Vector3d(vv);
+            makeClip(vv);
+
+            int pos = 0;
+            boolean prev = false;
+
+            for (int i = 0; i < vertices.length; i++) {
+                final boolean b = isBehind(vertices[i], np, vv[3]);
+                if (b && !prev) {
+                    pos = i;
+                    prev = true;
+                } else if (!b && prev) {
+                    prev = false;
+                    try {
+                        list.add(cut(pos, i, np, vv[3]));
+                    } catch (InvalidPolygonException e) { }
+                }
+            }
+
+            if (prev) {
                 try {
-                    list.add(cut(pos, i, np, vv[3]));
+                    list.add(cut(pos, vertices.length, np, vv[3]));
                 } catch (InvalidPolygonException e) { }
             }
-        }
-
-        if (prev) {
-            try {
-                list.add(cut(pos, vertices.length, np, vv[3]));
-            } catch (InvalidPolygonException e) { }
+        } else {
+            list.add(this);
         }
 
         return list;
@@ -236,22 +244,15 @@ public class PolyLine extends ConvexObject {
         }
     }
 
-
-    @Override
-    protected Path2D getProjectedPolyLine() {
-        Path2D.Double path = new Path2D.Double();
-
-        path.moveTo(vertices[0].getX(), vertices[0].getY());
-        for (int i = 1; i < vertices.length; i++) {
-            path.lineTo(vertices[i].getX(), vertices[i].getY());
-        }
-
-        return path;
-    }
-
     @Override
     public void draw(Graphics2D g2d) {
         Stroke oldStroke = g2d.getStroke();
+        Shape oldClip = g2d.getClip();
+
+        Shape newClip = getClip();
+        if (newClip != null) {
+            g2d.clip(newClip);
+        }
 
         if (monochromatic) {
             g2d.setColor(colors[0]);
@@ -274,6 +275,10 @@ public class PolyLine extends ConvexObject {
             }
         }
 
+        if (newClip != null) {
+            g2d.setClip(oldClip);
+        }
+
         g2d.setStroke(oldStroke);
     }
 
index 45c4d40..ec0c6a2 100644 (file)
@@ -13,6 +13,7 @@ package org.scilab.forge.scirenderer.implementation.g2d.motor;
 
 import java.awt.Color;
 import java.awt.Graphics2D;
+import java.awt.Shape;
 import java.awt.Stroke;
 import java.awt.geom.Path2D;
 import java.util.ArrayList;
@@ -32,17 +33,19 @@ public class Segment extends ConvexObject implements Comparable<Segment> {
     private Integer hash;
     protected G2DStroke stroke;
     protected List<ConvexObject> segmentOn;
+    protected boolean is2D;
 
-    public Segment(Vector3d[] vertices, Color[] colors, G2DStroke stroke) throws InvalidPolygonException {
+    public Segment(Vector3d[] vertices, Color[] colors, G2DStroke stroke, boolean is2D) throws InvalidPolygonException {
         super(vertices, colors);
         if (vertices.length != 2) {
             throw new InvalidPolygonException("Invalid segment: must have 2 vertices.");
         }
         this.stroke = stroke;
+        this.is2D = is2D;
     }
 
     public Segment(Vector3d[] vertices, Color[] colors) throws InvalidPolygonException {
-        this(vertices, colors, null);
+        this(vertices, colors, null, false);
     }
 
     public void setStroke(G2DStroke stroke) {
@@ -129,6 +132,11 @@ public class Segment extends ConvexObject implements Comparable<Segment> {
     @Override
     public List<ConvexObject> breakObject(Vector4d v) {
         double[] vv = v.getData();
+
+        if (is2D && vv[2] == 0) {
+            makeClip(vv);
+        }
+
         Vector3d np = new Vector3d(vv);
         boolean a = isBehind(vertices[0], np, vv[3]);
         boolean b = isBehind(vertices[1], np, vv[3]);
@@ -150,9 +158,9 @@ public class Segment extends ConvexObject implements Comparable<Segment> {
 
         try {
             if (a) {
-                s = new Segment(new Vector3d[] {vertices[0], p}, new Color[] {colors[0], color}, this.stroke);
+                s = new Segment(new Vector3d[] {vertices[0], p}, new Color[] {colors[0], color}, this.stroke, this.is2D);
             } else {
-                s = new Segment(new Vector3d[] {p, vertices[1]}, new Color[] {color, colors[1]}, this.stroke);
+                s = new Segment(new Vector3d[] {p, vertices[1]}, new Color[] {color, colors[1]}, this.stroke, this.is2D);
             }
 
             List<ConvexObject> list = new ArrayList<ConvexObject>(1);
@@ -171,15 +179,15 @@ public class Segment extends ConvexObject implements Comparable<Segment> {
             Vector3d q = Vector3d.getBarycenter(vertices[0], vertices[1], c, 1 - c);
             Color color = getColorsBarycenter(colors[0], colors[1], c, 1 - c);
             try {
-                list.add(new Segment(new Vector3d[] {vertices[0], q}, new Color[] {colors[0], color}, stroke));
-                list.add(new Segment(new Vector3d[] {q, vertices[1]}, new Color[] {color, colors[1]}, stroke));
+                list.add(new Segment(new Vector3d[] {vertices[0], q}, new Color[] {colors[0], color}, stroke, this.is2D));
+                list.add(new Segment(new Vector3d[] {q, vertices[1]}, new Color[] {color, colors[1]}, stroke, this.is2D));
 
                 return list;
             } catch (InvalidPolygonException e) { }
         } else {
             List<Segment> list = new ArrayList<Segment>(1);
             try {
-                list.add(new Segment(new Vector3d[] {vertices[0], vertices[1]}, new Color[] {colors[0], colors[1]}, stroke));
+                list.add(new Segment(new Vector3d[] {vertices[0], vertices[1]}, new Color[] {colors[0], colors[1]}, stroke, this.is2D));
 
                 return list;
             } catch (InvalidPolygonException e) { }
@@ -198,12 +206,22 @@ public class Segment extends ConvexObject implements Comparable<Segment> {
                 g2d.setStroke(stroke);
             }
 
+            Shape oldClip = g2d.getClip();
+            Shape newClip = getClip();
+            if (newClip != null) {
+                g2d.clip(newClip);
+            }
+
             g2d.draw(polyline);
 
             if (oldStroke != stroke) {
                 g2d.setStroke(oldStroke);
             }
 
+            if (newClip != null) {
+                g2d.setClip(oldClip);
+            }
+
             drawAreas(g2d);
         }
     }
index 234d4c1..fd370fa 100644 (file)
@@ -155,8 +155,8 @@ public class Triangle extends ConvexObject {
         Color cc = getColorsBarycenter(o.colors[0], o.colors[1], c, 1 - c);
 
         try {
-            list.add(new Segment(new Vector3d[] {o.vertices[0], p}, new Color[] {o.colors[0], cc}, o.stroke));
-            list.add(new Segment(new Vector3d[] {p, o.vertices[1]}, new Color[] {cc, o.colors[1]}, o.stroke));
+            list.add(new Segment(new Vector3d[] {o.vertices[0], p}, new Color[] {o.colors[0], cc}, o.stroke, o.is2D));
+            list.add(new Segment(new Vector3d[] {p, o.vertices[1]}, new Color[] {cc, o.colors[1]}, o.stroke, o.is2D));
         } catch (InvalidPolygonException e) { }
 
         List<ConvexObject> list1 = breakTriangleOnLine(this, p, Vector3d.product(v0v1, vertices[0].minus(p)));
@@ -347,8 +347,8 @@ public class Triangle extends ConvexObject {
         Color cc = getColorsBarycenter(s.colors[0], s.colors[1], c, 1 - c);
 
         try {
-            list.add(new Segment(new Vector3d[] {s.vertices[0], p}, new Color[] {s.colors[0], cc}, s.stroke));
-            list.add(new Segment(new Vector3d[] {p, s.vertices[1]}, new Color[] {cc, s.colors[1]}, s.stroke));
+            list.add(new Segment(new Vector3d[] {s.vertices[0], p}, new Color[] {s.colors[0], cc}, s.stroke, s.is2D));
+            list.add(new Segment(new Vector3d[] {p, s.vertices[1]}, new Color[] {cc, s.colors[1]}, s.stroke, s.is2D));
         } catch (InvalidPolygonException e) { }