/// <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); }