应用程序: Site

Revit平台: 所有

Revit版本: 2014.0

首次发布于: 2014.0

编程语言: C#

技能水平: 中等

类别: 元素

类型: 外部应用程序

主题:Site

概要:

包括TopographySurfaceSiteSubRegion编辑工具,其中包括添加预定义点区域、更改点高程、移动点和删除点。

相关类:

Autodesk.Revit.UI.IExternalCommand

Autodesk.Revit.DB.Architecture.TopographySurface

Autodesk.Revit.DB.Architecture.SiteSubRegion

Autodesk.Revit.DB.Architecture.TopographyEditScope

项目文件:

· Application.cs - 实现Revit插件接口IExternalApplication

· SiteAddRetainingPondCommand.cs - 添加一个新的圆形蓄水池到用户选择的TopographySurface的命令。

· SiteDeleteRegionAndPointsCommand.cs - 删除一个子区域和其中包含的所有地形表面点的命令。

· SiteLowerTerrainInRegionCommand.cs - 将一个子区域中包含的所有点下降3英尺的命令。

· SiteMoveRegionAndPointsCommand.cs - 将子区域及其包含的点移动到宿主表面上新的位置的命令。

· SiteNormalizeTerrainInRegionCommand.cs - 将区域中的所有点正常化到平均海拔高度的命令。

· SiteRaiseTerrainInRegionCommand.cs - 提起子区域中包含的所有点3英尺的命令。

· SiteEditingUtils.cs - 用于现场编辑命令的数据库级别工具。

· SiteUIUtils.cs - 用于现场编辑命令的用户界面工具。

描述:

该示例提供以下功能。

· 在用户指定的位置自动创建地形家族(圆形蓄水池)。

· 将子区域及其包含的点移动到宿主表面上的另一个位置。

· 提升和降低子区域中的地形。

· 将子区域中的地形通过移动所有点到平均海拔高度来正常化。

删除一个子区域及其中包含的点

说明:

打开至少包含一个TopographySurfaceRevit项目。切换到“Add-ins”选项卡。

1. 选择“Add Pond”在表面添加新的蓄水池。子区域和地形点会自动计算和创建。如果模型中存在多个地形表面,会提示你选择宿主表面。然后选择池子的位置。

2. 选择“Move Region”将子区域及其包含的点移动到新位置。选择子区域,然后选择目标位置。

3. 选择“Delete Region”删除所选子区域及其包含的点。

4. 选择“Raise/Lower/Normalize Terrain”操纵所选子区域的高程。

源代码:

完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码

Application.cs

