diff --git a/BuildingCoder/BuildingCoder/CmdLinkedFileElements.cs b/BuildingCoder/BuildingCoder/CmdLinkedFileElements.cs index f7d18c49..f5db0b11 100644 --- a/BuildingCoder/BuildingCoder/CmdLinkedFileElements.cs +++ b/BuildingCoder/BuildingCoder/CmdLinkedFileElements.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; @@ -148,5 +149,61 @@ FilteredElementCollector a return Result.Cancelled; } + + #region AddFaceBasedFamilyToLinks + public void AddFaceBasedFamilyToLinks( Document doc ) + { + ElementId alignedLinkId = new ElementId( 125929 ); + + // Get symbol + + ElementId symbolId = new ElementId( 126580 ); + + FamilySymbol fs = doc.GetElement( symbolId ) + as FamilySymbol; + + // Aligned + + RevitLinkInstance linkInstance = doc.GetElement( + alignedLinkId ) as RevitLinkInstance; + + Document linkDocument = linkInstance + .GetLinkDocument(); + + FilteredElementCollector wallCollector + = new FilteredElementCollector( linkDocument ); + + wallCollector.OfClass( typeof( Wall ) ); + + Wall targetWall = wallCollector.FirstElement() + as Wall; + + Reference exteriorFaceRef + = HostObjectUtils.GetSideFaces( + targetWall, ShellLayerType.Exterior ) + .First(); + + Reference linkToExteriorFaceRef + = exteriorFaceRef.CreateLinkReference( + linkInstance ); + + Line wallLine = ( targetWall.Location + as LocationCurve ).Curve as Line; + + XYZ wallVector = ( wallLine.GetEndPoint( 1 ) + - wallLine.GetEndPoint( 0 ) ).Normalize(); + + using( Transaction t = new Transaction( doc ) ) + { + t.Start( "Add to face" ); + + doc.Create.NewFamilyInstance( + linkToExteriorFaceRef, XYZ.Zero, + wallVector, fs ); + + t.Commit(); + } + } + #endregion // AddFaceBasedFamilyToLinks } } diff --git a/BuildingCoder/BuildingCoder/CmdViewsShowingElements.cs b/BuildingCoder/BuildingCoder/CmdViewsShowingElements.cs index 47e2c6e1..54fc6f2c 100644 --- a/BuildingCoder/BuildingCoder/CmdViewsShowingElements.cs +++ b/BuildingCoder/BuildingCoder/CmdViewsShowingElements.cs @@ -2,7 +2,7 @@ // // CmdViewsShowingElements.cs - determine all views displaying a given set of elements // -// By cshha, +// By Colin, cshha, // http://forums.autodesk.com/t5/user/viewprofilepage/user-id/1162312 // published in // http://forums.autodesk.com/t5/Revit-API/Revision-help-which-views-show-this-object/m-p/5029772 @@ -155,4 +155,198 @@ IEnumerable targets return Result.Succeeded; } } + + #region Align two views + /// + /// http://forums.autodesk.com/t5/Revit-API/Align-views-on-sheet/td-p/5048740 + /// + class CmdAlignTwoViews : IExternalCommand + { + const BuiltInParameter _bipFarOffset + = BuiltInParameter.VIEWER_BOUND_OFFSET_FAR; + + 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; + } + } + #endregion // Align two views + } diff --git a/BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs b/BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs index 568615d0..c475e8d5 100644 --- a/BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs +++ b/BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs @@ -34,6 +34,7 @@ // 2014-04-11 2014.0.109.0 renamed CmdSlopedFloor.cs to CmdCreateSlopedSlab.cs, implemented CmdCategorySupportsTypeParameter // 2014-04-14 2015.0.109.0 migrated to Revit 2015 // 2014-05-14 2015.0.110.0 CmdViewsShowingElements +// 2014-07-21 2015.0.110.1 AddFaceBasedFamilyToLinks // -[assembly: AssemblyVersion( "2015.0.110.0" )] -[assembly: AssemblyFileVersion( "2015.0.110.0" )] +[assembly: AssemblyVersion( "2015.0.110.1" )] +[assembly: AssemblyFileVersion( "2015.0.110.1" )]