Skip to content

Commit

Permalink
Merge branch 'r2025' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
chuongmep committed Aug 22, 2024
2 parents 643f7d4 + 6254667 commit 83e7673
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 22 deletions.
55 changes: 55 additions & 0 deletions OpenMEPRevit/ClassModel/GridItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Autodesk.DesignScript.Runtime;
using Autodesk.Revit.DB;

namespace OpenMEPRevit.ClassModel;

[IsVisibleInDynamoLibrary(false)]
public class GridItem
{
public Autodesk.Revit.DB.Grid Grid { get; set; }

public bool IsHorizontal => Direction(Grid.Curve)!.IsAlmostEqualTo(XYZ.BasisX);

public GridItem(Autodesk.Revit.DB.Grid grid)
{
Grid = grid;
}

public double DistanceTo(XYZ? point)
{
Curve curve = this.Grid.Curve;
var plane = Plane.CreateByNormalAndOrigin(new XYZ(0, 0, 1), XYZ.Zero);
Curve newcurve = ProjectLineOnPlane(plane, curve);
XYZ p = ProjectPointOnPlane(plane, point);
// get distance curve to point
double distance = newcurve.Distance(p);
return distance;
}

XYZ ProjectPointOnPlane(Autodesk.Revit.DB.Plane plane, XYZ? point)
{
var origin = plane.Origin;
var normal = plane.Normal;
var v = point - origin;
var d = normal.DotProduct(v);
return point - d * normal;
}

Autodesk.Revit.DB.Curve ProjectLineOnPlane(Autodesk.Revit.DB.Plane plane, Autodesk.Revit.DB.Curve line)
{
var origin = plane.Origin;
var normal = plane.Normal;
var v = line.GetEndPoint(0) - origin;
var d = normal.DotProduct(v);
var p0 = line.GetEndPoint(0) - d * normal;
v = line.GetEndPoint(1) - origin;
d = normal.DotProduct(v);
var p1 = line.GetEndPoint(1) - d * normal;
return Autodesk.Revit.DB.Line.CreateBound(p0, p1);
}
XYZ? Direction(Autodesk.Revit.DB.Curve curve)
{
Line? line = curve as Line;
return line?.Direction;
}
}
164 changes: 146 additions & 18 deletions OpenMEPRevit/Element/Element.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using Autodesk.DesignScript.Runtime;
using Autodesk.Revit.DB;
using Dynamo.Graph.Nodes;
using OpenMEPRevit.ClassModel;
using OpenMEPRevit.Helpers;
using ProtoCore.Lang;
using Revit.Elements;
using Revit.GeometryConversion;
using RevitServices.Persistence;
using RevitServices.Transactions;
using Grid = Autodesk.Revit.DB.Grid;
using Level = Autodesk.Revit.DB.Level;
using Point = Autodesk.DesignScript.Geometry.Point;

Expand Down Expand Up @@ -37,10 +41,18 @@ private Element()
{
if (element == null)
throw new ArgumentNullException(nameof(element));
if (element.InternalElement is IndependentTag)
{
XYZ min = element.BoundingBox.MinPoint.ToXyz();
XYZ max = element.BoundingBox.MaxPoint.ToXyz();
return min.Add(max).Divide(2).ToPoint();
}

if (element.InternalElement is Autodesk.Revit.DB.FabricationPart fabricationPart)
{
return fabricationPart.Origin.ToPoint();
}

if (element.InternalElement.Location is LocationPoint)
{
LocationPoint? lc = element.InternalElement.Location as LocationPoint;
Expand All @@ -53,10 +65,122 @@ private Element()
return lc?.Curve.Evaluate(0.5, false).ToPoint();
}

BoundingBoxXYZ bb = element.InternalElement.get_BoundingBox(null);
BoundingBoxXYZ? bb = element.InternalElement.get_BoundingBox(null);
if (bb == null)
{
return null;
}

return bb.Max.Add(bb.Min).Divide(0.5).ToPoint();
}

