+
+ public void fitToView(Collection<vtkProp3D> props) {
+ if (props.isEmpty())
+ return;
+
+ double[] bounds = new double[] { Double.MAX_VALUE, -Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE }, b = new double[6];
+ for (vtkProp3D prop : props) {
+ prop.GetBounds(b);
+ for (int i = 0; i < 6; i+=2)
+ bounds[i] = Math.min(bounds[i], b[i]);
+ for (int i = 1; i < 6; i+=2)
+ bounds[i] = Math.max(bounds[i], b[i]);
+ }
+
+ fitToView(bounds);
+ }
+
+ public void fitToView(double[] bounds) {
+ Vector3d center = new Vector3d((bounds[0] + bounds[1])/2, (bounds[2] + bounds[3])/2, (bounds[4] + bounds[5])/2);
+ Vector3d viewDir = new Vector3d(cam.GetDirectionOfProjection());
+ Vector3d upDir = new Vector3d(cam.GetViewUp());
+ viewDir.normalize();
+ upDir.normalize();
+ Vector3d sideDir = new Vector3d();
+ sideDir.cross(viewDir, upDir);
+ sideDir.normalize();
+
+ double width = getBoxWidth(bounds, sideDir);
+ double height = getBoxWidth(bounds, upDir);
+ double depth = getBoxWidth(bounds, viewDir);
+
+ int[] size = rw.GetActualSize();
+
+ double distance1 = height / 2 / Math.tan(Math.toRadians(cam.GetViewAngle()) / 2);
+ double distance2 = distance1 * (width / size[0] / (height / size[1]));
+
+ double distance = Math.max(distance1, distance2) + depth / 2;
+
+ viewDir.scale(-distance);
+ viewDir.add(center);
+
+ cam.SetPosition(viewDir.x, viewDir.y, viewDir.z);
+ focus(center.x, center.y, center.z);
+
+ if (cam.GetParallelProjection() == 1) {
+ cam.SetParallelScale(Math.max(height, width * size[1] / size[0]) / 2);
+ }
+ }
+
+ private static double getBoxWidth(double[] bounds, Vector3d dir) {
+ double dx = bounds[1] - bounds[0];
+ double dy = bounds[3] - bounds[2];
+ double dz = bounds[5] - bounds[4];
+
+ return Math.abs(dx * dir.x) + Math.abs(dy * dir.y) + Math.abs(dz * dir.z);
+ }