public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; using (Transaction trans = new Transaction(doc)) { trans.Start("Place views"); View frontView = doc.GetElement(new ElementId(180041)) as View; View leftView = doc.GetElement(new ElementId(180032)) as View; AssemblyInstance assemblyInst = doc.GetElement(new ElementId(179915)) as AssemblyInstance; ViewSheet vSheet = doc.GetElement(new ElementId(180049)) as ViewSheet; // Assume that the scale is the same for both views int scale = frontView.Scale; leftView.Scale = scale; // Save current crop box values BoundingBoxXYZ savedBoxFront = null, savedBoxLeft = null; bool frontCropActive, frontCropVisible, leftCropActive, leftCropVisible; double farClipFront = 0, farClipLeft = 0; Parameter param; Transform transformFront = frontView.CropBox.Transform; Transform transformLeft = leftView.CropBox.Transform; // Save old values. I have to store the farclip and reset it later savedBoxFront = frontView.CropBox; frontCropActive = frontView.CropBoxActive; frontCropVisible = frontView.CropBoxVisible; param = frontView.get_Parameter(_bipFarOffset); if (param != null) { farClipFront = param.AsDouble(); } savedBoxLeft = leftView.CropBox; leftCropActive = leftView.CropBoxActive; leftCropVisible = leftView.CropBoxVisible; param = leftView.get_Parameter(_bipFarOffset); if (param != null) { farClipLeft = param.AsDouble(); } // Here my approach differs from yours. // I'm starting from the old bounding box to // ensure that I get the correct transformation. // I tried to create a new Transformation but // this didn't work. BoundingBoxXYZ newBoxFront = frontView.CropBox; newBoxFront.set_MinEnabled(0, true); newBoxFront.set_MinEnabled(1, true); newBoxFront.set_MinEnabled(2, true); newBoxFront.Min = new XYZ(-2000, -2000, 0); newBoxFront.set_MaxEnabled(0, true); newBoxFront.set_MaxEnabled(1, true); newBoxFront.set_MaxEnabled(2, true); newBoxFront.Max = new XYZ(2000, 2000, 0); BoundingBoxXYZ newBoxLeft = leftView.CropBox; newBoxLeft.set_MinEnabled(0, true); newBoxLeft.set_MinEnabled(1, true); newBoxLeft.set_MinEnabled(2, true); newBoxLeft.Min = new XYZ(-2000, -2000, 0); newBoxLeft.set_MaxEnabled(0, true); newBoxLeft.set_MaxEnabled(1, true); newBoxLeft.set_MaxEnabled(2, true); newBoxLeft.Max = new XYZ(2000, 2000, 0); frontView.CropBox = newBoxFront; leftView.CropBox = newBoxLeft; doc.Regenerate(); frontView.CropBoxActive = true; leftView.CropBoxActive = true; doc.Regenerate(); ElementId vid = vSheet.Id; XYZ p = XYZ.Zero; var vpFront = Viewport.Create(doc, vid, frontView.Id, p); var vpLeft = Viewport.Create(doc, vid, leftView.Id, p); doc.Regenerate(); // Align lower left - works // because crop boxes are same Outline outline1 = vpFront.GetBoxOutline(); Outline outline2 = vpLeft.GetBoxOutline(); XYZ min1 = outline1.MinimumPoint; XYZ min2 = outline2.MinimumPoint; XYZ diffToMove = min1 - min2; ElementTransformUtils.MoveElement(doc, vpLeft.Id, diffToMove); // Tranform the view such that the origin // of the assemblyInstance for each view is // on the middle of the sheet // 1) Move the views such that the assembly // Origin lies on the same on the origin of sheet p = assemblyInst.GetTransform().Origin; XYZ v = transformFront.Origin - p; XYZ translation = new XYZ( v.DotProduct(transformFront.BasisX), v.DotProduct(transformFront.BasisY), 0) / scale; ElementTransformUtils.MoveElement(doc, vpFront.Id, translation); v = transformLeft.Origin - p; translation = new XYZ( v.DotProduct(transformLeft.BasisX), v.DotProduct(transformLeft.BasisY), 0) / scale; ElementTransformUtils.MoveElement(doc, vpLeft.Id, translation); // 2) Move the views such that the assembly // origin lies on the center of the sheet double width = 840 * 0.0032808399; double height = 594 * 0.0032808399; XYZ sheetMidpoint = (vSheet.Origin + XYZ.BasisX * width + XYZ.BasisY * height) / 2.0; ElementTransformUtils.MoveElement(doc, vpFront.Id, sheetMidpoint); ElementTransformUtils.MoveElement(doc, vpLeft.Id, sheetMidpoint); // Once the views are on the middle, move the // left view to the left of the front view: // Do the correct translations to suit the // defined layout translation = XYZ.BasisX * ( -((outline1.MinimumPoint.X - outline1.MinimumPoint.X) / 2 + (outline2.MinimumPoint.X - outline2.MinimumPoint.X) + 1)); ElementTransformUtils.MoveElement(doc, vpLeft.Id, translation); doc.Regenerate(); // Restore view crop boxes frontView.CropBox = savedBoxFront; frontView.CropBoxActive = frontCropActive; frontView.CropBoxVisible = frontCropVisible; param = frontView.get_Parameter(_bipFarOffset); if (param != null) { param.Set(farClipFront); } leftView.CropBox = savedBoxLeft; leftView.CropBoxActive = leftCropActive; leftView.CropBoxVisible = leftCropVisible; param = leftView.get_Parameter(_bipFarOffset); if (param != null) { param.Set(farClipLeft); } trans.Commit(); } return(Result.Succeeded); }
private static BoundingBoxXYZ GetBoundingBox(List <Element> elements) { BoundingBoxXYZ boundingBox = new BoundingBoxXYZ(); try { boundingBox.Enabled = true; for (int i = 0; i < 3; i++) { boundingBox.set_MinEnabled(i, true); boundingBox.set_MaxEnabled(i, true); boundingBox.set_BoundEnabled(0, i, true); boundingBox.set_BoundEnabled(1, i, true); } BoundingBoxXYZ tempBoundingBox = elements.First().get_BoundingBox(null); if (null != tempBoundingBox) { tempBoundingBox.Enabled = true; double maxX = tempBoundingBox.Max.X; double maxY = tempBoundingBox.Max.Y; double maxZ = tempBoundingBox.Max.Z; double minX = tempBoundingBox.Min.X; double minY = tempBoundingBox.Min.Y; double minZ = tempBoundingBox.Min.Z; foreach (Element element in elements) { try { BoundingBoxXYZ bbBox = element.get_BoundingBox(null); if (null != boundingBox) { bbBox.Enabled = true; if (bbBox.Max.X > maxX) { maxX = bbBox.Max.X; } if (bbBox.Max.Y > maxY) { maxY = bbBox.Max.Y; } if (bbBox.Max.Z > maxZ) { maxZ = bbBox.Max.Z; } if (bbBox.Min.X < minX) { minX = bbBox.Min.X; } if (bbBox.Min.Y < minY) { minY = bbBox.Min.Y; } if (bbBox.Min.Z < minZ) { minZ = bbBox.Min.Z; } } } catch { continue; } } XYZ xyzMax = new XYZ(maxX, maxY, maxZ); XYZ xyzMin = new XYZ(minX, minY, minZ); boundingBox.set_Bounds(0, xyzMin); boundingBox.set_Bounds(1, xyzMax); } } catch (Exception ex) { MessageBox.Show("Failed to get bounding box XYZ.\n" + ex.Message, "Get Bounding Box", MessageBoxButtons.OK, MessageBoxIcon.Warning); } return(boundingBox); }
private OrthogonalCamera GetOrthogonalCamera(Dictionary <int, ElementProperties> elementDictionary, string imagePath) { OrthogonalCamera orthoCamera = new OrthogonalCamera(); try { BoundingBoxXYZ boundingBox = new BoundingBoxXYZ(); boundingBox.Enabled = true; for (int i = 0; i < 3; i++) { boundingBox.set_MinEnabled(i, true); boundingBox.set_MaxEnabled(i, true); boundingBox.set_BoundEnabled(0, i, true); boundingBox.set_BoundEnabled(1, i, true); } BoundingBoxXYZ tempBoundingBox = elementDictionary.First().Value.RevitElement.get_BoundingBox(null); tempBoundingBox.Enabled = true; double maxX = tempBoundingBox.Max.X; double maxY = tempBoundingBox.Max.Y; double maxZ = tempBoundingBox.Max.Z; double minX = tempBoundingBox.Min.X; double minY = tempBoundingBox.Min.Y; double minZ = tempBoundingBox.Min.Z; List <ElementId> elementIds = new List <ElementId>(); Dictionary <int, Category> categories = new Dictionary <int, Category>(); foreach (ElementProperties ep in elementDictionary.Values) { Element element = ep.RevitElement; if (null != element) { try { if (!categories.ContainsKey(element.Category.Id.IntegerValue)) { categories.Add(element.Category.Id.IntegerValue, element.Category); } BoundingBoxXYZ bbBox = element.get_BoundingBox(null); bbBox.Enabled = true; elementIds.Add(element.Id); if (null != boundingBox) { if (bbBox.Max.X > maxX) { maxX = bbBox.Max.X; } if (bbBox.Max.Y > maxY) { maxY = bbBox.Max.Y; } if (bbBox.Max.Z > maxZ) { maxZ = bbBox.Max.Z; } if (bbBox.Min.X < minX) { minX = bbBox.Min.X; } if (bbBox.Min.Y < minY) { minY = bbBox.Min.Y; } if (bbBox.Min.Z < minZ) { minZ = bbBox.Min.Z; } } } catch { continue; } } } XYZ xyzMax = new XYZ(maxX, maxY, maxZ); XYZ xyzMin = new XYZ(minX, minY, minZ); boundingBox.set_Bounds(0, xyzMin); boundingBox.set_Bounds(1, xyzMax); ViewFamilyType view3dFamilyType = null; FilteredElementCollector collector = new FilteredElementCollector(m_doc); List <Element> elements = collector.OfClass(typeof(ViewFamilyType)).ToElements().ToList(); foreach (Element element in elements) { ViewFamilyType viewfamilytype = element as ViewFamilyType; if (viewfamilytype.ViewFamily == ViewFamily.ThreeDimensional) { view3dFamilyType = viewfamilytype; break; } } if (null != view3dFamilyType) { using (TransactionGroup transGroup = new TransactionGroup(m_doc)) { transGroup.Start("Start Creating View 3D"); using (Transaction trans = new Transaction(m_doc)) { trans.Start("Create View"); View3D view3d = View3D.CreateIsometric(m_doc, view3dFamilyType.Id); view3d.SetSectionBox(boundingBox); view3d.GetSectionBox().Enabled = true; view3d.DetailLevel = ViewDetailLevel.Fine; foreach (Category category in categories.Values) { if (category.get_AllowsVisibilityControl(view3d)) { #if RELEASE2017 || RELEASE2018 view3d.SetCategoryHidden(category.Id, false); #else view3d.SetVisibility(category, true); #endif } } view3d.get_Parameter(BuiltInParameter.MODEL_GRAPHICS_STYLE).Set(4); //m_app.ActiveUIDocument.ActiveView = view3d; //m_app.ActiveUIDocument.RefreshActiveView(); XYZ eyePostion = view3d.GetOrientation().EyePosition; Point viewPoint = new Point(); viewPoint.X = eyePostion.X; viewPoint.Y = eyePostion.Y; viewPoint.Z = eyePostion.Z; orthoCamera.CameraViewPoint = viewPoint; XYZ forwardDirection = view3d.GetOrientation().ForwardDirection; Direction fDirection = new Direction(); fDirection.X = forwardDirection.X; fDirection.Y = forwardDirection.Y; fDirection.Z = forwardDirection.Z; orthoCamera.CameraDirection = fDirection; XYZ upDirection = view3d.GetOrientation().UpDirection; Direction uDirection = new Direction(); uDirection.X = upDirection.X; uDirection.Y = upDirection.Y; uDirection.Z = upDirection.Z; orthoCamera.CameraUpVector = uDirection; orthoCamera.ViewToWorldScale = view3d.Scale; m_app.ActiveUIDocument.RefreshActiveView(); trans.Commit(); trans.Start("Export Image"); //create snapshot.png ImageExportOptions option = new ImageExportOptions(); option.HLRandWFViewsFileType = ImageFileType.PNG; option.ImageResolution = ImageResolution.DPI_300; option.ShouldCreateWebSite = false; option.ExportRange = ExportRange.SetOfViews; option.FilePath = imagePath; List <ElementId> viewIds = new List <ElementId>(); viewIds.Add(view3d.Id); option.SetViewsAndSheets(viewIds); if (ImageExportOptions.IsValidFileName(option.FilePath)) { m_doc.ExportImage(option); } trans.Commit(); } transGroup.RollBack(); } if (File.Exists(imagePath)) { File.Delete(imagePath); } string[] fileNames = Directory.GetFiles(Path.GetDirectoryName(imagePath), "snapshot*"); foreach (string fName in fileNames) { if (Path.GetExtension(fName) == ".png" || Path.GetExtension(fName) == ".jpg") { File.Move(fName, imagePath); if (File.Exists(fName)) { File.Delete(fName); } } } } } catch (Exception ex) { MessageBox.Show("Failed to get the orthogonal camera.\n" + ex.Message, "Get Orthogonal Camera", MessageBoxButton.OK, MessageBoxImage.Warning); } return(orthoCamera); }