727 lines
30 KiB
C#
727 lines
30 KiB
C#
|
|
using Autodesk.Revit.Attributes;
|
|||
|
|
using Autodesk.Revit.DB;
|
|||
|
|
using Autodesk.Revit.UI;
|
|||
|
|
|
|||
|
|
using Nice3point.Revit.Toolkit.External;
|
|||
|
|
|
|||
|
|
using System;
|
|||
|
|
using System.Globalization;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using System.Windows;
|
|||
|
|
|
|||
|
|
using System.Windows.Media;
|
|||
|
|
|
|||
|
|
namespace Szmedi.RvKits.DrawingTools
|
|||
|
|
{
|
|||
|
|
[Transaction(TransactionMode.Manual)]
|
|||
|
|
|
|||
|
|
public class DimensionView3dCmd : ExternalCommand
|
|||
|
|
{
|
|||
|
|
public override void Execute()
|
|||
|
|
{
|
|||
|
|
ViewFamilyType viewFamilyType = new FilteredElementCollector(Document)
|
|||
|
|
.OfClass(typeof(ViewFamilyType))
|
|||
|
|
.Cast<ViewFamilyType>()
|
|||
|
|
.FirstOrDefault(t => t.ViewFamily == ViewFamily.ThreeDimensional);
|
|||
|
|
IEnumerable<Grid> grids = new FilteredElementCollector(Document).OfClass(typeof(Grid)).Cast<Grid>();
|
|||
|
|
View3D myView = null;
|
|||
|
|
int n = 100;
|
|||
|
|
if (!grids.Any())
|
|||
|
|
{
|
|||
|
|
Result = Result.Cancelled;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
Document.Invoke(
|
|||
|
|
_ =>
|
|||
|
|
{
|
|||
|
|
if (viewFamilyType != null)
|
|||
|
|
{
|
|||
|
|
myView = View3D.CreateIsometric(Document, viewFamilyType.Id);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < n; i++)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
myView.Name = $"三维轴测视图_{i}";
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
catch (Autodesk.Revit.Exceptions.ArgumentException) { }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
myView.SaveOrientationAndLock();
|
|||
|
|
List<ModelCurve> mcurves = Create3dGrid(myView, grids);
|
|||
|
|
Document.Regenerate();
|
|||
|
|
CreateDimension(Document, myView, mcurves);
|
|||
|
|
},
|
|||
|
|
"三维标注"
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
UiDocument.ActiveView = myView;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取族实例所有面(实际为族类型的所有面)
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="instance"></param>
|
|||
|
|
/// <param name="options"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static List<Face> GetFacesByFamilyInstance(FamilyInstance instance, Options options)
|
|||
|
|
{
|
|||
|
|
List<Face> faces = new();
|
|||
|
|
//根据打开的方式得到几何信息
|
|||
|
|
GeometryElement geometry = instance.get_Geometry(options);
|
|||
|
|
foreach (GeometryObject geomObj in geometry)
|
|||
|
|
{
|
|||
|
|
//geomObj为几何实例
|
|||
|
|
GeometryInstance geomInstance = geomObj as GeometryInstance;
|
|||
|
|
if (geomInstance == null)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
//族实例未修改过(连接,剪切,复制,扩展)
|
|||
|
|
bool usesSymbolGeometry = instance is not null && !instance.HasModifiedGeometry();
|
|||
|
|
bool bo = instance.HasModifiedGeometry();
|
|||
|
|
GeometryElement instanceGeometry = usesSymbolGeometry
|
|||
|
|
? geomInstance.GetSymbolGeometry()
|
|||
|
|
: geomInstance.GetInstanceGeometry();
|
|||
|
|
|
|||
|
|
if (instanceGeometry != null)
|
|||
|
|
{
|
|||
|
|
//instanceGeometry.GetTransformed();
|
|||
|
|
//从实例中找到实例的几何体
|
|||
|
|
foreach (GeometryObject instObj in instanceGeometry)
|
|||
|
|
{
|
|||
|
|
//三维的实体
|
|||
|
|
Solid instSolid = instObj as Solid;
|
|||
|
|
if (instSolid == null || instSolid.Faces.Size == 0 || instSolid.Edges.Size == 0)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
foreach (Face face in instSolid.Faces)
|
|||
|
|
{
|
|||
|
|
faces.Add(face);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//geomObj为几何体
|
|||
|
|
Solid solid = geomObj as Solid;
|
|||
|
|
if (solid != null)
|
|||
|
|
{
|
|||
|
|
if (solid.Faces.Size == 0 || solid.Edges.Size == 0)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
foreach (Face face in solid.Faces)
|
|||
|
|
{
|
|||
|
|
faces.Add(face);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return faces;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取元素侧面
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="elem"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static List<Face> GetSideFacesByElement(Element elem)
|
|||
|
|
{
|
|||
|
|
Options opt = new() { ComputeReferences = true, DetailLevel = ViewDetailLevel.Fine };
|
|||
|
|
GeometryElement ge = elem.get_Geometry(opt);
|
|||
|
|
List<Face> lstpf = new();
|
|||
|
|
foreach (GeometryObject obj in ge)
|
|||
|
|
{
|
|||
|
|
Solid solid = obj as Solid;
|
|||
|
|
if (solid != null)
|
|||
|
|
{
|
|||
|
|
foreach (Face face in solid.Faces)
|
|||
|
|
{
|
|||
|
|
PlanarFace pf = face as PlanarFace;
|
|||
|
|
if (pf != null)
|
|||
|
|
{
|
|||
|
|
//点乘,即面的法向与Z轴始终垂直
|
|||
|
|
double dotp = pf.FaceNormal.DotProduct(XYZ.BasisZ);
|
|||
|
|
if (dotp is < 1.0e-09 and > (-1.0e-09)) //近似为0
|
|||
|
|
{
|
|||
|
|
lstpf.Add(pf);
|
|||
|
|
}
|
|||
|
|
//if (pf.FaceNormal.CrossProduct(wall.Orientation).IsZeroLength())
|
|||
|
|
//{
|
|||
|
|
// lstpf.Add(pf);
|
|||
|
|
//}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CylindricalFace cy = face as CylindricalFace;
|
|||
|
|
if (cy != null)
|
|||
|
|
{
|
|||
|
|
lstpf.Add(cy);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return lstpf;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return lstpf;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private List<ModelCurve> Create3dGrid(View view, IEnumerable<Grid> grids)
|
|||
|
|
{
|
|||
|
|
Document Document = view.Document;
|
|||
|
|
List<TextNoteType> textnotetypes = new FilteredElementCollector(Document)
|
|||
|
|
.OfClass(typeof(TextNoteType))
|
|||
|
|
.Cast<TextNoteType>()
|
|||
|
|
.ToList();
|
|||
|
|
TextNoteType textnotetype = textnotetypes.FirstOrDefault();
|
|||
|
|
List<ModelCurve> curves = new();
|
|||
|
|
IEnumerable<bool> gridGroups = grids
|
|||
|
|
.GroupBy(g => g.Curve.ComputeDerivatives(0, true).BasisX.Normalize().X)
|
|||
|
|
.Select(s => s.Count() > 1);
|
|||
|
|
|
|||
|
|
Plane plane = Plane.CreateByOriginAndBasis(XYZ.Zero, XYZ.BasisX, XYZ.BasisY);
|
|||
|
|
SketchPlane sketch = SketchPlane.Create(Document, plane);
|
|||
|
|
|
|||
|
|
foreach (Grid grid in grids)
|
|||
|
|
{
|
|||
|
|
Curve curve = grid.Curve;
|
|||
|
|
XYZ startp = curve.GetEndPoint(0);
|
|||
|
|
XYZ endp = curve.GetEndPoint(1);
|
|||
|
|
|
|||
|
|
int radius = 2;
|
|||
|
|
XYZ direction = curve.ComputeDerivatives(0, true).BasisX.Normalize().Negate();
|
|||
|
|
XYZ direction1 = curve.ComputeDerivatives(1, true).BasisX.Normalize();
|
|||
|
|
SketchPlane gridSketch = SketchPlane.Create(Document, new Reference(grid));
|
|||
|
|
XYZ loc = startp + (direction * radius);
|
|||
|
|
XYZ loc1 = endp + (direction1 * radius);
|
|||
|
|
|
|||
|
|
Arc circle = Arc.Create(loc, radius, 0, Math.PI * 2, XYZ.BasisX, XYZ.BasisY);
|
|||
|
|
Arc circle1 = Arc.Create(loc1, radius, 0, Math.PI * 2, XYZ.BasisX, XYZ.BasisY);
|
|||
|
|
|
|||
|
|
TextNoteOptions options =
|
|||
|
|
new(textnotetype.Id)
|
|||
|
|
{
|
|||
|
|
HorizontalAlignment = HorizontalTextAlignment.Center,
|
|||
|
|
#if REVIT2019 || REVIT2020
|
|||
|
|
VerticalAlignment = VerticalTextAlignment.Middle
|
|||
|
|
#endif
|
|||
|
|
};
|
|||
|
|
//Text.FromStringOriginAndScale(grid.Name, loc, size);
|
|||
|
|
//Text.FromStringOriginAndScale(grid.Name, loc1, size);
|
|||
|
|
TextNote.Create(Document, view.Id, loc, grid.Name, options);
|
|||
|
|
TextNote.Create(Document, view.Id, loc1, grid.Name, options);
|
|||
|
|
|
|||
|
|
ModelCurve gridLine = Document.Create.NewModelCurve(grid.Curve, gridSketch);
|
|||
|
|
Document.Create.NewModelCurve(circle, sketch);
|
|||
|
|
Document.Create.NewModelCurve(circle1, sketch);
|
|||
|
|
curves.Add(gridLine);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return curves;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal static MethodInfo GenerateTransientDisplayMethod()
|
|||
|
|
{
|
|||
|
|
Type geometryElementType = typeof(GeometryElement);
|
|||
|
|
MethodInfo[] geometryElementTypeMethods = geometryElementType.GetMethods(
|
|||
|
|
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic
|
|||
|
|
);
|
|||
|
|
MethodInfo method = geometryElementTypeMethods.FirstOrDefault(x => x.Name == "SetForTransientDisplay");
|
|||
|
|
return method;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private ReferenceArray RemoveZeroSegements(Wall wall, ReferenceArray wallLengthRefernceArray, Dimension lengthdim)
|
|||
|
|
{
|
|||
|
|
List<Reference> referencesdelete = new();
|
|||
|
|
ReferenceArray finallengthreferenceArray = new();
|
|||
|
|
for (int i = 0; i < lengthdim.NumberOfSegments; i++)
|
|||
|
|
{
|
|||
|
|
if (lengthdim.Segments.get_Item(i).ValueString == "0")
|
|||
|
|
{
|
|||
|
|
if (lengthdim.References.get_Item(i).ElementId == wall.Id)
|
|||
|
|
{
|
|||
|
|
referencesdelete.Add(lengthdim.References.get_Item(i));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (lengthdim.References.get_Item(i + 1).ElementId == wall.Id)
|
|||
|
|
{
|
|||
|
|
referencesdelete.Add(lengthdim.References.get_Item(i + 1));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < wallLengthRefernceArray.Size; i++)
|
|||
|
|
{
|
|||
|
|
bool isContain = false;
|
|||
|
|
Reference reference = wallLengthRefernceArray.get_Item(i);
|
|||
|
|
foreach (Reference referdelete in referencesdelete)
|
|||
|
|
{
|
|||
|
|
if (reference.EqualTo(referdelete))
|
|||
|
|
{
|
|||
|
|
isContain = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!isContain)
|
|||
|
|
{
|
|||
|
|
finallengthreferenceArray.Append(reference);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return finallengthreferenceArray;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void CreateBeamsDimension(Document Document)
|
|||
|
|
{
|
|||
|
|
FilteredElementCollector col = new(Document, Document.ActiveView.Id);
|
|||
|
|
ElementCategoryFilter categoryFilter1 = new(BuiltInCategory.OST_StructuralFraming);
|
|||
|
|
col.WherePasses(categoryFilter1);
|
|||
|
|
IEnumerable<Element> beams = col.GroupBy(g => g.Name).Select(s => s.FirstOrDefault());
|
|||
|
|
|
|||
|
|
foreach (FamilyInstance familyInstance in beams)
|
|||
|
|
{
|
|||
|
|
XYZ loc = (familyInstance.Location as LocationPoint).Point;
|
|||
|
|
List<Face> faces = GetSideFacesByElement(familyInstance);
|
|||
|
|
if (faces.Count == 0) //找不到实例的几何元素时,需从类型集合查找
|
|||
|
|
{
|
|||
|
|
Options options = new() { ComputeReferences = true };
|
|||
|
|
faces = GetFacesByFamilyInstance(familyInstance, options);
|
|||
|
|
for (int i = faces.Count - 1; i >= 0; i--)
|
|||
|
|
{
|
|||
|
|
PlanarFace pf = faces[i] as PlanarFace;
|
|||
|
|
if (pf.FaceNormal.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero))
|
|||
|
|
{
|
|||
|
|
faces.Remove(faces[i]); //移除顶面底面
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ReferenceArray referenceArray = new();
|
|||
|
|
ReferenceArrayArray referenceArrayArray = new();
|
|||
|
|
GetParallFacesReferenceArray(faces, faces.FirstOrDefault(), referenceArray, referenceArrayArray);
|
|||
|
|
foreach (ReferenceArray array in referenceArrayArray)
|
|||
|
|
{
|
|||
|
|
PlanarFace face = familyInstance.GetGeometryObjectFromReference(array.get_Item(0)) as PlanarFace;
|
|||
|
|
Line line = Line.CreateUnbound(loc, face.FaceNormal).CreateOffset(600 / 304.8, XYZ.BasisZ) as Line;
|
|||
|
|
Document.Create.NewDimension(Document.ActiveView, line, array);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void CreateColumnsDimension(Document Document, View view)
|
|||
|
|
{
|
|||
|
|
FilteredElementCollector col = new(Document, view.Id);
|
|||
|
|
ElementCategoryFilter categoryFilter1 = new(BuiltInCategory.OST_StructuralColumns);
|
|||
|
|
ElementCategoryFilter categoryFilter2 = new(BuiltInCategory.OST_Columns);
|
|||
|
|
LogicalOrFilter andFilter = new(categoryFilter1, categoryFilter2);
|
|||
|
|
col.WherePasses(andFilter);
|
|||
|
|
IEnumerable<Element> columns = col.GroupBy(g => g.Name).Select(s => s.FirstOrDefault());
|
|||
|
|
|
|||
|
|
foreach (FamilyInstance familyInstance in columns)
|
|||
|
|
{
|
|||
|
|
XYZ loc = (familyInstance.Location as LocationPoint).Point;
|
|||
|
|
List<Face> faces = GetSideFacesByElement(familyInstance);
|
|||
|
|
if (faces.Count == 0) //找不到实例的几何元素时,需从类型集合查找
|
|||
|
|
{
|
|||
|
|
Options options = new() { ComputeReferences = true };
|
|||
|
|
faces = GetFacesByFamilyInstance(familyInstance, options);
|
|||
|
|
for (int i = faces.Count - 1; i >= 0; i--)
|
|||
|
|
{
|
|||
|
|
if (faces[i] is PlanarFace)
|
|||
|
|
{
|
|||
|
|
PlanarFace pf = faces[i] as PlanarFace;
|
|||
|
|
if (pf.FaceNormal.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero))
|
|||
|
|
{
|
|||
|
|
faces.Remove(faces[i]); //移除顶面底面
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ReferenceArray referenceArray = new();
|
|||
|
|
ReferenceArrayArray referenceArrayArray = new();
|
|||
|
|
GetParallFacesReferenceArray(faces, faces.FirstOrDefault(), referenceArray, referenceArrayArray);
|
|||
|
|
foreach (ReferenceArray array in referenceArrayArray)
|
|||
|
|
{
|
|||
|
|
if (array.Size == 0)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PlanarFace face = familyInstance.GetGeometryObjectFromReference(array.get_Item(0)) as PlanarFace;
|
|||
|
|
Line line = Line.CreateUnbound(loc, face.FaceNormal).CreateOffset(600 / 304.8, XYZ.BasisZ) as Line;
|
|||
|
|
Document.Create.NewDimension(Document.ActiveView, line, array);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void CreateDimension(Document Document, View view, List<ModelCurve> mcurves)
|
|||
|
|
{
|
|||
|
|
List<Curve> lines = mcurves.Where(c => c is ModelLine).Select(mc => mc.GeometryCurve).ToList();
|
|||
|
|
|
|||
|
|
List<List<Curve>> groups = new();
|
|||
|
|
GetParallLineGroups(lines, groups);
|
|||
|
|
foreach (List<Curve> g in groups)
|
|||
|
|
{
|
|||
|
|
List<Line> gx = g.ConvertAll(x => x as Line);
|
|||
|
|
if (!gx.Any())
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
XYZ direction = gx.FirstOrDefault()?.Direction;
|
|||
|
|
//IOrderedEnumerable<Line> orderedlist = null;
|
|||
|
|
//if (direction.AngleTo(XYZ.BasisX) >= direction.AngleTo(XYZ.BasisY))
|
|||
|
|
//{
|
|||
|
|
// orderedlist = gx.OrderBy(l => l.Direction.X);
|
|||
|
|
//}
|
|||
|
|
//else
|
|||
|
|
//{
|
|||
|
|
// orderedlist = gx.OrderBy(l => l.Direction.Y);
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
if (g.Count <= 1)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Line line =
|
|||
|
|
Line.CreateUnbound(g.FirstOrDefault()?.GetEndPoint(0), direction.CrossProduct(XYZ.BasisZ))
|
|||
|
|
.CreateOffset(1500 / 304.8, XYZ.BasisZ) as Line;
|
|||
|
|
Line line1 =
|
|||
|
|
Line.CreateUnbound(g.FirstOrDefault()?.GetEndPoint(1), direction.CrossProduct(XYZ.BasisZ))
|
|||
|
|
.CreateOffset(1500 / 304.8, XYZ.BasisZ) as Line;
|
|||
|
|
ReferenceArray arrayAll = new();
|
|||
|
|
foreach (Curve l in g)
|
|||
|
|
{
|
|||
|
|
arrayAll.Append(l.Reference);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Dimension dimension1 = Document.Create.NewDimension(view, line, arrayAll);
|
|||
|
|
Dimension dimension2 = Document.Create.NewDimension(view, line1, arrayAll);
|
|||
|
|
Document.Regenerate();
|
|||
|
|
Line line3 =
|
|||
|
|
Line.CreateUnbound(g.FirstOrDefault()?.GetEndPoint(0), direction.CrossProduct(XYZ.BasisZ))
|
|||
|
|
.CreateOffset(1000 / 304.8, XYZ.BasisZ) as Line;
|
|||
|
|
Line line4 =
|
|||
|
|
Line.CreateUnbound(g.FirstOrDefault()?.GetEndPoint(1), direction.CrossProduct(XYZ.BasisZ))
|
|||
|
|
.CreateOffset(1000 / 304.8, XYZ.BasisZ) as Line;
|
|||
|
|
|
|||
|
|
ReferenceArray array = new();
|
|||
|
|
array.Append(dimension1.References.get_Item(0));
|
|||
|
|
array.Append(dimension1.References.get_Item(arrayAll.Size - 1));
|
|||
|
|
Document.Create.NewDimension(view, line3, array);
|
|||
|
|
Document.Create.NewDimension(view, line4, array);
|
|||
|
|
Document.Regenerate();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void CreateWallDimension(Document Document, View view)
|
|||
|
|
{
|
|||
|
|
FilteredElementCollector wallCol = new FilteredElementCollector(Document, view.Id).OfClass(typeof(Wall));
|
|||
|
|
|
|||
|
|
foreach (Wall wall in wallCol)
|
|||
|
|
{
|
|||
|
|
if (wall.WallType.Kind != WallKind.Basic)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
LocationCurve loc = wall.Location as LocationCurve;
|
|||
|
|
ReferenceArray wallThickReferenceArray = new();
|
|||
|
|
ReferenceArray wallLengthRefernceArray = new();
|
|||
|
|
List<Face> faces = GetSideFacesByElement(wall);
|
|||
|
|
|
|||
|
|
foreach (Face face in faces)
|
|||
|
|
{
|
|||
|
|
PlanarFace pf = face as PlanarFace;
|
|||
|
|
if (pf == null || face.Reference == null || pf.OrientationMatchesSurfaceOrientation == false)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (pf.FaceNormal.CrossProduct(wall.Orientation).IsAlmostEqualTo(XYZ.Zero))
|
|||
|
|
{
|
|||
|
|
if (Document.GetElement(face.Reference).Id == wall.Id)
|
|||
|
|
{
|
|||
|
|
wallThickReferenceArray.Append(face.Reference);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (pf.FaceNormal.DotProduct(wall.Orientation) < 0.001)
|
|||
|
|
{
|
|||
|
|
wallLengthRefernceArray.Append(face.Reference);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
int scale = Document.ActiveView.Scale;
|
|||
|
|
Autodesk.Revit.DB.Transform tranform = Autodesk.Revit.DB.Transform.CreateTranslation(
|
|||
|
|
wall.Orientation * scale * 15 / 304.8
|
|||
|
|
);
|
|||
|
|
Line wallcurve = (wall.Location as LocationCurve).Curve as Line;
|
|||
|
|
Line lengthLine = wallcurve.CreateTransformed(tranform) as Line;
|
|||
|
|
Dimension lengthdim = Document.Create.NewDimension(Document.ActiveView, lengthLine, wallLengthRefernceArray);
|
|||
|
|
Document.Regenerate();
|
|||
|
|
|
|||
|
|
ReferenceArray finallengthreferenceArray = RemoveZeroSegements(wall, wallLengthRefernceArray, lengthdim);
|
|||
|
|
Document.Delete(lengthdim.Id);
|
|||
|
|
Document.Create.NewDimension(Document.ActiveView, lengthLine, finallengthreferenceArray);
|
|||
|
|
|
|||
|
|
Line thickLine = Line.CreateUnbound(wallcurve.Evaluate(0.2, true), wall.Orientation);
|
|||
|
|
Dimension thickdim = Document.Create.NewDimension(Document.ActiveView, thickLine, wallThickReferenceArray);
|
|||
|
|
|
|||
|
|
if (lengthdim.Segments.Size > 2)
|
|||
|
|
{
|
|||
|
|
ReferenceArray referenceArray = new();
|
|||
|
|
Reference refer1 = lengthdim.References.get_Item(0);
|
|||
|
|
Reference refer2 = lengthdim.References.get_Item(lengthdim.References.Size - 1);
|
|||
|
|
referenceArray.Append(refer1);
|
|||
|
|
referenceArray.Append(refer2);
|
|||
|
|
Autodesk.Revit.DB.Transform tranform1 = Autodesk.Revit.DB.Transform.CreateTranslation(
|
|||
|
|
wall.Orientation * scale * 25 / 304.8
|
|||
|
|
);
|
|||
|
|
Line lengthLine1 = wallcurve.CreateTransformed(tranform1) as Line;
|
|||
|
|
|
|||
|
|
Document.Create.NewDimension(Document.ActiveView, lengthLine1, referenceArray);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception) { }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void GetParallFacesReferenceArray(
|
|||
|
|
List<Face> faces,
|
|||
|
|
Face firstFace,
|
|||
|
|
ReferenceArray referenceArray,
|
|||
|
|
ReferenceArrayArray referenceArrayArray
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
if (referenceArrayArray.Size == 0)
|
|||
|
|
{
|
|||
|
|
referenceArrayArray.Append(referenceArray);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < faces.Count; i++)
|
|||
|
|
{
|
|||
|
|
if (faces[i] is not PlanarFace)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PlanarFace tempFace = faces[i] as PlanarFace;
|
|||
|
|
PlanarFace pf = firstFace as PlanarFace;
|
|||
|
|
XYZ facenormal = pf.FaceNormal;
|
|||
|
|
//把初始的第一个添加进集合
|
|||
|
|
|
|||
|
|
if (tempFace.FaceNormal.CrossProduct(facenormal).IsAlmostEqualTo(XYZ.Zero))
|
|||
|
|
{
|
|||
|
|
referenceArray.Append(tempFace.Reference);
|
|||
|
|
faces.Remove(tempFace);
|
|||
|
|
GetParallFacesReferenceArray(faces, tempFace, referenceArray, referenceArrayArray);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (i == faces.Count() - 1)
|
|||
|
|
{
|
|||
|
|
referenceArray = new ReferenceArray();
|
|||
|
|
GetParallFacesReferenceArray(faces, faces.FirstOrDefault(), referenceArray, referenceArrayArray);
|
|||
|
|
if (!faces.Any())
|
|||
|
|
{
|
|||
|
|
referenceArrayArray.Append(referenceArray);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 递归找到所有平行线集合
|
|||
|
|
/// </summary>
|
|||
|
|
public static void GetParallLineGroups(List<Curve> lines, List<List<Curve>> groups)
|
|||
|
|
{
|
|||
|
|
Curve firstLine = lines.FirstOrDefault();
|
|||
|
|
lines = lines.FindAll(curve => curve is Line);
|
|||
|
|
List<Curve> group = new() { firstLine };
|
|||
|
|
groups.Add(group);
|
|||
|
|
Line line = firstLine as Line;
|
|||
|
|
lines.Remove(firstLine);
|
|||
|
|
|
|||
|
|
for (int i = lines.Count - 1; i >= 0; i--)
|
|||
|
|
{
|
|||
|
|
if (lines[i] is not Line)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Line tempLine = lines[i] as Line;
|
|||
|
|
|
|||
|
|
if (
|
|||
|
|
tempLine.Direction.CrossProduct(line.Direction).IsAlmostEqualTo(XYZ.Zero)
|
|||
|
|
&& Math.Abs(tempLine.Length - line.Length) < 0.00001
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
group.Add(tempLine);
|
|||
|
|
lines.Remove(tempLine);
|
|||
|
|
|
|||
|
|
//GetParallFaces(faces, tempFace, ZoomRBGroup, groups);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (lines.Count >= 1)
|
|||
|
|
{
|
|||
|
|
GetParallLineGroups(lines, groups);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void TransientGrid(Document Document, Grid grid)
|
|||
|
|
{
|
|||
|
|
double radius = 1.5;
|
|||
|
|
double size = 1.8;
|
|||
|
|
XYZ startp = grid.Curve.GetEndPoint(0);
|
|||
|
|
XYZ endp = grid.Curve.GetEndPoint(1);
|
|||
|
|
XYZ direction = grid.Curve.ComputeDerivatives(0, true).BasisX.Normalize().Negate();
|
|||
|
|
XYZ direction1 = grid.Curve.ComputeDerivatives(1, true).BasisX.Normalize();
|
|||
|
|
XYZ loc = startp + (direction * radius);
|
|||
|
|
XYZ loc1 = endp + (direction1 * radius);
|
|||
|
|
|
|||
|
|
IEnumerable<Curve> text = Text.FromStringOriginAndScale(grid.Name, loc, size);
|
|||
|
|
IEnumerable<Curve> text1 = Text.FromStringOriginAndScale(grid.Name, loc1, size);
|
|||
|
|
|
|||
|
|
Arc circle = Arc.Create(loc, radius, 0, Math.PI * 2, XYZ.BasisX, XYZ.BasisY);
|
|||
|
|
Arc circle1 = Arc.Create(loc1, radius, 0, Math.PI * 2, XYZ.BasisX, XYZ.BasisY);
|
|||
|
|
List<GeometryObject> geoms = new() { grid.Curve, circle, circle1 };
|
|||
|
|
geoms.AddRange(text);
|
|||
|
|
geoms.AddRange(text1);
|
|||
|
|
MethodInfo method = GenerateTransientDisplayMethod();
|
|||
|
|
object[] argsM = new object[4];
|
|||
|
|
argsM[0] = Document;
|
|||
|
|
argsM[1] = ElementId.InvalidElementId;
|
|||
|
|
argsM[2] = geoms;
|
|||
|
|
argsM[3] = ElementId.InvalidElementId;
|
|||
|
|
ElementId transientElementId = (ElementId)method.Invoke(null, argsM);
|
|||
|
|
MessageBox.Show(transientElementId.IntegerValue.ToString(), "元素ID");
|
|||
|
|
//doc.Delete(transientElementId);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class TransientElementMaker : ITransientElementMaker
|
|||
|
|
{
|
|||
|
|
private readonly Document _document;
|
|||
|
|
|
|||
|
|
public List<GeometryObject> GeometryObjects { get; set; }
|
|||
|
|
|
|||
|
|
public TransientElementMaker(Document document)
|
|||
|
|
{
|
|||
|
|
_document = document;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Execute()
|
|||
|
|
{
|
|||
|
|
if (GeometryObjects != null)
|
|||
|
|
{
|
|||
|
|
DirectShape ds = DirectShape.CreateElement(_document, new ElementId(BuiltInCategory.OST_GenericModel));
|
|||
|
|
//CreateUtils.CreateCube(), CreateUtils.CreateSphere()为创建一个立方体与球体Solid,文略
|
|||
|
|
//ds.AppendShape(GeometryObjects);
|
|||
|
|
ds.AppendShape(new List<GeometryObject> { CreateCube() });
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Solid CreateCube()
|
|||
|
|
{
|
|||
|
|
CurveLoop cubeBaseLines = new();
|
|||
|
|
cubeBaseLines.Append(Line.CreateBound(new XYZ(0, 0, 0), new XYZ(100, 0, 0)));
|
|||
|
|
cubeBaseLines.Append(Line.CreateBound(new XYZ(100, 0, 0), new XYZ(100, 100, 0)));
|
|||
|
|
cubeBaseLines.Append(Line.CreateBound(new XYZ(100, 100, 0), new XYZ(0, 100, 0)));
|
|||
|
|
cubeBaseLines.Append(Line.CreateBound(new XYZ(0, 100, 0), new XYZ(0, 0, 0)));
|
|||
|
|
Solid solidCube = GeometryCreationUtilities.CreateExtrusionGeometry(new List<CurveLoop> { cubeBaseLines }, XYZ.BasisZ, 100);
|
|||
|
|
|
|||
|
|
return solidCube;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static class Text
|
|||
|
|
{
|
|||
|
|
public static IEnumerable<Curve> FromStringOriginAndScale(string text, XYZ origin, double scale)
|
|||
|
|
{
|
|||
|
|
//http://msdn.microsoft.com/en-us/library/ms745816(v=vs.110).aspx
|
|||
|
|
|
|||
|
|
List<Curve> crvs = new();
|
|||
|
|
|
|||
|
|
FontFamily font = new("Arial");
|
|||
|
|
FontStyle fontStyle = FontStyles.Normal;
|
|||
|
|
FontWeight fontWeight = FontWeights.Medium;
|
|||
|
|
|
|||
|
|
//if (Bold == true) fontWeight = FontWeights.Bold;
|
|||
|
|
//if (Italic == true) fontStyle = FontStyles.Italic;
|
|||
|
|
|
|||
|
|
// Create the formatted text based on the properties set.
|
|||
|
|
#if REVIT2019||REVIT2020
|
|||
|
|
System.Windows.Media.FormattedText formattedText =
|
|||
|
|
new(
|
|||
|
|
text,
|
|||
|
|
CultureInfo.GetCultureInfo("en-us"),
|
|||
|
|
FlowDirection.LeftToRight,
|
|||
|
|
new Typeface(font, fontStyle, fontWeight, FontStretches.Normal),
|
|||
|
|
1,
|
|||
|
|
Brushes.Black,
|
|||
|
|
1 // This brush does not matter since we use the geometry of the text.
|
|||
|
|
);
|
|||
|
|
#elif REVIT2018
|
|||
|
|
var formattedText = new System.Windows.Media.FormattedText(
|
|||
|
|
text,
|
|||
|
|
CultureInfo.GetCultureInfo("en-us"),
|
|||
|
|
FlowDirection.LeftToRight,
|
|||
|
|
new Typeface(font, fontStyle, fontWeight, FontStretches.Normal),
|
|||
|
|
1,
|
|||
|
|
Brushes.Black // This brush does not matter since we use the geometry of the text.
|
|||
|
|
,
|
|||
|
|
1.25
|
|||
|
|
);
|
|||
|
|
#endif
|
|||
|
|
// Build the geometry object that represents the text.
|
|||
|
|
Geometry textGeometry = formattedText.BuildGeometry(new System.Windows.Point(0, 0));
|
|||
|
|
foreach (PathFigure figure in textGeometry.GetFlattenedPathGeometry().Figures)
|
|||
|
|
{
|
|||
|
|
System.Windows.Point init = figure.StartPoint;
|
|||
|
|
System.Windows.Point a = figure.StartPoint;
|
|||
|
|
System.Windows.Point b;
|
|||
|
|
foreach (PathSegment segment in figure.GetFlattenedPathFigure().Segments)
|
|||
|
|
{
|
|||
|
|
if (segment is System.Windows.Media.LineSegment lineSeg)
|
|||
|
|
{
|
|||
|
|
b = lineSeg.Point;
|
|||
|
|
Line crv = LineBetweenPoints(origin, scale, a, b);
|
|||
|
|
a = b;
|
|||
|
|
crvs.Add(crv);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (segment is PolyLineSegment plineSeg)
|
|||
|
|
{
|
|||
|
|
foreach (System.Windows.Point segPt in plineSeg.Points)
|
|||
|
|
{
|
|||
|
|
Line crv = LineBetweenPoints(origin, scale, a, segPt);
|
|||
|
|
a = segPt;
|
|||
|
|
crvs.Add(crv);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return crvs;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static Line LineBetweenPoints(XYZ origin, double scale, System.Windows.Point a, System.Windows.Point b)
|
|||
|
|
{
|
|||
|
|
XYZ pt1 = new((a.X * scale) + origin.X, ((-a.Y + 1) * scale) + origin.Y, origin.Z);
|
|||
|
|
XYZ pt2 = new((b.X * scale) + origin.X, ((-b.Y + 1) * scale) + origin.Y, origin.Z);
|
|||
|
|
Line crv = Line.CreateBound(pt1, pt2);
|
|||
|
|
return crv;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|