//
// (C) Copyright 2003-2019 by Autodesk, Inc. All rights reserved.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM 'AS IS' AND WITH ALL ITS FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable. 
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Autodesk;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;
using System.Windows.Media.Imaging;
using System.Windows;
namespace Revit.SDK.Samples.Site.CS
{
    /// <summary>
    /// Implements the Revit add-in interface IExternalApplication
    /// </summary>
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
    public class Application : IExternalApplication
    {
        #region IExternalApplication Members
        /// <summary>
        /// Implements the OnShutdown event
        /// </summary>
        /// <param name="application"></param>
        /// <returns></returns>
        public Result OnShutdown(UIControlledApplication application)
        {
            return Result.Succeeded;
        }
        /// <summary>
        /// Implements the OnStartup event
        /// </summary>
        /// <param name="application"></param>
        /// <returns></returns>
        public Result OnStartup(UIControlledApplication application)
        {
            CreateSitePanel(application);
            return Result.Succeeded;
        }
        #endregion
        private void CreateSitePanel(UIControlledApplication application)
        {
            RibbonPanel rp = application.CreateRibbonPanel("Site");
            PushButtonData addPond = new PushButtonData("Site_Add_Pond", "Add Pond",
                                                            addAssemblyPath,
                                                            typeof(Revit.SDK.Samples.Site.CS.SiteAddRetainingPondCommand).FullName);
            SetIconsForPushButtonData(addPond, Revit.SDK.Samples.Site.CS.Properties.Resources.AddPond);
            PushButton pondPB = rp.AddItem(addPond) as PushButton;
            PushButtonData moveRegion = new PushButtonData("Site_Move_Region", "Move Region",
                                                            addAssemblyPath,
                                                            typeof(Revit.SDK.Samples.Site.CS.SiteMoveRegionAndPointsCommand).FullName);
            SetIconsForPushButtonData(moveRegion, Revit.SDK.Samples.Site.CS.Properties.Resources.MoveRegion);
            PushButtonData deleteRegion = new PushButtonData("Site_Delete_Region", "Delete Region",
                                                            addAssemblyPath,
                                                            typeof(Revit.SDK.Samples.Site.CS.SiteDeleteRegionAndPointsCommand).FullName);
            SetIconsForPushButtonData(deleteRegion, Revit.SDK.Samples.Site.CS.Properties.Resources.DeleteRegion);
            rp.AddStackedItems(moveRegion, deleteRegion);
            PushButtonData raiseTerrain = new PushButtonData("Site_Raise_Terrain", "Raise Terrain",
                                                            addAssemblyPath,
                                                            typeof(Revit.SDK.Samples.Site.CS.SiteRaiseTerrainInRegionCommand).FullName);
            SetIconsForPushButtonData(raiseTerrain, Revit.SDK.Samples.Site.CS.Properties.Resources.RaiseTerrain);
            PushButtonData lowerTerrain = new PushButtonData("Site_Lower_Terrain", "Lower Terrain",
                                                            addAssemblyPath,
                                                            typeof(Revit.SDK.Samples.Site.CS.SiteLowerTerrainInRegionCommand).FullName);
            SetIconsForPushButtonData(lowerTerrain, Revit.SDK.Samples.Site.CS.Properties.Resources.LowerTerrain);
            PushButtonData normalizeTerrain = new PushButtonData("Site_Normalize_Terrain", "Normalize Terrain",
                                                            addAssemblyPath,
                                                            typeof(Revit.SDK.Samples.Site.CS.SiteNormalizeTerrainInRegionCommand).FullName);
            SetIconsForPushButtonData(normalizeTerrain, Revit.SDK.Samples.Site.CS.Properties.Resources.SiteNormalize);
            rp.AddStackedItems(raiseTerrain, lowerTerrain, normalizeTerrain);
        }
        /// <summary>
        /// Utility for adding icons to the button.
        /// </summary>
        /// <param name="button">The push button.</param>
        /// <param name="icon">The icon.</param>
        private static void SetIconsForPushButtonData(PushButtonData button, System.Drawing.Icon icon)
        {
            button.LargeImage = GetStdIcon(icon);
            button.Image = GetSmallIcon(icon);
        }
        /// <summary>
        /// Gets the standard sized icon as a BitmapSource.
        /// </summary>
        /// <param name="icon">The icon.</param>
        /// <returns>The BitmapSource.</returns>
        private static BitmapSource GetStdIcon(System.Drawing.Icon icon)
        {
            return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                icon.Handle,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());
        }
        /// <summary>
        /// Gets the small sized icon as a BitmapSource.
        /// </summary>
        /// <param name="icon">The icon.</param>
        /// <returns>The BitmapSource.</returns>
        private static BitmapSource GetSmallIcon(System.Drawing.Icon icon)
        {
            System.Drawing.Icon smallIcon = new System.Drawing.Icon(icon, new System.Drawing.Size(16, 16));
            return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                smallIcon.Handle,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());
        }
        /// <summary>
        /// The path to this add-in assembly.
        /// </summary>
        static String addAssemblyPath = typeof(Revit.SDK.Samples.Site.CS.Application).Assembly.Location;
    }
}

SiteAddRetainingPondCommand.cs

