public static SmartSolidElement CreateChameferedBox(this SmartSolid ss, double width, double length, double height, ChameferFace ExcludeChameferFace = ChameferFace.All, double chameferLength = 0) { Application app = Program.COM_App; SmartSolidElement boxele = ss.CreateSlab(null, width, length, height); if ((ExcludeChameferFace != ChameferFace.All) && (chameferLength != 0) && (new double[] { width, length, height }.Min() / 2 >= chameferLength)) { double halfwidth = width / 2.0, halflength = length / 2.0, halfheight = height / 2.0; Point3d[] middleedgePoints = { app.Point3dFromXYZ(halfwidth, -halflength, 0), app.Point3dFromXYZ(halfwidth, halflength, 0), app.Point3dFromXYZ(-halfwidth, halflength, 0), app.Point3dFromXYZ(-halfwidth, -halflength, 0), app.Point3dFromXYZ(0, -halflength, -halfheight), app.Point3dFromXYZ(0, -halflength, halfheight), app.Point3dFromXYZ(0, halflength, halfheight), app.Point3dFromXYZ(0, halflength, -halfheight), app.Point3dFromXYZ(halfwidth, 0, -halfheight), app.Point3dFromXYZ(halfwidth, 0, halfheight), app.Point3dFromXYZ(-halfwidth, 0, halfheight), app.Point3dFromXYZ(-halfwidth, 0, -halfheight) }; Dictionary <int, int[]> vertexedgerelation = new Dictionary <int, int[]> { { 0, new int[] { 0, 5, 9 } }, { 1, new int[] { 1, 6, 9 } }, { 2, new int[] { 2, 6, 10 } }, { 3, new int[] { 3, 5, 10 } }, { 4, new int[] { 0, 4, 8 } }, { 5, new int[] { 1, 7, 8 } }, { 6, new int[] { 2, 7, 11 } }, { 7, new int[] { 3, 4, 11 } } }; Dictionary <string, int[]> faceedgerelation = new Dictionary <string, int[]> { { "Front", new int[] { 0, 3, 4, 5 } }, { "Back", new int[] { 1, 2, 6, 7 } }, { "Right", new int[] { 0, 1, 8, 9 } }, { "Left", new int[] { 2, 3, 10, 11 } }, { "Top", new int[] { 5, 6, 9, 10 } }, { "Bottom", new int[] { 4, 7, 8, 11 } } }; List <int> chameferededge = new List <int>(); for (int i = 0; i < 12; i++) { chameferededge.Add(i); } if ((ExcludeChameferFace & ChameferFace.Front) != 0) { chameferededge = chameferededge.Except(faceedgerelation["Front"]).ToList(); } if ((ExcludeChameferFace & ChameferFace.Back) != 0) { chameferededge = chameferededge.Except(faceedgerelation["Back"]).ToList(); } if ((ExcludeChameferFace & ChameferFace.Top) != 0) { chameferededge = chameferededge.Except(faceedgerelation["Top"]).ToList(); } if ((ExcludeChameferFace & ChameferFace.Bottom) != 0) { chameferededge = chameferededge.Except(faceedgerelation["Bottom"]).ToList(); } if ((ExcludeChameferFace & ChameferFace.Right) != 0) { chameferededge = chameferededge.Except(faceedgerelation["Right"]).ToList(); } if ((ExcludeChameferFace & ChameferFace.Left) != 0) { chameferededge = chameferededge.Except(faceedgerelation["Left"]).ToList(); } for (int i = 0; i < chameferededge.Count; i++) { boxele = ss.ChamferEdge(boxele, ref middleedgePoints[chameferededge[i]], chameferLength, chameferLength, true); } if (((ExcludeChameferFace & ChameferFace.XAxis) == 0) && ((ExcludeChameferFace & ChameferFace.YAxis) == 0) && ((ExcludeChameferFace & ChameferFace.ZAxis) == 0)) { double halfwidth_wcham = halfwidth - chameferLength, halflength_wcham = halflength - chameferLength, halfheight_wcham = halfheight - chameferLength; Point3d[] champlusPoints = { app.Point3dFromXYZ(halfwidth_wcham, -halflength_wcham, halfheight), app.Point3dFromXYZ(halfwidth_wcham, -halflength, halfheight_wcham), app.Point3dFromXYZ(halfwidth, -halflength_wcham, halfheight_wcham) }; ShapeElement champlus_shape = app.CreateShapeElement1(null, ref champlusPoints, MsdFillMode.Filled); SmartSolidElement champlus_ele_template = ss.ExtrudeClosedPlanarCurve(champlus_shape, 2 * chameferLength, 0, true); SmartSolidElement[] champlus_eleList = new SmartSolidElement[8]; champlus_eleList[0] = champlus_ele_template.Clone().AsSmartSolidElement; champlus_eleList[1] = champlus_eleList[0].Clone().AsSmartSolidElement; champlus_eleList[1].Mirror(ref middleedgePoints[10], ref middleedgePoints[9]); champlus_eleList[2] = champlus_eleList[1].Clone().AsSmartSolidElement; champlus_eleList[2].Mirror(ref middleedgePoints[5], ref middleedgePoints[6]); champlus_eleList[3] = champlus_eleList[0].Clone().AsSmartSolidElement; champlus_eleList[3].Mirror(ref middleedgePoints[5], ref middleedgePoints[6]); champlus_eleList[4] = champlus_eleList[0].Clone().AsSmartSolidElement; champlus_eleList[4].Mirror3d(ref middleedgePoints[0], ref middleedgePoints[1], ref middleedgePoints[2]); champlus_eleList[5] = champlus_eleList[4].Clone().AsSmartSolidElement; champlus_eleList[5].Mirror(ref middleedgePoints[11], ref middleedgePoints[8]); champlus_eleList[6] = champlus_eleList[5].Clone().AsSmartSolidElement; champlus_eleList[6].Mirror(ref middleedgePoints[4], ref middleedgePoints[7]); champlus_eleList[7] = champlus_eleList[4].Clone().AsSmartSolidElement; champlus_eleList[7].Mirror(ref middleedgePoints[4], ref middleedgePoints[7]); List <int> addplusvertex = new List <int>(); foreach (var verealtion in vertexedgerelation) { if (verealtion.Value.Except(chameferededge).Count() == 0) { addplusvertex.Add(verealtion.Key); } } foreach (var plusindex in addplusvertex) { boxele = ss.SolidSubtract(boxele, champlus_eleList[plusindex]); } } } return(boxele); }
/// <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); }