/// <summary>
/// Get the location of the element belong to the grid line with the closest distance
/// the location include the top, bottom, left, right grid line
/// </summary>
/// <param name="element">the elements</param>
/// <returns></returns>
[NodeCategory("Query")]
[MultiReturn("TopGrid", "BottomGrid", "LeftGrid", "RightGrid")]
public static Dictionary<string, object?> GetLocationGridLine(Revit.Elements.Element element)
{
var doc = DocumentManager.Instance.CurrentDBDocument;
List<GridItem> grids = GetGrids(doc);
XYZ? location = GetLocation(element)?.ToXyz();
if (location == null)
{
return new Dictionary<string, object?>()
{
{ "TopGrid", null },
{ "BottomGrid", null },
{ "LeftGrid", null },
{ "RightGrid", null }
};
}

Grid? topGrid = null;
Grid? bottomGrid = null;
Grid? leftGrid = null;
Grid? rightGrid = null;

var xGrids = grids.Where(x => x.IsHorizontal).ToList();
var yGrids = grids.Where(x => !x.IsHorizontal).ToList();
// top
double locationY = location.Y;
double yDistance = double.MaxValue;
foreach (var item in xGrids)
{
double yCurrent = item.Grid.Curve.GetEndPoint(0).Y;
double distanceTo = item.DistanceTo(location);
if (yCurrent >= locationY && distanceTo <= yDistance)
{
yDistance = distanceTo;
topGrid = item.Grid;
}
}

// bottom
yDistance = double.MaxValue;
foreach (var item in xGrids)
{
double yCurrent = item.Grid.Curve.GetEndPoint(0).Y;
double distanceTo = item.DistanceTo(location);
if (yCurrent <= locationY && distanceTo <= yDistance)
{
yDistance = distanceTo;
bottomGrid = item.Grid;
}
}

// left
double locationX = location.X;
double xDistance = double.MaxValue;
foreach (var item in yGrids)
{
double xCurrent = item.Grid.Curve.GetEndPoint(0).X;
double distanceTo = item.DistanceTo(location);
if (xCurrent <= locationX && distanceTo <= xDistance)
{
xDistance = distanceTo;
leftGrid = item.Grid;
}
}

// right
xDistance = double.MaxValue;
foreach (var item in yGrids)
{
double xCurrent = item.Grid.Curve.GetEndPoint(0).X;
double distanceTo = item.DistanceTo(location);
if (xCurrent >= locationX && distanceTo <= xDistance)
{
xDistance = distanceTo;
rightGrid = item.Grid;
}
}

return new Dictionary<string, object?>()
{
{ "TopGrid", topGrid?.ToDynamoType() },
{ "BottomGrid", bottomGrid?.ToDynamoType() },
{ "LeftGrid", leftGrid?.ToDynamoType() },
{ "RightGrid", rightGrid?.ToDynamoType() }
};
}

private static List<GridItem> GetGrids(Autodesk.Revit.DB.Document doc)
{
List<GridItem> gridItems = new List<GridItem>();
FilteredElementCollector collector = new FilteredElementCollector(doc);
var grids = collector.OfClass(typeof(Grid)).Cast<Autodesk.Revit.DB.Grid>().ToList();
foreach (Grid grid in grids)
{
gridItems.Add(new GridItem(grid));
}

return gridItems;
}

/// <summary>
/// Returns the Document in which the Element resides
/// </summary>
Expand All @@ -71,8 +195,8 @@ private Element()
{
return new Dictionary<string, object?>
{
{"Revit Document", element.InternalElement.Document},
{"Dynamo Document", element.InternalElement.Document.ToDynamoType()}
{ "Revit Document", element.InternalElement.Document },
{ "Dynamo Document", element.InternalElement.Document.ToDynamoType() }
};
}

Expand All @@ -95,7 +219,7 @@ private Element()
TransactionManager.Instance.TransactionTaskDone();
return element;
}

/// <summary>
/// Move the list collection of elements to new location
/// </summary>
Expand All @@ -106,17 +230,19 @@ private Element()
/// ![](../OpenMEPPage/element/dyn/pic/Element.MoveElements.png)
/// </example>
[NodeCategory("Action")]
public static List<Revit.Elements.Element> MoveElements(List<Revit.Elements.Element> elements, List<Point> newLocations)
public static List<Revit.Elements.Element> MoveElements(List<Revit.Elements.Element> elements,
List<Point> newLocations)
{
Autodesk.Revit.DB.Document doc = DocumentManager.Instance.CurrentDBDocument;
TransactionManager.Instance.EnsureInTransaction(doc);
if(elements.Count != newLocations.Count)
if (elements.Count != newLocations.Count)
throw new Exception("The number of elements and new locations must be the same.");
for (int i = 0; i < elements.Count; i++)
{
ElementTransformUtils.MoveElement(doc, elements[i].InternalElement.Id,
newLocations[i].ToXyz().Subtract(GetLocation(elements[i]).ToXyz()));
}

TransactionManager.Instance.TransactionTaskDone();
return elements;
}
Expand All @@ -141,11 +267,11 @@ private Element()
TransactionManager.Instance.EnsureInTransaction(doc);
double degree2Radian = angle * Math.PI / 180;
ElementTransformUtils.RotateElement(doc, element.InternalElement.Id,
(Autodesk.Revit.DB.Line) lineAxis.ToRevitType(), degree2Radian);
(Autodesk.Revit.DB.Line)lineAxis.ToRevitType(), degree2Radian);
TransactionManager.Instance.TransactionTaskDone();
return element;
}

/// <summary>
/// Set Rotate multiple family instances
/// This will be help save time when you have a lot of elements to rotate because just one transaction
Expand All @@ -162,7 +288,7 @@ private Element()
List<Autodesk.DesignScript.Geometry.Line> lineAxis,
List<double> angles)
{
if(elements.Count != lineAxis.Count)
if (elements.Count != lineAxis.Count)
throw new Exception("The number of elements and line axis must be the same");
TransactionManager.Instance.ForceCloseTransaction();
Autodesk.Revit.DB.Document doc = DocumentManager.Instance.CurrentDBDocument;
Expand All @@ -171,8 +297,9 @@ private Element()
{
double degree2Radian = angles[i] * Math.PI / 180;
ElementTransformUtils.RotateElement(doc, elements[i].InternalElement.Id,
(Autodesk.Revit.DB.Line) lineAxis[i].ToRevitType(), degree2Radian);
(Autodesk.Revit.DB.Line)lineAxis[i].ToRevitType(), degree2Radian);
}

