Files
RookieStation/RookieStation/CmdPlaceWallFinishes.cs
2021-06-04 16:43:37 +08:00

168 lines
8.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}