168 lines
8.1 KiB
C#
168 lines
8.1 KiB
C#
using Autodesk.Revit.DB;
|
||
using Autodesk.Revit.DB.Architecture;
|
||
using Autodesk.Revit.UI;
|
||
using Autodesk.Revit.UI.Selection;
|
||
using RookieStation.Utils;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Runtime.ConstrainedExecution;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Media.Effects;
|
||
|
||
namespace RookieStation.CommonTools
|
||
{
|
||
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
||
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
|
||
internal class CmdPlaceWallFinishes : IExternalCommand
|
||
{
|
||
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
|
||
{
|
||
UIApplication uiapp = commandData.Application;
|
||
UIDocument uidoc = uiapp.ActiveUIDocument;
|
||
Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
|
||
Document doc = uidoc.Document;
|
||
|
||
List<Room> rooms = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).Cast<Room>().ToList();
|
||
if (rooms.Count == 0)
|
||
{
|
||
TaskDialog.Show("温馨提示", "项目中当前没有房间");
|
||
return Result.Cancelled;
|
||
}
|
||
ElementCategoryFilter ecf = new ElementCategoryFilter(BuiltInCategory.OST_Walls);
|
||
ElementCategoryFilter ecf1 = new ElementCategoryFilter(BuiltInCategory.OST_StackedWalls);
|
||
LogicalOrFilter lof = new LogicalOrFilter(ecf, ecf1);
|
||
var walltypes = new FilteredElementCollector(doc).WherePasses(lof).WhereElementIsElementType().Cast<WallType>().ToList();
|
||
WpfWallFinishes finishes = null;
|
||
|
||
string addin_path = typeof(RsApp).Assembly.Location;
|
||
string assembly_directory = System.IO.Path.GetDirectoryName(addin_path);
|
||
AssemblyLoader loader = new AssemblyLoader(assembly_directory);
|
||
try
|
||
{
|
||
loader.HookAssemblyResolve();
|
||
|
||
finishes = new WpfWallFinishes(walltypes);
|
||
System.Windows.Interop.WindowInteropHelper mainUI = new System.Windows.Interop.WindowInteropHelper(finishes)
|
||
{
|
||
Owner = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle
|
||
};
|
||
finishes.ShowDialog();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
TaskDialog.Show("错误", ex.Message);
|
||
}
|
||
finally
|
||
{
|
||
loader.UnhookAssemblyResolve();
|
||
}
|
||
if (finishes.DialogResult != true)
|
||
{
|
||
return Result.Cancelled;
|
||
}
|
||
WallType walltype = finishes.WallType;
|
||
bool iscontinue = true;
|
||
try
|
||
{
|
||
while (iscontinue)
|
||
{
|
||
Reference refer = uidoc.Selection.PickObject(ObjectType.Element, new SelectFilter<Room>(), "请选择布置的房间");
|
||
//walltype包含了叠层墙和基本墙,属于不同族,如果出现名称一样,则会过滤出来两个
|
||
//var walltypes = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).OfClass(typeof(WallType)).WhereElementIsElementType();
|
||
|
||
//var walls = new FilteredElementCollector(doc).OfClass(typeof(Wall));
|
||
//var walltype = walltypes.Where(x => x.Name == "常规 - 200mm").FirstOrDefault() as WallType;
|
||
|
||
Room room = uidoc.Document.GetElement(refer) as Room;
|
||
List<CurveLoop> curveLoopList = new List<CurveLoop>();
|
||
List<ElementId> walltojoin = new List<ElementId>();
|
||
List<List<ElementId>> walltojoinlist = new List<List<ElementId>>();
|
||
var opts = new SpatialElementBoundaryOptions();
|
||
//{
|
||
// SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish
|
||
//};
|
||
double wallwidth = walltype.Width;
|
||
double wallheight = finishes.WallHeight;
|
||
//BuiltInCategory builtInCategory = (BuiltInCategory)walltype.Category.Id.IntegerValue;
|
||
//if (walltype.Kind == WallKind.Stacked)
|
||
//{
|
||
// var li = walltype.GetSubelements();
|
||
// walltype.get
|
||
//}
|
||
//if (walltype.Kind == WallKind.Basic)
|
||
//{
|
||
// var compounds = walltype.GetCompoundStructure();
|
||
// for (int i = 0; i < compounds.LayerCount; i++)
|
||
// {
|
||
// offest += compounds.GetWidth();
|
||
// }
|
||
//}
|
||
|
||
var segementsList = room.GetBoundarySegments(opts);
|
||
|
||
if (segementsList != null)
|
||
{
|
||
foreach (var boundarySegments in segementsList)
|
||
{
|
||
CurveLoop curveLoop = new CurveLoop();
|
||
foreach (var boundarySegment in boundarySegments)
|
||
{
|
||
curveLoop.Append(boundarySegment.GetCurve());
|
||
walltojoin.Add(boundarySegment.ElementId);
|
||
}
|
||
walltojoinlist.Add(walltojoin);
|
||
curveLoopList.Add(curveLoop);
|
||
}
|
||
}
|
||
|
||
doc.Invoke(ts =>
|
||
{
|
||
Plane plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, new XYZ());
|
||
//var mc = doc.Create.NewModelCurveArray(array, SketchPlane.Create(doc, plane));
|
||
for (int i = 0; i < curveLoopList.Count; i++)
|
||
{
|
||
//切线方向叉乘参数中的向量,内侧叉乘-z
|
||
var offestcurveloop = CurveLoop.CreateViaOffset(curveLoopList[i], wallwidth / 2, -XYZ.BasisZ);
|
||
for (int j = 0; j < offestcurveloop.Count(); j++)
|
||
{
|
||
Curve curve = offestcurveloop.ElementAt(j);
|
||
////c的方向叉乘参数中的向量,内侧叉乘-z
|
||
//var lc = c.CreateOffset(100 / 304.8, -XYZ.BasisZ);
|
||
|
||
//var x = curve.ComputeDerivatives(0.5, true).BasisX.CrossProduct(-XYZ.BasisZ).Normalize() * 100 / 304.8;
|
||
//var mc = doc.Create.NewModelCurve(lc, SketchPlane.Create(doc, plane));
|
||
//var mc = doc.Create.NewModelCurve(c, SketchPlane.Create(doc, plane));
|
||
var w = Wall.Create(doc, curve, walltype.Id, doc.ActiveView.GenLevel.Id, wallheight / 304.8, 0 / 304.8, false, false);
|
||
w.get_Parameter(BuiltInParameter.WALL_ATTR_ROOM_BOUNDING).Set(0);
|
||
doc.Regenerate();
|
||
//让门窗可以剪切出来
|
||
if (walltojoinlist[i][j].IntegerValue > 0)
|
||
{
|
||
Element elemtojoin = doc.GetElement(walltojoinlist[i][j]);
|
||
try
|
||
{
|
||
JoinGeometryUtils.JoinGeometry(doc, elemtojoin, w);
|
||
}
|
||
catch (Exception)
|
||
{
|
||
}
|
||
}
|
||
|
||
//WallUtils.AllowWallJoinAtEnd(w, 0);
|
||
//offestcurves.Add(lc);
|
||
}
|
||
}
|
||
}, "创建墙饰面");
|
||
}
|
||
}
|
||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||
{
|
||
return Result.Succeeded;
|
||
}
|
||
|
||
return Result.Succeeded;
|
||
}
|
||
}
|
||
} |