309 lines
10 KiB
C#
309 lines
10 KiB
C#
|
|
using Autodesk.Revit.DB;
|
|
using Autodesk.Revit.UI.Selection;
|
|
|
|
using Nice3point.Revit.Toolkit.External;
|
|
|
|
using System;
|
|
|
|
using System.Linq;
|
|
|
|
namespace Szmedi.RvKits.DrawingTools
|
|
{
|
|
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
|
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
|
|
public class DimensionElemCmd : ExternalCommand
|
|
{
|
|
public override void Execute()
|
|
{
|
|
using Transaction transaction = new(Document, "标注对象");
|
|
try
|
|
{
|
|
while (true)
|
|
{
|
|
transaction.Start();
|
|
Reference refer = UiDocument.Selection.PickObject(ObjectType.Element, "请选择要标注的对象");
|
|
Element e = UiDocument.Document.GetElement(refer);
|
|
CreateDimensionsByFaces(Document, e);
|
|
transaction.Commit();
|
|
}
|
|
}
|
|
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
|
{
|
|
if (transaction.GetStatus() == TransactionStatus.Started)
|
|
{
|
|
transaction.RollBack();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorMessage = ex.Message;
|
|
if (transaction.GetStatus() == TransactionStatus.Started)
|
|
{
|
|
transaction.RollBack();
|
|
}
|
|
}
|
|
}
|
|
|
|
private List<Face> GetElementFaces(Element elem)
|
|
{
|
|
List<Face> faces = new();
|
|
Options option =
|
|
new()
|
|
{
|
|
ComputeReferences = true,
|
|
DetailLevel = ViewDetailLevel.Fine,
|
|
IncludeNonVisibleObjects = true
|
|
};
|
|
GeometryElement geometry = elem.get_Geometry(option);
|
|
|
|
foreach (GeometryObject geomObj in geometry)
|
|
{
|
|
GeometryInstance geomInstance = geomObj as GeometryInstance;
|
|
|
|
if (geomInstance != null)
|
|
{
|
|
bool usesSymbolGeometry = elem is FamilyInstance && !(elem as FamilyInstance).HasModifiedGeometry();
|
|
GeometryElement instanceGeometry = usesSymbolGeometry
|
|
? geomInstance.GetSymbolGeometry()
|
|
: geomInstance.GetInstanceGeometry();
|
|
|
|
foreach (GeometryObject instObj in instanceGeometry)
|
|
{
|
|
Solid instSolid = instObj as Solid;
|
|
if (instSolid == null || instSolid.Faces.Size == 0 || instSolid.Edges.Size == 0 || instSolid.Volume < 0.0001)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
foreach (Face face in instSolid.Faces)
|
|
{
|
|
faces.Add(face);
|
|
}
|
|
}
|
|
}
|
|
|
|
Solid solid = geomObj as Solid;
|
|
if (solid != null)
|
|
{
|
|
if (solid.Faces.Size == 0 || solid.Edges.Size == 0 || solid.Volume < 0.0001)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
foreach (Face face in solid.Faces)
|
|
{
|
|
faces.Add(face);
|
|
}
|
|
}
|
|
}
|
|
|
|
return faces;
|
|
}
|
|
|
|
private void CreateDimensionsByFace(Document Document, Face face)
|
|
{
|
|
List<Line> lines = new();
|
|
if (face.EdgeLoops.Size > 0)
|
|
{
|
|
foreach (CurveLoop loop in face.GetEdgesAsCurveLoops())
|
|
{
|
|
foreach (Curve curve in loop)
|
|
{
|
|
if (curve is Line)
|
|
{
|
|
lines.Add(curve as Line);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (Line line in lines)
|
|
{
|
|
ReferenceArray array = new();
|
|
array.Append(line.GetEndPointReference(0));
|
|
array.Append(line.GetEndPointReference(1));
|
|
Document.Create.NewDimension(Document.ActiveView, line, array);
|
|
}
|
|
|
|
//List<Line> l1 = new List<Line>();
|
|
//List<List<Line>> l2 = new List<List<Line>>();
|
|
//GetParallLineGroups(lines, lines.FirstOrDefault(), l1, l2);
|
|
//foreach (List<Line> list in l2)
|
|
//{
|
|
// if (list.Count <= 1)
|
|
// {
|
|
// continue;
|
|
// }
|
|
|
|
// ReferenceArray array = new ReferenceArray();
|
|
// var p1 = list.FirstOrDefault().Evaluate(0.5, true);
|
|
// var result = list.LastOrDefault().Project(p1);
|
|
// var p2 = result.XYZPoint;
|
|
// Line l = Line.CreateBound(p1, p2);
|
|
// foreach (Line line in list)
|
|
// {
|
|
// array.Append(line.GetEndPointReference(0));
|
|
// }
|
|
|
|
// doc.Create.NewDimension(doc.ActiveView, l, array);
|
|
//}
|
|
}
|
|
|
|
private void CreateDimensionsByFaces(Document Document, Element e)
|
|
{
|
|
List<Face> elementFaces = GetElementFaces(e);
|
|
if (e is Wall w)
|
|
{
|
|
IEnumerable<ElementId> elementIds = w.FindInserts(true, false, false, false)
|
|
.Where(id => Document.GetElement(id) is Opening);
|
|
foreach (var id in elementIds)
|
|
{
|
|
var opening = Document.GetElement(id);
|
|
elementFaces.AddRange(GetElementFaces(opening));
|
|
}
|
|
}
|
|
|
|
Location loc = e.Location;
|
|
var bounding = e.get_BoundingBox(Document.ActiveView);
|
|
|
|
//if (loc == null)
|
|
//{
|
|
// MessageBox.Show("元素无法被标注");
|
|
// return;
|
|
//}
|
|
|
|
//if (loc is LocationCurve)
|
|
//{
|
|
// p = (loc as LocationCurve).Curve.GetEndPoint(0);
|
|
//}
|
|
//else if (loc is LocationPoint)
|
|
//{
|
|
// p = (loc as LocationPoint).Point;
|
|
//}
|
|
|
|
List<List<Face>> groups = new();
|
|
GetParallFaces(elementFaces, groups);
|
|
foreach (List<Face> faces in groups)
|
|
{
|
|
XYZ p = bounding.Min;
|
|
if (faces.Count <= 1)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var face = faces[0];
|
|
var face1 = faces[faces.Count - 1];
|
|
ReferenceArray array = new();
|
|
foreach (var f in faces)
|
|
{
|
|
if (f.Reference == null)
|
|
{
|
|
//var elementIds = e.GetGeneratingElementIds(f);
|
|
//var openingId = elementIds.FirstOrDefault();
|
|
//var opening = doc.GetElement(openingId) as Opening;
|
|
//var fa = opening.GetGeometryObjectFromReference(f.Reference);
|
|
//if (fa != f)
|
|
//{
|
|
// array.Append(fa.Reference);
|
|
//}
|
|
|
|
continue;
|
|
}
|
|
|
|
array.Append(f.Reference);
|
|
}
|
|
|
|
try
|
|
{
|
|
Line line = null;
|
|
if (face is not null and PlanarFace)
|
|
{
|
|
var pf = face as PlanarFace;
|
|
var direction = pf.FaceNormal;
|
|
if (direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero))
|
|
{
|
|
p += direction * 2;
|
|
}
|
|
else
|
|
{
|
|
p += direction.CrossProduct(XYZ.BasisZ) * 2;
|
|
}
|
|
|
|
line = Line.CreateUnbound(p, direction);
|
|
}
|
|
|
|
Document.Create.NewDimension(Document.ActiveView, line, array);
|
|
}
|
|
catch (Exception) { }
|
|
}
|
|
}
|
|
|
|
private void GetParallFaces(List<Face> faces, List<List<Face>> groups)
|
|
{
|
|
var firstface = faces.FirstOrDefault();
|
|
faces = faces.FindAll(face => face is PlanarFace);
|
|
List<Face> group = new() { firstface };
|
|
groups.Add(group);
|
|
PlanarFace pf = firstface as PlanarFace;
|
|
faces.Remove(firstface);
|
|
|
|
for (var i = faces.Count - 1; i >= 0; i--)
|
|
{
|
|
if (faces[i] is not PlanarFace)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var tempFace = faces[i] as PlanarFace;
|
|
|
|
if (tempFace.FaceNormal.CrossProduct(pf.FaceNormal).IsAlmostEqualTo(XYZ.Zero))
|
|
{
|
|
group.Add(tempFace);
|
|
faces.Remove(tempFace);
|
|
|
|
//GetParallFaces(faces, tempFace, ZoomRBGroup, groups);
|
|
}
|
|
}
|
|
|
|
if (faces.Count >= 1)
|
|
{
|
|
GetParallFaces(faces, groups);
|
|
}
|
|
}
|
|
|
|
private void GetParallLineGroups(List<Curve> lines, List<List<Curve>> groups)
|
|
{
|
|
var firstLine = lines.FirstOrDefault();
|
|
lines = lines.FindAll(curve => curve is Line);
|
|
List<Curve> group = new() { firstLine };
|
|
groups.Add(group);
|
|
Line pf = firstLine as Line;
|
|
lines.Remove(firstLine);
|
|
|
|
for (var i = 0; i < lines.Count; i++)
|
|
{
|
|
if (lines[i] is not Line)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var tempLine = lines[i] as Line;
|
|
|
|
if (tempLine.Direction.CrossProduct(pf.Direction).IsAlmostEqualTo(XYZ.Zero))
|
|
{
|
|
group.Add(tempLine);
|
|
lines.Remove(tempLine);
|
|
|
|
//GetParallFaces(faces, tempFace, ZoomRBGroup, groups);
|
|
}
|
|
}
|
|
|
|
if (lines.Count >= 1)
|
|
{
|
|
GetParallLineGroups(lines, groups);
|
|
}
|
|
}
|
|
}
|
|
}
|