Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions src/RhinoInside.Revit.External/DB/Extensions/GeometryObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -666,17 +666,16 @@ public int GetHashCode(GeometryObject value)

public static class GeometryObjectExtension
{
internal static bool IsValid(this GeometryObject geometry) => geometry?.IsValidObject() ?? false;

internal static bool IsValidObject(this GeometryObject geometry)
internal static bool IsEmpty(this GeometryObject geometry)
{
#if REVIT_2021
try { return geometry.Id >= 0; }
#else
// TODO : Test this, type by type, and use a faster fail check.
try { return geometry.TryGetLocation(out var _, out var _, out var _);}
#endif
catch { return false; }
switch (geometry)
{
case PolyLine pline: return pline.NumberOfCoordinates == 0;
case Mesh mesh: return mesh.NumTriangles == 0;
case Solid solid: return solid.Faces.IsEmpty;
}

return false;
}

public static bool AlmostEquals<G>(this G left, G right)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,8 @@ protected override void TrySolveInstance(IGH_DataAccess DA)
return;
}

var hostId = default(ARDB.ElementId);

if (element.Value is ARDB.Structure.Rebar rebar) hostId = rebar.GetHostId();
else if (element.Value is ARDB.Structure.RebarInSystem rebarInSystem) hostId = rebarInSystem.GetHostId();
else if (element.Value is ARDB.Structure.RebarContainer rebarContainer) hostId = rebarContainer.GetHostId();
else if (element.Value is ARDB.Structure.AreaReinforcement areaReinforcement) hostId = areaReinforcement.GetHostId();
else if (element.Value is ARDB.Structure.PathReinforcement pathReinforcement) hostId = pathReinforcement.GetHostId();
else if (element.Value is ARDB.Structure.FabricSheet fabricSheet) hostId = fabricSheet.HostId;
else if (element.Value is ARDB.FabricationPart fabricationPart)
{
using (var hostedInfo = fabricationPart.GetHostedInfo())
hostId = hostedInfo.HostId;
}
else hostId = element.Value.get_Parameter(ARDB.BuiltInParameter.HOST_ID_PARAM)?.AsElementId();

// Default to Level if hostId is null
DA.SetData("Host", element.GetElement<Types.GraphicalElement>(hostId ?? element.LevelId));
DA.SetData("Host", element.GetElement<Types.GraphicalElement>(element.Level));
}
}
}
31 changes: 29 additions & 2 deletions src/RhinoInside.Revit.GH/Parameters/Reference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Reflection;
using System.Windows.Forms;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Types;
using Rhino;
using Rhino.DocObjects;
using ARDB = Autodesk.Revit.DB;
Expand Down Expand Up @@ -209,14 +210,40 @@ bool Kernel.IGH_ReferenceParam.NeedsToBeExpired
continue;

if (modified.Contains(elementId))
return true;
return ReloadReferencedData(reload: true);

if (deleted.Contains(elementId))
return true;
return ReloadReferencedData(reload: false);
}

return false;
}

private bool ReloadReferencedData(bool reload)
{
if (typeof(Types.IGH_GeometryObject).IsAssignableFrom(typeof(T)))
{
if (OnPingDocument() is GH_Document document)
{
GH_Document.SolutionEndEventHandler SolutionEndEventHandler = default;
document.SolutionEnd += SolutionEndEventHandler = (s, a) =>
{
document.SolutionEnd -= SolutionEndEventHandler;

foreach (var data in VolatileData.AllData(true).OfType<IGH_ReferencedData>())
{
if (data is Types.IGH_GeometryObject)
{
data.UnloadReferencedData();
if (reload) data.LoadReferencedData();
}
}
};
}
}

return true;
}
#endregion

#region IGH_BakeAwareObject
Expand Down
15 changes: 8 additions & 7 deletions src/RhinoInside.Revit.GH/Types/GeometricElement+Bake.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ out int index
return true;
}

var geometryElementContent = geometryElement.ToArray();
if (geometryElementContent.Length < 1)
var geometryElementContent = geometryElement?.Where(x => !x.IsEmpty()).ToArray() ?? Array.Empty<ARDB.GeometryObject>();
if (geometryElementContent.Length == 0)
{
index = -1;
return false;
Expand All @@ -138,8 +138,9 @@ geometryElementContent[0] is ARDB.GeometryInstance geometryInstance &&
)
{
// Special case to simplify ARDB.FamilyInstance elements.
var instanceTransform = geometryInstance.Transform.ToTransform();
return BakeGeometryElement(idMap, false, doc, instanceTransform * transform, symbol, geometryInstance.SymbolGeometry, out index);
var instanceTransform = geometryInstance.Transform.ToTransform() * transform;
if (instanceTransform.IsIdentity)
return BakeGeometryElement(idMap, false, doc, instanceTransform, symbol, geometryInstance.SymbolGeometry, out index);
}

