/// <summary> /// Find the Perspective viewport in the 3dm file and sets up the default view. /// </summary> public void LoadCamera() { if (App.Manager.CurrentModel == null) { return; } Camera = new ViewportInfo(); bool cameraIsInitialized = false; int viewCount = App.Manager.CurrentModel.ModelFile.Views.Count; // find first perspective viewport projection in file if (viewCount > 0) { foreach (var view in App.Manager.CurrentModel.ModelFile.Views) { if (view.Viewport.IsPerspectiveProjection) { cameraIsInitialized = true; Camera = view.Viewport; Camera.TargetPoint = view.Viewport.TargetPoint; Camera.SetScreenPort(0, (int)View.Bounds.Size.Width, 0, (int)View.Bounds.Size.Height, 1, 1000); Camera.FrustumAspect = Camera.ScreenPortAspect; Camera.SetFrustumNearFar(App.Manager.CurrentModel.BBox); break; } } } // If there isn't one, then cook up a viewport from scratch... if (!cameraIsInitialized) { Camera.SetScreenPort(0, (int)View.Bounds.Size.Width, 0, (int)View.Bounds.Size.Height, 1, 1000); Camera.TargetPoint = new Rhino.Geometry.Point3d(0, 0, 0); var plane = new Rhino.Geometry.Plane(Rhino.Geometry.Point3d.Origin, new Rhino.Geometry.Vector3d(-1, -1, -1)); Camera.SetCameraLocation(new Rhino.Geometry.Point3d(10, 10, 10)); var dir = new Rhino.Geometry.Vector3d(-1, -1, -1); dir.Unitize(); Camera.SetCameraDirection(dir); Camera.SetCameraUp(plane.YAxis); Camera.SetFrustum(-1, 1, -1, 1, 0.1, 1000); Camera.FrustumAspect = Camera.ScreenPortAspect; Camera.IsPerspectiveProjection = true; Camera.Camera35mmLensLength = 50; if (App.Manager.CurrentModel != null) { if (App.Manager.CurrentModel.AllMeshes != null) { Camera.DollyExtents(App.Manager.CurrentModel.AllMeshes, 1.0); } } } }
/// <summary> /// <para>Magnify/Zoom the Camera in a viewport</para> /// <para>method =</para> /// <para>0 performs a "dolly" magnification by moving the /// camera along the camera direction vector so that /// the amount of the screen subtended by an object /// changes.</para> /// <para>1 performs a "zoom" magnification by adjusting the /// "lens" angle</para> /// </summary> public static bool Magnify(this ViewportInfo viewport, Size viewSize, double magnifcationFactor, int method, System.Drawing.PointF fixedScreenPoint) { if (viewport.IsCameraLocationLocked) { return(false); } int screenWidth = viewSize.Width; int screenHeight = viewSize.Height; if (1 > screenWidth || 1 > screenHeight) { return(false); } // move camera toward target to magnify if (magnifcationFactor > 0) { // if the screen point is not in the viewport, then ignore it. if (!fixedScreenPoint.IsEmpty) { if (fixedScreenPoint.X <= 0 || fixedScreenPoint.X >= screenWidth - 1 || fixedScreenPoint.Y <= 0 || fixedScreenPoint.Y >= screenHeight - 1) { fixedScreenPoint.X = 0; fixedScreenPoint.Y = 0; } } double frustumLeft = viewport.FrustumLeft; double frustumRight = viewport.FrustumRight; double frustumBottom = viewport.FrustumBottom; double frustumTop = viewport.FrustumTop; double frustumNear = viewport.FrustumNear; double frustumFar = viewport.FrustumFar; double frustumWidth = viewport.FrustumWidth; double frustumHeight = viewport.FrustumHeight; double d = 0.0; // dolly camera towards target point... if (viewport.IsPerspectiveProjection && method == 0) { const double miniumumTargetDistance = 0.000001; var cameraZ = viewport.CameraZ; var cameraLocation = viewport.CameraLocation; var target = viewport.TargetPoint; double targetDistance = (cameraLocation - target) * cameraZ; if (targetDistance >= 0.0) { double delta = (1.0 - (1.0 / magnifcationFactor)) * targetDistance; if (targetDistance - delta > miniumumTargetDistance) { cameraLocation = cameraLocation - (delta * cameraZ); viewport.SetCameraLocation(cameraLocation); if (!fixedScreenPoint.IsEmpty) { d = targetDistance / viewport.FrustumNear; frustumWidth *= d; frustumHeight *= d; d = (targetDistance - delta) / targetDistance; } } } } if (method == 1) { // parallel proj or "true" zoom // apply magnification to frustum d = 1.0 / magnifcationFactor; frustumLeft *= d; frustumRight *= d; frustumBottom *= d; frustumTop *= d; viewport.SetFrustum(frustumLeft, frustumRight, frustumBottom, frustumTop, frustumNear, frustumFar); } if (!fixedScreenPoint.IsEmpty && Math.Abs(d) > Double.Epsilon) { // lateral dolly to keep fixed_screen_point in same location on screen Rhino.Geometry.Vector3d scale = new Rhino.Geometry.Vector3d(1.0, 1.0, 1.0); scale.X = viewport.ViewScale.Width; scale.Y = viewport.ViewScale.Height; double fx = ((double)fixedScreenPoint.X / (double)screenWidth); double fy = ((double)fixedScreenPoint.Y / (double)screenHeight); double dx = ((0.5 - fx) * (1.0 - d) * frustumWidth) / scale.X; double dy = ((fy - 0.5) * (1.0 - d) * frustumHeight) / scale.Y; Rhino.Geometry.Vector3d dollyVector = dx * viewport.CameraX + dy * viewport.CameraY; var cameraLocation = viewport.CameraLocation; var target = viewport.TargetPoint; viewport.TargetPoint = target - dollyVector; viewport.SetCameraLocation(cameraLocation - dollyVector); } } return(true); }