TransactionManager.Instance.TransactionTaskDone();
return elements;
}
Expand All @@ -192,11 +319,11 @@ private Element()
List<Autodesk.DesignScript.Geometry.Vector> vectorAxis,
List<double> angles)
{
if(elements.Count != vectorAxis.Count)
if (elements.Count != vectorAxis.Count)
throw new Exception("The number of elements and vector axis must be the same");
Autodesk.Revit.DB.Document doc = DocumentManager.Instance.CurrentDBDocument;
TransactionManager.Instance.EnsureInTransaction(doc);

for (int i = 0; i < elements.Count; i++)
{
double degree2Radian = angles[i] * Math.PI / 180;
Expand All @@ -205,12 +332,13 @@ private Element()
Autodesk.Revit.DB.Line line =
Autodesk.Revit.DB.Line.CreateBound(location!.Add(vectorAxis[i].ToRevitType().Multiply(2)), location);
ElementTransformUtils.RotateElement(doc, elements[i].InternalElement.Id,
(Autodesk.Revit.DB.Line) line, degree2Radian);
(Autodesk.Revit.DB.Line)line, degree2Radian);
}

TransactionManager.Instance.TransactionTaskDone();
return elements;
}

/// <summary>
/// Set Rotate of fitting By Vector
/// </summary>
Expand All @@ -235,7 +363,7 @@ private Element()
Autodesk.Revit.DB.Line line =
Autodesk.Revit.DB.Line.CreateBound(location!.Add(vectorAxis.ToRevitType().Multiply(2)), location);
ElementTransformUtils.RotateElement(doc, element.InternalElement.Id,
(Autodesk.Revit.DB.Line) line, degree2Radian);
(Autodesk.Revit.DB.Line)line, degree2Radian);
TransactionManager.Instance.TransactionTaskDone();
return element;
}
Expand Down Expand Up @@ -277,7 +405,6 @@ private Element()

#else
if (levelId.Value == -1)

#endif
{
// General get level method
Expand Down Expand Up @@ -361,7 +488,7 @@ private Element()
{
if (element == null) throw new ArgumentNullException(nameof(element));
List<Connector> connectors = ConnectorManager.Connector.GetConnectors(element);
if (connectors.Count==0) return null;
if (connectors.Count == 0) return null;
dynamic? systemType = connectors.Select(x => ConnectorManager.Connector.SystemType(x)).FirstOrDefault();
return systemType;
}
Expand All @@ -383,7 +510,7 @@ private Element()
if (connectors.Count == 0) return new List<Revit.Elements.Element>();
foreach (var connector in connectors)
{
if(connector== null) continue;
if (connector == null) continue;
ConnectorSet connectedConnectors = connector.AllRefs;
foreach (Connector connectedConnector in connectedConnectors)
{
Expand All @@ -394,6 +521,7 @@ private Element()
}
}
}

if (connectedElements.Count == 0) return new List<Revit.Elements.Element>();
return connectedElements.Select(x => x.ToDynamoType()).ToList();
}
Expand Down
4 changes: 2 additions & 2 deletions OpenMEPRevit/Element/ImportInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ private ImportInstance()
{
ElementId elementId = import.GetTypeId();
ElementType? elementType = import.Document.GetElement(elementId) as Autodesk.Revit.DB.ElementType;
IDictionary<ExternalResourceType,ExternalResourceReference> externalResourceReferences = elementType.GetExternalResourceReferences();
foreach (KeyValuePair<ExternalResourceType, ExternalResourceReference> externalResourceReference in externalResourceReferences)
IDictionary<ExternalResourceType, ExternalResourceReference>? externalResourceReferences = elementType?.GetExternalResourceReferences();
foreach (KeyValuePair<ExternalResourceType, ExternalResourceReference> externalResourceReference in externalResourceReferences!)
{
IDictionary<string,string> information = externalResourceReference.Value.GetReferenceInformation();
foreach (KeyValuePair<string, string> keyValuePair in information)
Expand Down
4 changes: 2 additions & 2 deletions OpenMEPRevit/OpenMEPRevit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@
<DefineConstants>$(DefineConstants);R23</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('Debug R24'))">
<DynamoVersion>2.18</DynamoVersion>
<DynamoOutput>2.18</DynamoOutput>
<DynamoVersion>2.19</DynamoVersion>
<DynamoOutput>2.19</DynamoOutput>
<RevitVersion>2024</RevitVersion>
<TargetFramework>net48</TargetFramework>
<DefineConstants>$(DefineConstants);R24</DefineConstants>
Expand Down

0 comments on commit 83e7673

Please sign in to comment.