//
// (C) Copyright 2003-2019 by Autodesk, Inc. All rights reserved.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM 'AS IS' AND WITH ALL ITS FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable. 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Architecture;
namespace Revit.SDK.Samples.Site.CS
{
    /// <summary>
    /// A command that adds a new circular retaining pond to a TopographySurface where the user selects.
    /// </summary>
    /// <remarks>This command demonstrates how the Site API supports creation of standard topography "families" representing
    /// commonly used landscape structures.</remarks>
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    class SiteAddRetainingPondCommand : IExternalCommand
    {
        #region IExternalCommand Members
        /// <summary>
        /// Implementation of the external command.
        /// </summary>
        /// <param name="commandData"></param>
        /// <param name="message"></param>
        /// <param name="elements"></param>
        /// <returns></returns>
        public Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
        {
            AddNewRetainingPond(commandData.Application.ActiveUIDocument, 32);
            return Result.Succeeded;
        }
        /// <summary>
        /// Adds a new retaining pond.
        /// </summary>
        /// <param name="uiDoc">The document.</param>
        /// <param name="pondRadius">The radius of the pond.</param>
        private void AddNewRetainingPond(UIDocument uiDoc, double pondRadius)
        {
            Document doc = uiDoc.Document;
            // Find toposurfaces
            FilteredElementCollector tsCollector = new FilteredElementCollector(doc);
            tsCollector.OfClass(typeof(TopographySurface));
            IEnumerable<TopographySurface> tsEnumerable = tsCollector.Cast<TopographySurface>().Where<TopographySurface>(ts => !ts.IsSiteSubRegion);
            int count = tsEnumerable.Count<TopographySurface>();
            // If there is only on surface, use it.  If there is more than one, let the user select the target.
            TopographySurface targetSurface = null;
            if (count > 1) // tmp
            {
                targetSurface = SiteUIUtils.PickTopographySurface(uiDoc);
            }
            else
            {
                targetSurface = tsEnumerable.First<TopographySurface>();
            }
            // Pick point and project to plane at toposurface average elevation
            XYZ point = SiteUIUtils.PickPointNearToposurface(uiDoc, targetSurface, "Pick point for center of pond.");
            double elevation = point.Z;
            // Add subregion first, so that any previously existing points can be removed to avoid distorting the new region
            // Find material "Water"
            FilteredElementCollector collector = new FilteredElementCollector(doc);
            collector.OfClass(typeof(Material));
            Material mat = collector.Cast<Material>().FirstOrDefault<Material>(m => m.Name == "Water");
            // Create subregion curves
            List<Curve> curves = new List<Curve>();
            curves.Add(Arc.Create(point, pondRadius, 0, Math.PI, XYZ.BasisX, XYZ.BasisY));
            curves.Add(Arc.Create(point, pondRadius, Math.PI, 2 * Math.PI, XYZ.BasisX, XYZ.BasisY));
            CurveLoop curveLoop = CurveLoop.Create(curves);
            List<CurveLoop> curveLoops = new List<CurveLoop>();
            curveLoops.Add(curveLoop);
            // All changes are added to one transaction group - will create one undo item
            using (TransactionGroup addGroup = new TransactionGroup(doc, "Add pond group"))
            {
                addGroup.Start();
                IList<XYZ> existingPoints = null;
                // Transacton for adding subregion.
                using (Transaction t2 = new Transaction(doc, "Add subregion"))
                {
                    t2.Start();
                    SiteSubRegion region = SiteSubRegion.Create(doc, curveLoops, targetSurface.Id);
                    if (mat != null)
                    {
                        region.TopographySurface.MaterialId = mat.Id;
                    }
                    t2.Commit();
                    // The boundary points for the subregion cannot be deleted, since they are generated
                    // to represent the subregion boundary rather than representing real points in the host.
                    // Get non-boundary points only to be deleted.
                    existingPoints = SiteEditingUtils.GetNonBoundaryPoints(region.TopographySurface);
                    // Average elevation of all points in the subregion to use as base elevation for the pond topography
                    elevation = SiteEditingUtils.GetAverageElevation(region.TopographySurface.GetPoints());
                }
                // Add the topography points to the target surface via edit scope.
                using (TopographyEditScope editScope = new TopographyEditScope(doc, "Edit TS"))
                {
                    editScope.Start(targetSurface.Id);
                    // Transaction for points changes
                    using (Transaction t = new Transaction(doc, "Add points"))
                    {
                        t.Start();
                        // Delete existing points first to avoid conflict
                        if (existingPoints.Count > 0)
                        {
                            targetSurface.DeletePoints(existingPoints);
                        }
                        // Generate list of points to add
                        IList<XYZ> points = SiteEditingUtils.GeneratePondPointsSurrounding(new XYZ(point.X, point.Y, elevation - 3), pondRadius);
                        targetSurface.AddPoints(points);
                        t.Commit();
                    }
                    editScope.Commit(new TopographyEditFailuresPreprocessor());
                }
                addGroup.Assimilate();
            }
        }
        #endregion
    }
}

SiteDeleteRegionAndPointsCommand.cs

//
// (C) Copyright 2003-2019 by Autodesk, Inc. All rights reserved.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM 'AS IS' AND WITH ALL ITS FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable. 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
namespace Revit.SDK.Samples.Site.CS
{
    /// <summary>
    /// A command that deletes a subregion and all topography surface points it contains.
    /// </summary>
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    class SiteDeleteRegionAndPointsCommand: IExternalCommand
    {
        #region IExternalCommand Members
        /// <summary>
        /// Implementation of the command.
        /// </summary>
        /// <param name="commandData"></param>
        /// <param name="message"></param>
        /// <param name="elements"></param>
        /// <returns></returns>
        public Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
        {
            DeleteSubregionAndPoints(commandData.Application.ActiveUIDocument);
            return Result.Succeeded;
        }
        /// <summary>
        /// Deletes a subregion and all topography surface points it contains.
        /// </summary>
        /// <param name="uiDoc">The document.</param>
        public void DeleteSubregionAndPoints(UIDocument uiDoc)
        {
            Document doc = uiDoc.Document;
            // Select subregion
            TopographySurface subregion = SiteUIUtils.PickSubregion(uiDoc);
            TopographySurface toposurface = SiteEditingUtils.GetTopographySurfaceHost(subregion);
            IList<XYZ> points = SiteEditingUtils.GetNonBoundaryPoints(subregion);
            // All changes are added to one transaction group - will create one undo item
            using (TransactionGroup deleteGroup = new TransactionGroup(doc, "Delete region"))
            {
                deleteGroup.Start();
                // Edit scope to delete points- if there are points in the region
                if (points.Count > 0)
                {
                    using (TopographyEditScope editScope = new TopographyEditScope(doc, "Edit TS"))
                    {
                        editScope.Start(toposurface.Id);
                        // Transaction for point deletion
                        using (Transaction t = new Transaction(doc, "Delete points"))
                        {
                            t.Start();
                            toposurface.DeletePoints(points);
                            t.Commit();
                        }
                        editScope.Commit(new TopographyEditFailuresPreprocessor());
                    }
                }
                // Transaction to delete subregion
                using (Transaction t2 = new Transaction(doc, "Delete subregion"))
                {
                    t2.Start();
                    doc.Delete(subregion.Id);
                    t2.Commit();
                }
                deleteGroup.Assimilate();
            }
        }
        #endregion
    }
}