Ejemplo n.º 1
0
        /// <summary>
        /// Generate Viewpoint
        /// </summary>
        private VisualizationInfo generateViewpoint()
        {
            try
            {
                // save selected elements to BCF compoments first
                List <Component> bcfComponents = new List <Component>();
                var selectedElements           = MSApp.ActiveModelReference.GetSelectedElements().BuildArrayFromContents();
                if (selectedElements.Length > 0)
                {
                    string originatingSystem = getBentleyProductName();
                    bcfComponents = new List <Component>();
                    foreach (Element e in selectedElements)
                    {
                        string          ifcGuid = string.Empty;
                        PropertyHandler handler = MSApp.CreatePropertyHandler(e);
                        if (handler.SelectByAccessString("GUID"))
                        {
                            Guid guid = parseGuid(handler.GetDisplayString());
                            ifcGuid = IfcGuid.ToIfcGuid(guid).ToString();
                        }
                        bcfComponents.Add(new Component(originatingSystem, e.ID.ToString(), ifcGuid));
                    }
                }

                // get current view
                int    activeViewNum = getActiveViewNumber();
                View   currentView   = MSApp.ActiveDesignFile.Views[activeViewNum];
                double unitFactor    = 1 / GetGunits();

                // enable perspective camera back and forth to get correct view attributes, see the post below
                // https://communities.bentley.com/products/programming/microstation_programming/f/343173/t/80064
                MSApp.CadInputQueue.SendKeyin("MDL KEYIN BENTLEY.VIEWATTRIBUTESDIALOG,VAD VIEWATTRIBUTESDIALOG SETATTRIBUTE 0 Camera True");
                MSApp.CadInputQueue.SendKeyin("MDL KEYIN BENTLEY.VIEWATTRIBUTESDIALOG,VAD VIEWATTRIBUTESDIALOG SETATTRIBUTE 0 Camera False");

                // camera direction
                Point3d direction = MSApp.Point3dNormalize(MSApp.Point3dSubtract(currentView.get_CameraTarget(), currentView.get_CameraPosition()));

                // force view center to be identical as camera target if camera direction is not along Z axis (i.e., not top view or bottom view)
                if (direction.X > distancePrecision || direction.Y > distancePrecision) // arbitrary precision
                {
                    Point3d center = new Point3d();
                    center = currentView.get_Center();
                    Point3d extents = new Point3d();
                    extents = currentView.get_Extents();
                    Point3d translation = new Point3d();
                    translation = MSApp.Point3dSubtract(center, currentView.get_CameraTarget());
                    ViewCameraParameters vcp = new ViewCameraParametersClass();
                    vcp.set_CameraPosition(MSApp.Point3dAdd(currentView.get_CameraPosition(), translation));
                    vcp.set_CameraTarget(MSApp.Point3dAdd(currentView.get_CameraTarget(), translation));
                    currentView.SetCameraProperties(vcp);
                    currentView.set_Extents(extents);
                    currentView.set_Center(center);
                    currentView.Redraw();
                }

                // camera scale
                double h   = currentView.get_Extents().Y *unitFactor;
                double w   = currentView.get_Extents().X *unitFactor;
                double fov = 180 * currentView.CameraAngle / Math.PI;

                // camera location
                Point3d cameraLocation = MSApp.Point3dScale(currentView.get_CameraPosition(), unitFactor);
                // grab current view center point and force to top view if camera direction is along Z axis (i.e., top view or bottom view)
                if (direction.X < distancePrecision && direction.Y < distancePrecision) // arbitrary precision
                {
                    cameraLocation = MSApp.Point3dScale(currentView.get_Center(), unitFactor);
                    direction.Z    = -1.0;
                }

                // camera up vector
                Point3d upVector = currentView.get_CameraUpVector();

                // set up BCF viewpoint
                VisualizationInfo v = new VisualizationInfo();
                v.Components = bcfComponents;

                // FIXME: ignore perspective view for now

                /*if (currentView.isPerspective)
                 * {
                 *  v.PerspectiveCamera = new PerspectiveCamera();
                 *  v.PerspectiveCamera.CameraViewPoint.X = cameraLocation.X;
                 *  v.PerspectiveCamera.CameraViewPoint.Y = cameraLocation.Y;
                 *  v.PerspectiveCamera.CameraViewPoint.Z = cameraLocation.Z;
                 *  v.PerspectiveCamera.CameraUpVector.X = upVector.X;
                 *  v.PerspectiveCamera.CameraUpVector.Y = upVector.Y;
                 *  v.PerspectiveCamera.CameraUpVector.Z = upVector.Z;
                 *  v.PerspectiveCamera.CameraDirection.X = direction.X;
                 *  v.PerspectiveCamera.CameraDirection.Y = direction.Y;
                 *  v.PerspectiveCamera.CameraDirection.Z = direction.Z;
                 *  v.PerspectiveCamera.FieldOfView = fov;
                 * }
                 * else
                 * {*/
                v.OrthogonalCamera = new OrthogonalCamera();
                v.OrthogonalCamera.CameraViewPoint.X = cameraLocation.X;
                v.OrthogonalCamera.CameraViewPoint.Y = cameraLocation.Y;
                v.OrthogonalCamera.CameraViewPoint.Z = cameraLocation.Z;
                v.OrthogonalCamera.CameraUpVector.X  = upVector.X;
                v.OrthogonalCamera.CameraUpVector.Y  = upVector.Y;
                v.OrthogonalCamera.CameraUpVector.Z  = upVector.Z;
                v.OrthogonalCamera.CameraDirection.X = direction.X;
                v.OrthogonalCamera.CameraDirection.Y = direction.Y;
                v.OrthogonalCamera.CameraDirection.Z = direction.Z;
                v.OrthogonalCamera.ViewToWorldScale  = h;
                //}

                // get current clip volume and compute clipping planes
                ulong previousClipVolumeId = 0;
                try
                {
                    int status = mdlView_getClipBoundaryElement(ref previousClipVolumeId, activeViewNum - 1).ToInt32();
                    if (status == 0)
                    {
                        Element previousClipVolume = MSApp.ActiveModelReference.GetElementByID((long)previousClipVolumeId);
                        var     smartSolids        = MSApp.SmartSolid.ConvertToSmartSolidElement(previousClipVolume).BuildArrayFromContents();
                        if (smartSolids.Length > 0)
                        {
                            // just consider one solid for now
                            SmartSolidElement clipVolumeSolid = smartSolids[0].AsSmartSolidElement;
                            var surfaces = clipVolumeSolid.ExtractAllSurfaceFromSolid().BuildArrayFromContents();
                            List <ClippingPlane> clippingPlanes = new List <ClippingPlane>();
                            foreach (Element surface in surfaces)
                            {
                                ComplexShapeElement surfaceShape = surface.AsComplexShapeElement();
                                var vertices = surfaceShape.ConstructVertexList(0.1); // arbitrary tolerance for now
                                if (vertices.Length > 0)
                                {
                                    // produce BCF clipping planes
                                    Point3d       location      = MSApp.Point3dScale(MSApp.Point3dAdd(clipVolumeSolid.Origin, vertices[0]), unitFactor);
                                    ClippingPlane clippingPlane = new ClippingPlane()
                                    {
                                        Direction = new Direction()
                                        {
                                            X = surfaceShape.Normal.X, Y = surfaceShape.Normal.Y, Z = surfaceShape.Normal.Z
                                        },
                                        Location = new Classes.BCF2.Point()
                                        {
                                            X = location.X, Y = location.Y, Z = location.Z
                                        }
                                    };
                                    clippingPlanes.Add(clippingPlane);
                                }
                            }
                            // add to BCF clipping planes
                            v.ClippingPlanes = clippingPlanes.ToArray();
                        }
                    }
                }
                catch (Exception ex)
                {
                    // do nothing just for catching the exception when clip volume not found, element not found, or not being converted to smart solid
                }

                return(v);
            }
            catch (System.Exception ex1)
            {
                MessageBox.Show("exception: " + ex1, "Error!");
            }
            return(null);
        }