// Get a Unique Instance Definition name.
Expand Down Expand Up @@ -167,10 +168,10 @@ geometryElementContent[0] is ARDB.GeometryInstance geometryInstance &&
var objectGeometry = default(GeometryBase);
switch (g)
{
case ARDB.Mesh m: if (m.NumTriangles > 0) objectGeometry = m.ToMesh(); break;
case ARDB.Solid s: if (!s.Faces.IsEmpty) objectGeometry = s.ToBrep(); break;
case ARDB.Mesh m: objectGeometry = m.ToMesh(); break;
case ARDB.Solid s: objectGeometry = s.ToBrep(); break;
case ARDB.Curve c: objectGeometry = c.ToCurve(); break;
case ARDB.PolyLine p: if (p.NumberOfCoordinates > 0) objectGeometry = p.ToPolylineCurve(); break;
case ARDB.PolyLine p: objectGeometry = p.ToPolylineCurve(); break;
case ARDB.GeometryInstance i:
using (GeometryDecoder.Context.Push())
{
Expand Down
10 changes: 4 additions & 6 deletions src/RhinoInside.Revit.GH/Types/GeometricElement+ModelContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ ARDB.GeometryElement geometryElement
if (idMap.TryGetValue(element.Id, out var modelContent))
return modelContent as ModelInstanceDefinition;

var geometryElementContent = geometryElement?.ToArray() ?? Array.Empty<ARDB.GeometryObject>();
var geometryElementContent = geometryElement?.Where(x => !x.IsEmpty()).ToArray() ?? Array.Empty<ARDB.GeometryObject>();
if (geometryElementContent.Length == 0)
return null;

Expand All @@ -58,8 +58,9 @@ geometryElementContent[0] is ARDB.GeometryInstance geometryInstance &&
)
{
// Special case to simplify ARDB.FamilyInstance elements.
var instanceTransform = geometryInstance.Transform.ToTransform();
return ToModelInstanceDefinition(idMap, instanceTransform * transform, symbol, geometryInstance.SymbolGeometry);
var instanceTransform = geometryInstance.Transform.ToTransform() * transform;
if (instanceTransform.IsIdentity)
return ToModelInstanceDefinition(idMap, instanceTransform, symbol, geometryInstance.SymbolGeometry);
}

var definition = new ModelInstanceDefinition.Attributes()
Expand Down Expand Up @@ -89,7 +90,6 @@ geometryElementContent[0] is ARDB.GeometryInstance geometryInstance &&
break;

case ARDB.PolyLine pline:
if (pline.NumberOfCoordinates == 0) continue;
var plineGeometry = pline.ToPolylineCurve();
if (!identity) plineGeometry.Transform(transform);
geo = new GH_Curve(plineGeometry);
Expand All @@ -102,15 +102,13 @@ geometryElementContent[0] is ARDB.GeometryInstance geometryInstance &&
break;

case ARDB.Mesh mesh:
if (mesh.NumTriangles == 0) continue;
var meshGeometry = mesh.ToMesh();
if (!identity) meshGeometry.Transform(transform);
geo = new GH_Mesh(meshGeometry);
shaded = true;
break;

case ARDB.Solid solid:
if (solid.Faces.IsEmpty) continue;
var solidGeometry = solid.ToBrep();
if (!identity) solidGeometry.Transform(transform);
if (solidGeometry.TryGetExtrusion(out var extrusion)) geo = new GH_Extrusion(extrusion);
Expand Down
30 changes: 27 additions & 3 deletions src/RhinoInside.Revit.GH/Types/GeometricElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,33 @@ public GeometricElement(ARDB.Element element) : base(element) { }
#region IHostElementAccess
GraphicalElement IHostElementAccess.HostElement => HostElement;

public virtual GraphicalElement HostElement => Value is ARDB.Element element ?
GetElement<GraphicalElement>(element.LevelId) :
default;
public virtual GraphicalElement HostElement
{
get
{
if (Value is ARDB.Element element)
{
var hostId = default(ARDB.ElementId);

if (element is ARDB.Structure.Rebar rebar) hostId = rebar.GetHostId();
else if (element is ARDB.Structure.RebarInSystem rebarInSystem) hostId = rebarInSystem.GetHostId();
else if (element is ARDB.Structure.RebarContainer rebarContainer) hostId = rebarContainer.GetHostId();
else if (element is ARDB.Structure.AreaReinforcement areaReinforcement) hostId = areaReinforcement.GetHostId();
else if (element is ARDB.Structure.PathReinforcement pathReinforcement) hostId = pathReinforcement.GetHostId();
else if (element is ARDB.Structure.FabricSheet fabricSheet) hostId = fabricSheet.HostId;
else if (element is ARDB.FabricationPart fabricationPart)
{
using (var hostedInfo = fabricationPart.GetHostedInfo())
hostId = hostedInfo.HostId;
}
else hostId = element.get_Parameter(ARDB.BuiltInParameter.HOST_ID_PARAM)?.AsElementId();

return GetElement<GraphicalElement>(hostId ?? LevelId);
}

return default;
}
}
#endregion
}
}
24 changes: 7 additions & 17 deletions src/RhinoInside.Revit.GH/Types/GeometryObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,7 @@ public override bool ConvertTo<Q>(out Q target)

