整理代码
This commit is contained in:
277
ShrlAlgoToolkit.RevitAddins/RvCivil/CreateOpeningsViewModel.cs
Normal file
277
ShrlAlgoToolkit.RevitAddins/RvCivil/CreateOpeningsViewModel.cs
Normal file
@@ -0,0 +1,277 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit.UI.Selection;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
|
||||
using ShrlAlgo.Toolkit.Core.Assist;
|
||||
using ShrlAlgoToolkit.Core.Assist;
|
||||
|
||||
namespace ShrlAlgo.RvKits.RvCivil
|
||||
{
|
||||
public partial class CreateOpeningsViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty] private bool addCasing;
|
||||
|
||||
[ObservableProperty] private double distance;
|
||||
|
||||
private readonly string openingsFamilyFolder = $"{Variables.FamilyFolder}Opening";
|
||||
private readonly string casingsFamilyFolder = $"{Variables.FamilyFolder}Casing";
|
||||
private readonly ActionEventHandler handler = new();
|
||||
[ObservableProperty] private FileInfo selectedCasing;
|
||||
[ObservableProperty] private List<FileInfo> casingFiles = [];
|
||||
public CreateOpeningsViewModel()
|
||||
{
|
||||
var files = Directory.GetFiles(casingsFamilyFolder);
|
||||
foreach (var file in files)
|
||||
{
|
||||
CasingFiles.Add(new FileInfo(file));
|
||||
}
|
||||
}
|
||||
[RelayCommand]
|
||||
private void CreateOpenings()
|
||||
{
|
||||
try
|
||||
{
|
||||
handler.Raise(
|
||||
uiapp =>
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
var doc = uidoc.Document;
|
||||
var reference = uidoc.Selection.PickObject(
|
||||
ObjectType.Element,
|
||||
new FuncFilter(e => e is Floor or ExtrusionRoof or FootPrintRoof or Ceiling or Wall or FamilyInstance),
|
||||
"请选择需要开洞的图元"
|
||||
);
|
||||
var elementToOpen = doc.GetElement(reference);
|
||||
|
||||
var intersectsElement = new ElementIntersectsElementFilter(elementToOpen);
|
||||
var mepCurves = doc.OfCollector().WherePasses(intersectsElement).Where(e => e is MEPCurve).Cast<MEPCurve>().ToList();
|
||||
|
||||
if (doc.ActiveView.ViewType != ViewType.ThreeD)
|
||||
{
|
||||
MessageBox.Show("请选择三维视图", "提示");
|
||||
}
|
||||
doc.InvokeGroup(
|
||||
_ =>
|
||||
{
|
||||
foreach (var mepCurve in mepCurves)
|
||||
{
|
||||
doc.Invoke(
|
||||
_ =>
|
||||
{
|
||||
//var level = new FilteredElementCollector(doc, doc.ActiveView.Id).OfCollector(BuiltInCategory.OST_Levels).OfClass(typeof(Level)).FirstElement();
|
||||
doc.ActiveView.SketchPlane = SketchPlane.Create(
|
||||
doc,
|
||||
elementToOpen.LevelId);
|
||||
},
|
||||
"设置工作平面");
|
||||
var curve = mepCurve.GetCurve();
|
||||
var conn = mepCurve.GetConnectors().OfType<Connector>().FirstOrDefault();
|
||||
double diameter = default;
|
||||
double width = default;
|
||||
double height = default;
|
||||
//double angle = default;
|
||||
Family openingFamily = null;
|
||||
var faceNormal = XYZ.Zero;
|
||||
faceNormal = conn.CoordinateSystem.BasisY;
|
||||
doc.Invoke(
|
||||
ts =>
|
||||
{
|
||||
switch (conn.Shape)
|
||||
{
|
||||
case ConnectorProfileType.Oval:
|
||||
break;
|
||||
case ConnectorProfileType.Rectangular:
|
||||
openingFamily = AddCasing
|
||||
? doc.GetOrLoadedFamily(
|
||||
$"{casingsFamilyFolder}\\矩形套管.rfa")
|
||||
: doc.GetOrLoadedFamily(
|
||||
$"{openingsFamilyFolder}\\矩形洞口.rfa");
|
||||
|
||||
width = conn.Width + (double)(Distance / 304.8);
|
||||
height = conn.Height + (double)(Distance / 304.8);
|
||||
|
||||
break;
|
||||
case ConnectorProfileType.Round:
|
||||
openingFamily = doc.GetOrLoadedFamily(
|
||||
AddCasing
|
||||
? $"{casingsFamilyFolder}\\圆形套管.rfa"
|
||||
: $"{openingsFamilyFolder}\\圆形洞口.rfa");
|
||||
|
||||
diameter = mepCurve.Diameter + (double)(Distance / 304.8);
|
||||
break;
|
||||
case ConnectorProfileType.Invalid:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//doc.ActiveView.SketchPlane = originSketch;
|
||||
if (openingFamily == null)
|
||||
{
|
||||
return Result.Failed;
|
||||
}
|
||||
var intersects = FindIntersects(elementToOpen, curve);
|
||||
|
||||
if (intersects.Count != 2)
|
||||
{
|
||||
return Result.Failed;
|
||||
}
|
||||
|
||||
var line = Line.CreateBound(intersects[0], intersects[1])
|
||||
.ExtendLine(0.5, true);
|
||||
|
||||
doc.ActiveView.ShowActiveWorkPlane();
|
||||
if (faceNormal == XYZ.Zero)
|
||||
{
|
||||
return Result.Failed;
|
||||
}
|
||||
|
||||
var plane = Plane.CreateByNormalAndOrigin(
|
||||
faceNormal,
|
||||
line.Evaluate(0.5, true));
|
||||
doc.ActiveView.SketchPlane = SketchPlane.Create(doc, plane);
|
||||
var workPlane = new FilteredElementCollector(
|
||||
doc,
|
||||
doc.ActiveView.Id)
|
||||
.OfCategory(BuiltInCategory.OST_IOSSketchGrid)
|
||||
.FirstElement();
|
||||
doc.Regenerate();
|
||||
var op = new Options
|
||||
{
|
||||
IncludeNonVisibleObjects = true,
|
||||
View = doc.ActiveView,
|
||||
//DetailLevel = ViewDetailLevel.Fine,
|
||||
ComputeReferences = true
|
||||
};
|
||||
var planeFace = workPlane
|
||||
.get_Geometry(op)
|
||||
.Where(obj => obj is Solid)
|
||||
.Cast<Solid>()
|
||||
.Select(s => s.Faces.get_Item(0))
|
||||
.FirstOrDefault();
|
||||
|
||||
var options = ts.GetFailureHandlingOptions();
|
||||
options.SetFailuresPreprocessor(new FailuresPreProcessor());
|
||||
ts.SetFailureHandlingOptions(options);
|
||||
|
||||
if (planeFace == null)
|
||||
{
|
||||
return Result.Failed;
|
||||
}
|
||||
|
||||
var symbolIds = openingFamily.GetFamilySymbolIds().FirstOrDefault();
|
||||
var symbol = doc.GetElement(symbolIds) as FamilySymbol;
|
||||
if (symbol != null && !symbol.IsActive)
|
||||
{
|
||||
symbol.Activate();
|
||||
}
|
||||
|
||||
var newFamilyInstance = doc.Create
|
||||
.NewFamilyInstance(planeFace, line, symbol);
|
||||
if (diameter != 0.0)
|
||||
{
|
||||
newFamilyInstance.GetParameters("洞口直径").FirstOrDefault()?.Set(
|
||||
diameter);
|
||||
}
|
||||
else if (width != 0.0 && height != 0.0)
|
||||
{
|
||||
newFamilyInstance.GetParameters("洞口宽度").FirstOrDefault()?.Set(width);
|
||||
newFamilyInstance.GetParameters("洞口高度").FirstOrDefault()?.Set(
|
||||
height);
|
||||
}
|
||||
|
||||
//ElementTransformUtils.RotateElement(doc, newFamilyInstance.ViewId, line, angle);
|
||||
doc.Regenerate();
|
||||
InstanceVoidCutUtils.AddInstanceVoidCut(
|
||||
doc,
|
||||
elementToOpen,
|
||||
newFamilyInstance);
|
||||
doc.Delete(doc.ActiveView.SketchPlane.Id);
|
||||
return Result.Succeeded;
|
||||
},
|
||||
"新建洞口");
|
||||
}
|
||||
},
|
||||
"开洞");
|
||||
});
|
||||
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
|
||||
catch (Exception e)
|
||||
{
|
||||
e.Message.ToLog();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 找到宿主的面
|
||||
/// </summary>
|
||||
/// <param name="wall"></param>
|
||||
/// <returns></returns>
|
||||
private static Face FindCeilingAndFloorFace(Wall wall)
|
||||
{
|
||||
Options opt = new() { ComputeReferences = true, DetailLevel = ViewDetailLevel.Fine };
|
||||
var geometryElement = wall.get_Geometry(opt);
|
||||
|
||||
Face normalFace = null;
|
||||
foreach (var geometryObject in geometryElement)
|
||||
{
|
||||
var solid = geometryObject as Solid;
|
||||
if (solid != null && solid.Faces.Size > 0)
|
||||
{
|
||||
foreach (Face face in solid.Faces)
|
||||
{
|
||||
var planarFace = face as PlanarFace;
|
||||
if (planarFace != null)
|
||||
{
|
||||
if (
|
||||
planarFace.FaceNormal.AngleTo(new XYZ(1, 1, 0)) == 0
|
||||
|| Math.Abs(planarFace.FaceNormal.AngleTo(new XYZ(1, 1, 0)) - Math.PI) < 0.0001
|
||||
)
|
||||
{
|
||||
normalFace = face;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return normalFace;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找所有管线定位线与元素面的碰撞点
|
||||
/// </summary>
|
||||
/// <param name="elementToOpen"></param>
|
||||
/// <param name="curve"></param>
|
||||
/// <returns></returns>
|
||||
private static List<XYZ> FindIntersects(Element elementToOpen, Curve curve)
|
||||
{
|
||||
var faces = elementToOpen.GetAllGeometryObjects<Face>();
|
||||
var intersects = new List<XYZ>();
|
||||
foreach (var face in faces)
|
||||
{
|
||||
//face = FindCeilingAndFloorFace(openingElement as Wall);
|
||||
var intersect = face.Intersect(curve, out var result);
|
||||
if (intersect == SetComparisonResult.Overlap)
|
||||
{
|
||||
//CurveArray curveArray = new CurveArray();
|
||||
var x = result.get_Item(0);
|
||||
var intersection = x.XYZPoint;
|
||||
intersects.Add(intersection);
|
||||
|
||||
//doc.Create.NewOpening(openingElement, curveArray, true);
|
||||
}
|
||||
}
|
||||
|
||||
return intersects;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user