public override object ScriptVariable() => Value;

public new ARDB.GeometryObject Value
{
get
{
var geometryObject = base.Value as ARDB.GeometryObject;
switch (geometryObject?.IsValidObject())
{
case false:
Debug.WriteLine("GeometryObject is not valid.");
ResetValue();
return base.Value as ARDB.GeometryObject;

case true: return geometryObject;
default: return null;
}
}
}
public new ARDB.GeometryObject Value => base.Value as ARDB.GeometryObject;

protected override object FetchValue()
{
Expand Down Expand Up @@ -158,6 +142,12 @@ protected void SetValue(ARDB.Document document, ARDB.Reference reference)

protected override void SubInvalidateGraphics()
{
_Location = null;
_Wires = null;
_Meshes = null;
_LevelOfDetail = double.NaN;
_ClippingBox = default;

base.SubInvalidateGraphics();
}
#endregion
Expand Down
20 changes: 10 additions & 10 deletions src/RhinoInside.Revit/GH/Guest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -558,11 +558,7 @@ void Revit_DocumentChanged(object sender, ARDB.Events.DocumentChangedEventArgs e
{
var activeDefinition = definition.SolutionState == GH_ProcessStep.Process;

// Prevent delayed solutions.
if (activeDefinition)
continue;

var change = new DocumentChangedEvent()
var change = activeDefinition ? null: new DocumentChangedEvent()
{
Operation = e.Operation,
Document = document,
Expand All @@ -588,13 +584,13 @@ void Revit_DocumentChanged(object sender, ARDB.Events.DocumentChangedEventArgs e
if (obj is Kernel.IGH_ReferenceParam persistentParam)
{
if (persistentParam.NeedsToBeExpired(document, added, deleted, modified))
change.ExpiredObjects.Add(persistentParam);
change?.ExpiredObjects.Add(persistentParam);
}
else if (obj is Kernel.IGH_ReferenceComponent persistentComponent)
{
if (persistentComponent.NeedsToBeExpired(document, added, deleted, modified))
{
change.ExpiredObjects.Add(persistentComponent);
change?.ExpiredObjects.Add(persistentComponent);
}
else
{
Expand All @@ -607,7 +603,7 @@ void Revit_DocumentChanged(object sender, ARDB.Events.DocumentChangedEventArgs e
if (activeDefinition && recipient.Phase == GH_SolutionPhase.Blank)
continue;

change.ExpiredObjects.Add(recipient.Attributes.GetTopLevel.DocObject as IGH_ActiveObject);
change?.ExpiredObjects.Add(recipient.Attributes.GetTopLevel.DocObject as IGH_ActiveObject);
}
}
}
Expand All @@ -616,7 +612,11 @@ void Revit_DocumentChanged(object sender, ARDB.Events.DocumentChangedEventArgs e
} catch { }
}

if (change.ExpiredObjects.Count > 0)
// Prevent delayed solutions but notify components & params about changes.
if (activeDefinition)
continue;

if (change?.ExpiredObjects.Count > 0)
DocumentChangedEvent.Enqueue(change);
}
}
Expand Down Expand Up @@ -664,7 +664,7 @@ public static void Enqueue(DocumentChangedEvent value)
}
#if DEBUG
else if (!System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.Escape))
{
{
value.Definition.ScheduleSolution
(
delay: 500,
Expand Down
Loading