From eaf90658c74908e88bb9af4f8f22d7c9f6adb2f4 Mon Sep 17 00:00:00 2001 From: Carson Date: Tue, 21 May 2024 13:59:28 -0500 Subject: [PATCH 01/11] Creation --- CarsonsAddins/CarsonsAddins.csproj | 4 +- .../DimensionSettingsWindow.xaml.cs | 3 +- .../Pipeline/Models/DimensionPipeline.cs | 35 +++- .../PipingElementReferenceOrderedList.cs | 124 +++++++++--- .../Updaters/ParameterManagerUpdater.cs | 7 +- .../Shared/Utils/DimensioningUtils.cs | 51 +++-- CarsonsAddins/Shared/Utils/GeometryUtils.cs | 184 ++++++++++++++---- .../Standalone/DebugGeometryCommand.cs | 98 ++++++++++ 8 files changed, 414 insertions(+), 92 deletions(-) create mode 100644 CarsonsAddins/Standalone/DebugGeometryCommand.cs diff --git a/CarsonsAddins/CarsonsAddins.csproj b/CarsonsAddins/CarsonsAddins.csproj index 28ae44b..dafecb6 100644 --- a/CarsonsAddins/CarsonsAddins.csproj +++ b/CarsonsAddins/CarsonsAddins.csproj @@ -141,6 +141,7 @@ + @@ -156,10 +157,11 @@ - + + diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs index a890bba..b8b1974 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs +++ b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs @@ -49,7 +49,7 @@ public DimensionSettingsWindow() public void Init(UIDocument uidoc) { DimensionStylesSettings = new DimensionStyles(); - BuiltInCategory[] pipingCategories = new BuiltInCategory[] {BuiltInCategory.OST_PipeCurves, BuiltInCategory.OST_PipeFitting, BuiltInCategory.OST_PipeAccessory, BuiltInCategory.OST_MechanicalEquipment, BuiltInCategory.OST_PipeCurvesCenterLine, BuiltInCategory.OST_PipeFittingCenterLine, BuiltInCategory.OST_CenterLines}; + BuiltInCategory[] pipingCategories = new BuiltInCategory[] {BuiltInCategory.OST_PipeCurves, BuiltInCategory.OST_PipeFitting, BuiltInCategory.OST_PipeAccessory, BuiltInCategory.OST_MechanicalEquipment, BuiltInCategory.OST_PipeCurvesCenterLine, BuiltInCategory.OST_PipeFittingCenterLine, BuiltInCategory.OST_CenterLines, BuiltInCategory.OST_ReferenceLines}; dimensionTypes = new FilteredElementCollector(uidoc.Document).WhereElementIsElementType().OfClass(typeof(DimensionType)).ToElements().Cast().Where(dt => DimensionStyleType.Linear.Equals(dt.StyleType)).ToArray(); graphicStyles = new FilteredElementCollector(uidoc.Document).OfClass(typeof(GraphicsStyle)).Cast().Where(gs => pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Id.IntegerValue) || ((gs.GraphicsStyleCategory.Parent != null) && pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Parent.Id.IntegerValue))).ToArray(); LoadFromDB(); @@ -57,6 +57,7 @@ public void Init(UIDocument uidoc) GraphicsStyleList.Init(graphicStyles, ref DimensionStylesSettings.centerlineStyles); //DimensionPreviewControl.AddPreviewControlWithCustomView(uidoc.Document); } + public PushButtonData RegisterButton(Assembly assembly) { return new PushButtonData("Dimension Pipeline Settings", "Dimension Pipeline Settings", assembly.Location, typeof(GenericCommands.ShowWindow).FullName) diff --git a/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs b/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs index b95f403..d44bc01 100644 --- a/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs +++ b/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs @@ -108,10 +108,10 @@ public static void CreateDimensions(Document doc, Element[] elements, Element se AddReferences(ref primaryReferenceArray, ref secondaryReferenceArray, node, secondaryDimension); if (node.firstReference != null || node.lastReference != null) matchesPrimary = false; bool splitDimension = (i == referenceSets.nodes.Length - 1) || (node.mode == PipingElementReferenceOrderedList.FlangeDimensionMode.Ignore || (node.mode == PipingElementReferenceOrderedList.FlangeDimensionMode.Partial && (node.isEdge || node.adjacentNonLinear))); - if (splitDimension && secondaryReferenceArray.Size > 1) + if (splitDimension) { BuiltInCategory builtInCategory = (node.referenceCount == secondaryReferenceArray.Size) ? node.builtInCategory : BuiltInCategory.OST_PipeCurves; - if (!matchesPrimary) doc.Create.NewDimension(activeView, secondaryDimensionLine, secondaryReferenceArray, dimensionStyles.GetSecondaryDimensionType(builtInCategory) ?? defaultDimensionType); + if (!matchesPrimary && secondaryReferenceArray.Size > 1) doc.Create.NewDimension(activeView, secondaryDimensionLine, secondaryReferenceArray, dimensionStyles.GetSecondaryDimensionType(builtInCategory) ?? defaultDimensionType); secondaryReferenceArray.Clear(); matchesPrimary = true; } @@ -120,19 +120,36 @@ public static void CreateDimensions(Document doc, Element[] elements, Element se doc.Create.NewDimension(activeView, primaryDimensionLine, primaryReferenceArray, dimensionStyles.primaryDimensionType ?? defaultDimensionType); } private static void AddReferences(ref ReferenceArray primaryReferenceArray, ref ReferenceArray secondaryReferenceArray, PipingElementReferenceOrderedList.ReferenceNode node, bool secondaryDimension) - { - if (node.isStart && node.centerReference == null && node.lastReference != null) primaryReferenceArray.Append(node.lastReference); - if (node.centerReference != null) primaryReferenceArray.Append(node.centerReference); - if (node.isEnd && node.centerReference == null && node.firstReference != null) primaryReferenceArray.Append(node.firstReference); + { + if (node.isEdge) + { + if (node.isLinear) + { + if (node.isEnd) AddReferenceIfNotNull(ref primaryReferenceArray, node.lastReference); + else if (node.isStart) AddReferenceIfNotNull(ref primaryReferenceArray, node.firstReference); + } + else if (node.centerReference == null) + { + if (node.isStart) AddReferenceIfNotNull(ref primaryReferenceArray, node.lastReference); + else if (node.isEnd) AddReferenceIfNotNull(ref primaryReferenceArray, node.firstReference); + } + } + AddReferenceIfNotNull(ref primaryReferenceArray, node.centerReference); + if (secondaryDimension) { - if (node.firstReference != null) secondaryReferenceArray.Append(node.firstReference); - if (node.centerReference != null) secondaryReferenceArray.Append(node.centerReference); - if (node.lastReference != null) secondaryReferenceArray.Append(node.lastReference); + AddReferenceIfNotNull(ref secondaryReferenceArray, node.firstReference); + AddReferenceIfNotNull(ref secondaryReferenceArray, node.centerReference); + AddReferenceIfNotNull(ref secondaryReferenceArray, node.lastReference); } } + private static void AddReferenceIfNotNull(ref ReferenceArray referenceArray, Reference reference) + { + if (referenceArray == null || reference == null) return; + referenceArray.Append(reference); + } } } diff --git a/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs b/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs index 22d1051..18ba14d 100644 --- a/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs +++ b/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs @@ -6,7 +6,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; - namespace CarsonsAddins.Pipeline.Models { class PipingElementReferenceOrderedList @@ -25,50 +24,122 @@ public PipingElementReferenceOrderedList(ElementId[] validStyleIds, View activeV private void PopulateNodes(ElementId[] validStyleIds, View activeView) { Plane plane = activeView.SketchPlane.GetPlane(); - nodes[0] = new ReferenceNode + for (int i = 0; i < orderedElements.Length; i++) { - builtInCategory = (BuiltInCategory)orderedElements[0].Category.Id.IntegerValue, - mode = GetMode(orderedElements[0]), - origin = GeometryUtils.GetOrigin(orderedElements[0].Location), - isStart = true, - isEnd = false, - adjacentNonLinear = false, - isLinear = ConnectionUtils.IsLinearElement(orderedElements[0]), - centerReference = (!ElementCheckUtils.IsPipeFlange(orderedElements[0])) ? DimensioningUtils.GetEndReference(activeView, validStyleIds, orderedElements[0]) : null - }; - nodes[0].adjacentNonLinear = nodes[0].isLinear; - for (int i = 1; i < orderedElements.Length; i++) + CreateReferenceNode(i); + } + if (nodes.Length > 1) { - CreateReferenceNode(validStyleIds, activeView, plane, i); + if (nodes[0].isLinear ) + { + Connector connector = ConnectionUtils.GetParallelConnector(ConnectionUtils.GetConnectors(orderedElements[0]).Where(con => ConnectionUtils.IsConnectedTo(orderedElements[1], con)).FirstOrDefault()); + //nodes[0].firstReference = GetPseudoConnectorReference(validStyleIds, activeView, plane, connector); + nodes[0].firstConnector = connector; + } + if (nodes[nodes.Length - 1].isLinear) + { + Connector connector = ConnectionUtils.GetParallelConnector(ConnectionUtils.GetConnectors(orderedElements[nodes.Length - 1]).Where(con => ConnectionUtils.IsConnectedTo(orderedElements[nodes.Length - 2], con)).FirstOrDefault()); + //nodes[nodes.Length - 1].lastReference = GetPseudoConnectorReference(validStyleIds, activeView, plane, connector); + nodes[0].lastConnector = connector; + + } + } + else if (nodes[0].isLinear) + { + Connector[] connectors = ConnectionUtils.GetConnectors(orderedElements[0]); + nodes[0].firstConnector = connectors[0]; + nodes[0].lastConnector = connectors[1]; } + PopulateNodeReferences(validStyleIds, activeView); + FillAdjacentNodeReferences(); SetAdjacentNonLinear(); } - private void CreateReferenceNode(ElementId[] validStyleIds, View activeView, Plane plane, int index) + private void CreateReferenceNode(int index) { Element element = orderedElements[index]; + //Reference currentFirstReference = null; + Connector firstConnector = null; + if (index > 0) + { + (Connector, Connector) connection = ConnectionUtils.TryGetConnection(orderedElements[index - 1], element); + firstConnector = connection.Item2; + nodes[index - 1].lastConnector = connection.Item1; + //currentFirstReference = GetPseudoConnectorReference(validStyleIds, activeView, plane, connection.Item2); - (Connector, Connector) connection = ConnectionUtils.TryGetConnection(orderedElements[index - 1], element); - Reference currentFirstReference = GeometryUtils.GetPseudoReferenceOfConnector(GeometryUtils.GetGeometryOptions(), plane, connection.Item2) - ?? GeometryUtils.GetPseudoReferenceOfConnector(GeometryUtils.GetGeometryOptions(activeView), plane, connection.Item2); - - nodes[index - 1].lastReference = GeometryUtils.GetPseudoReferenceOfConnector(GeometryUtils.GetGeometryOptions(), plane, connection.Item1) - ?? GeometryUtils.GetPseudoReferenceOfConnector(GeometryUtils.GetGeometryOptions(activeView), plane, connection.Item1) ?? currentFirstReference; + //nodes[index - 1].lastReference = GetPseudoConnectorReference(validStyleIds, activeView, plane, connection.Item1) ?? currentFirstReference; + //currentFirstReference = currentFirstReference ?? nodes[index - 1].lastReference; + } bool isLinear = ConnectionUtils.IsLinearElement(element); + bool isStart = index == 0; bool isEnd = index == orderedElements.Length - 1; - bool isFlange = ElementCheckUtils.IsPipeFlange(element); + //bool isFlange = ElementCheckUtils.IsPipeFlange(element); nodes[index] = new ReferenceNode { builtInCategory = (BuiltInCategory)element.Category.Id.IntegerValue, mode = GetMode(element), origin = GeometryUtils.GetOrigin(element.Location), - isStart = false, + isStart = isStart, isEnd = isEnd, isLinear = isLinear, adjacentNonLinear = false, - centerReference = isFlange ? null : (isEnd) ? DimensioningUtils.GetEndReference(activeView, validStyleIds, element) : (!isLinear) ? DimensioningUtils.GetCenterReference(validStyleIds, element) : null, - firstReference = currentFirstReference ?? nodes[index - 1].lastReference, + //centerReference = isFlange ? null : (!isLinear) ? DimensioningUtils.GetProjectedCenterReference(GeometryUtils.GetGeometryOptions(), validStyleIds, plane, element) ?? DimensioningUtils.GetProjectedCenterReference(GeometryUtils.GetGeometryOptions(activeView), validStyleIds, plane, element) : null, + //firstReference = currentFirstReference, + firstConnector = firstConnector }; } + private Reference GetPseudoConnectorReference(ElementId[] validStyleIds, View activeView, Plane plane, Connector connector) + { + return GeometryUtils.GetPseudoReferenceOfConnector(validStyleIds, GeometryUtils.GetGeometryOptions(activeView), plane, connector) ?? + GeometryUtils.GetPseudoReferenceOfConnector(validStyleIds, GeometryUtils.GetGeometryOptions(), plane, connector); + } + + private Reference FindReference(GeometryUtils.XYZWithReference[] xyzReferences, Plane plane, XYZ xyz) + { + Reference reference = xyzReferences.Where(xyzReference => xyz.IsAlmostEqualTo(xyzReference.xyz)).FirstOrDefault().reference; + if (reference != null) return reference; + XYZ projectedXYZ = GeometryUtils.ProjectPointOntoPlane(plane, xyz); + Reference projectedReference = xyzReferences.Where(xyzReference => xyz.IsAlmostEqualTo(GeometryUtils.ProjectPointOntoPlane(plane, xyzReference.xyz))).FirstOrDefault().reference; + return projectedReference; + } + + private void PopulateNodeReferences(ElementId[] validStyleIds, View activeView) + { + Plane plane = activeView.SketchPlane.GetPlane(); + GeometryUtils.XYZWithReference[][] nodeReferencesWithView = Enumerable.Range(0,nodes.Length).Select(i => GeometryUtils.XYZWithReference.StripGeometryObjectsWithReferences(validStyleIds, GeometryUtils.GetGeometryOptions(activeView), orderedElements[i])).ToArray(); + GeometryUtils.XYZWithReference[][] nodeReferencesWithoutView = Enumerable.Range(0, nodes.Length).Select(i => GeometryUtils.XYZWithReference.StripGeometryObjectsWithReferences(validStyleIds, GeometryUtils.GetGeometryOptions(), orderedElements[i])).ToArray(); + for (int i = 0; i < nodes.Length; i++) + { + if (nodes[i].firstConnector != null) + { + XYZ firstConnectorOrigin = nodes[i].firstConnector.Origin; + nodes[i].firstReference = FindReference(nodeReferencesWithView[i], plane, firstConnectorOrigin) ?? FindReference(nodeReferencesWithoutView[i], plane, firstConnectorOrigin); + } + if (!nodes[i].isLinear) + { + XYZ origin = nodes[i].origin; + nodes[i].firstReference = FindReference(nodeReferencesWithView[i], plane, origin) ?? FindReference(nodeReferencesWithoutView[i], plane, origin); + } + if (nodes[i].lastConnector != null) + { + XYZ lastConnectorOrigin = nodes[i].lastConnector.Origin; + nodes[i].lastReference = FindReference(nodeReferencesWithView[i], plane, lastConnectorOrigin) ?? FindReference(nodeReferencesWithoutView[i], plane, lastConnectorOrigin); + } + + } + } + private void FillAdjacentNodeReferences() + { + for (int i = 0; i < nodes.Length - 1; i++) + { + if ((nodes[i].firstReference == null) != (nodes[i + 1].lastReference == null)) + { + Reference reference = nodes[i].firstReference ?? nodes[i].lastReference; + nodes[i].firstReference = reference; + nodes[i + 1].lastReference = reference; + } + + } + } private void SetAdjacentNonLinear() { for (int i = 0; i < nodes.Length; i++) @@ -173,7 +244,8 @@ public struct ReferenceNode public Reference firstReference; public Reference centerReference; public Reference lastReference; - + public Connector firstConnector; + public Connector lastConnector; } } diff --git a/CarsonsAddins/Shared/Updaters/ParameterManagerUpdater.cs b/CarsonsAddins/Shared/Updaters/ParameterManagerUpdater.cs index bf96708..6c644b4 100644 --- a/CarsonsAddins/Shared/Updaters/ParameterManagerUpdater.cs +++ b/CarsonsAddins/Shared/Updaters/ParameterManagerUpdater.cs @@ -59,8 +59,11 @@ private void RegisterTriggers() public void Execute(UpdaterData data) { if (parameterManager == null) return; - RemoveStaleReferences(data.GetDeletedElementIds().ToArray()); - RefreshParameters(data.GetModifiedElementIds().ToArray()); + ElementId[] deletedElementIds = data.GetModifiedElementIds().Where(elementId => elementIds.Contains(elementId)).ToArray(); + ElementId[] modifiedElementIds = data.GetModifiedElementIds().Where(elementId => elementIds.Contains(elementId)).ToArray(); + + RemoveStaleReferences(deletedElementIds); + RefreshParameters(modifiedElementIds); } private void RemoveStaleReferences(ElementId[] deletedElementIds) diff --git a/CarsonsAddins/Shared/Utils/DimensioningUtils.cs b/CarsonsAddins/Shared/Utils/DimensioningUtils.cs index 090be1e..36eaa78 100644 --- a/CarsonsAddins/Shared/Utils/DimensioningUtils.cs +++ b/CarsonsAddins/Shared/Utils/DimensioningUtils.cs @@ -292,21 +292,7 @@ public static Reference GetFlangeEndReference(Plane plane, Element flange, Eleme if (connector == null) return null; Connector adjacent = ConnectionUtils.GetAdjacentConnector(connector); if (adjacent == null) return null; - return GeometryUtils.GetPseudoReferenceOfConnector(GeometryUtils.GetGeometryOptions(), plane, adjacent); - } - - - /// - /// Retrieves a reference to the end point of a Piping Element. Meant to be used when dimensioning to a end of the Pipeline - /// - /// The active View. - /// The ElementIds corresponding to the valid centerline line styles. - /// a Piping Element - /// a Reference corresponding to the endpoint of the Piping Element. - public static Reference GetEndReference(View activeView, ElementId[] validStyleIds, Element element) - { - if (ElementCheckUtils.IsPipe(element)) return GetPipeEndReference(activeView, element as Pipe); - return GetCenterReference(validStyleIds, element); + return GeometryUtils.GetPseudoReferenceOfConnector(null, GeometryUtils.GetGeometryOptions(), plane, adjacent); } /// @@ -372,8 +358,7 @@ public static Reference GetCenterReference(ElementId[] validStyleIds, Element el { Line[] instanceLines = GeometryUtils.GetInstanceGeometryObjectsWithStyleIds(GeometryUtils.GetGeometryOptions(), element, validStyleIds); Line[] symbolLines = GeometryUtils.GetSymbolGeometryObjectsWithStyleIds(GeometryUtils.GetGeometryOptions(), element, validStyleIds); - if (instanceLines == null || symbolLines == null) return null; - if (instanceLines.Length == 0 || symbolLines.Length == 0) return null; + if (instanceLines == null || instanceLines.Length == 0 || symbolLines == null || symbolLines.Length == 0) return null; XYZ origin = GetOriginOfElement(element); int id = -1; int endIndex = -1; @@ -394,6 +379,31 @@ public static Reference GetCenterReference(ElementId[] validStyleIds, Element el return symbolLines.Where(line => line.Id.Equals(id)).FirstOrDefault()?.GetEndPointReference(endIndex); } + public static Reference GetProjectedCenterReference(Options geometryOptions, ElementId[] validStyleIds, Plane plane, Element element) + { + Line[] instanceLines = GeometryUtils.GetInstanceGeometryObjectsWithStyleIds(geometryOptions, element, validStyleIds); + Line[] symbolLines = GeometryUtils.GetSymbolGeometryObjectsWithStyleIds(geometryOptions, element, validStyleIds); + if (instanceLines == null || instanceLines.Length == 0 || symbolLines == null || symbolLines.Length == 0) return null; + XYZ projectedOrigin = GeometryUtils.ProjectPointOntoPlane(plane, GetOriginOfElement(element)); + int id = -1; + int endIndex = -1; + foreach (Line line in instanceLines) + { + for (int i = 0; i < 2; i++) + { + XYZ projectedEndPoint = GeometryUtils.ProjectPointOntoPlane(plane, line.GetEndPoint(i)); + if (projectedEndPoint.IsAlmostEqualTo(projectedOrigin)) + { + id = line.Id; + endIndex = i; + break; + } + } + if (id != -1) break; + } + if (id == -1 || endIndex == -1) return null; + return symbolLines.Where(line => line.Id.Equals(id)).FirstOrDefault()?.GetEndPointReference(endIndex); + } /// /// Retrieves the Reference for unused connector of the pipe. @@ -423,9 +433,10 @@ public static Reference GetPipeEndReference(View activeView, Pipe pipe) public static Reference GetMechanicalEquipmentEndReference(Plane plane, FamilyInstance mechanicalEquipment, FamilyInstance connected) { - Connector connector = ConnectionUtils.TryGetOneSidedConnection(mechanicalEquipment, connected); - if (connector == null) return null; - return GeometryUtils.GetPseudoReferenceOfConnector(GeometryUtils.GetGeometryOptions(), plane, connector); + return null; + //Connector connector = ConnectionUtils.TryGetOneSidedConnection(mechanicalEquipment, connected); + //if (connector == null) return null; + //return GeometryUtils.GetPseudoReferenceOfConnector(GeometryUtils.GetGeometryOptions(), plane, connector); } } diff --git a/CarsonsAddins/Shared/Utils/GeometryUtils.cs b/CarsonsAddins/Shared/Utils/GeometryUtils.cs index 85065f8..ab96df1 100644 --- a/CarsonsAddins/Shared/Utils/GeometryUtils.cs +++ b/CarsonsAddins/Shared/Utils/GeometryUtils.cs @@ -3,8 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; +using static CarsonsAddins.Utils.GeometryUtils; namespace CarsonsAddins.Utils { @@ -129,20 +128,82 @@ public static (PlanarFace, PlanarFace) GetPlanarFaceFromConnector(Options geomet } return (null, null); } - - public static Reference GetPseudoReferenceOfConnector(Options geometryOptions, Plane plane, Connector connector) + public static Reference GetPseudoReferenceOfConnector(ElementId[] validElementIds, Options geometryOptions, Plane plane, Connector connector) + { + return GetExposedPseudoReferenceOfConnectorByFaces(geometryOptions, plane, connector) ?? + GetExposedPseudoReferenceOfConnectorByLines(validElementIds, geometryOptions, plane, connector) ?? + GetPseudoReferenceOfConnectorByFace(geometryOptions, plane, connector) ?? + GetPseudoReferenceOfConnector(validElementIds, geometryOptions, plane, connector); + } + public static Reference GetPseudoReferenceOfConnectorByFace(Options geometryOptions, Plane plane, Connector connector) { if (connector == null) return null; XYZ projectedOrigin = ProjectPointOntoPlane(plane, connector.Origin); if (projectedOrigin == null) return null; PlanarFace[] instancePlanarFaces = GetGeometryObjectFromInstanceGeometry(geometryOptions, connector.Owner); Lookup symbolPlanarFacesLookup = GetGeometryObjectFromSymbolGeometry(geometryOptions, connector.Owner).ToLookup(planarFace => planarFace.Id) as Lookup; - PlanarFace instanceConnectorFace = instancePlanarFaces.Where(planarFace => ProjectPointOntoPlane(plane, planarFace.Origin).IsAlmostEqualTo(projectedOrigin, 0.000001)).FirstOrDefault(); + PlanarFace instanceConnectorFace = instancePlanarFaces.Where(planarFace => projectedOrigin.IsAlmostEqualTo(ProjectPointOntoPlane(plane, planarFace.Origin), 0.000001)).FirstOrDefault(); if (instanceConnectorFace == default(PlanarFace)) return null; PlanarFace symbolFace = symbolPlanarFacesLookup[instanceConnectorFace.Id].FirstOrDefault(); Reference referenceConnectorFace = symbolFace.Reference; return referenceConnectorFace; } + public static Reference GetPseudoReferenceOfConnectorByLines(ElementId[] validElementIds, Options geometryOptions, Plane plane, Connector connector) + { + if (connector == null || validElementIds == null || validElementIds.Length == 0) return null; + XYZ projectedOrigin = ProjectPointOntoPlane(plane, connector.Origin); + if (projectedOrigin == null) return null; + Line[] instanceLines = GetGeometryObjectFromInstanceGeometry(geometryOptions, connector.Owner).Where(line => validElementIds.Contains(line.GraphicsStyleId)).ToArray(); + Lookup referenceLookup = GetGeometryObjectFromSymbolGeometry(geometryOptions, connector.Owner).ToLookup(line => line.Id, line => GetEndPointReferences(line)) as Lookup; + foreach (Line line in instanceLines) + { + for (int i = 0 ; i < 2; i++) + { + XYZ endPoint = line.GetEndPoint(i); + XYZ projectedEndPoint = ProjectPointOntoPlane(plane, endPoint); + if (projectedOrigin.IsAlmostEqualTo(projectedEndPoint) && referenceLookup.Contains(line.Id)) return referenceLookup[line.Id].FirstOrDefault()?[i]; + } + + } + return null; + } + + public static Reference GetExposedPseudoReferenceOfConnectorByFaces(Options geometryOptions, Plane plane, Connector connector) + { + if (connector == null) return null; + XYZ projectedOrigin = ProjectPointOntoPlane(plane, connector.Origin); + if (projectedOrigin == null) return null; + PlanarFace[] faces = GetExposedGeometryObjects(geometryOptions, connector.Owner); + foreach (PlanarFace face in faces) + { + XYZ projectedFaceOrigin = ProjectPointOntoPlane(plane, face.Origin); + if (projectedOrigin.IsAlmostEqualTo(projectedFaceOrigin)) return face.Reference; + + } + return null; + } + + public static Reference GetExposedPseudoReferenceOfConnectorByLines(ElementId[] validElementIds, Options geometryOptions, Plane plane, Connector connector) + { + if (connector == null || validElementIds == null || validElementIds.Length == 0) return null; + XYZ projectedOrigin = ProjectPointOntoPlane(plane, connector.Origin); + if (projectedOrigin == null) return null; + Line[] lines = GetExposedGeometryObjects(geometryOptions, connector.Owner).Where(line => validElementIds.Contains(line.GraphicsStyleId)).ToArray(); + foreach (Line line in lines) + { + for (int i = 0; i < 2; i++) + { + XYZ endPoint = line.GetEndPoint(i); + XYZ projectedEndPoint = ProjectPointOntoPlane(plane, endPoint); + if (projectedOrigin.IsAlmostEqualTo(projectedEndPoint)) return line.GetEndPointReference(i); + } + + } + return null; + } + + + public static GeometryObject[] GetGeometryLinesOfBend(View activeView, Element element, ElementId validStyleId) { if (element == null) return null; @@ -288,37 +349,33 @@ public static T[] GetInstanceGeometryObjectsWithStyleIds(Options geometryOpti } return geometryObjects.ToArray(); } - public static XYZWithReference[] StripGeometryObjectsWithReferences(Element element) + public static GeometryObject[] BreakdownGeometryElementIntoDimensionableGeometryObjects(ElementId[] validStyleIds, GeometryElement geometryInstance) { - GeometryElement geometryElement = element.get_Geometry(GetGeometryOptions()); - if (geometryElement == null) return new XYZWithReference[0]; - GeometryInstance geometryInstance = geometryElement.OfType().FirstOrDefault(); - if (geometryInstance == null) return new XYZWithReference[0]; - List geometryObjectWithReferences = new List(); - IdWithXYZ[] idsWithXYZs = IdWithXYZ.BreakdownGeometryObjects(BreakdownSolidsIntoDimensionableGeometryObjects(geometryInstance.GetInstanceGeometry())); - Lookup idsWithReferences = IdWithReference.BreakdownGeometryObjects(BreakdownSolidsIntoDimensionableGeometryObjects(geometryInstance.GetSymbolGeometry())) - .ToLookup(idWithReference => idWithReference.id) as Lookup; + if (geometryInstance == null) return new GeometryObject[0]; + List geometryObjects = new List(); + foreach (GeometryObject geometryObject in geometryInstance) + { + if (geometryObject == null) continue; + else if (geometryObject is Solid solid) geometryObjects.AddRange(solid.Faces.OfType().ToArray()); + else if (geometryObject is Point) geometryObjects.Add(geometryObject); + else if (geometryObject is Curve && (validStyleIds.Contains(geometryObject.GraphicsStyleId) || validStyleIds == null)) geometryObjects.Add(geometryObject); - XYZWithReference[] xyzsWithReferences = idsWithXYZs.Select(xyzWithRef => new XYZWithReference(xyzWithRef.xyz, idsWithReferences[xyzWithRef.id] - .Where(idWithRef => xyzWithRef.secondaryId == idWithRef.secondaryId).FirstOrDefault().reference)).ToArray(); - return xyzsWithReferences; + } + return geometryObjects.ToArray(); } - - public static GeometryObject[] BreakdownSolidsIntoDimensionableGeometryObjects(GeometryElement geometryElement) + public static GeometryObject[] StripExposedGeometryObjects(ElementId[] validStyleIds, GeometryElement geometryElement) { if (geometryElement == null) return new GeometryObject[0]; List geometryObjects = new List(); foreach (GeometryObject geometryObject in geometryElement) { - if (geometryObject == null) continue; + if (geometryObject == null || !geometryObject.IsElementGeometry || geometryObject is GeometryInstance) continue; else if (geometryObject is Solid solid) geometryObjects.AddRange(solid.Faces.OfType().ToArray()); - else if (geometryObject is Point) geometryObjects.Add(geometryObject); - else if (geometryObject is Line) geometryObjects.Add(geometryObject); - + else if (geometryObject is Point point && point.Reference != null) geometryObjects.Add(geometryObject); + else if (geometryObject is Line && (validStyleIds.Contains(geometryObject.GraphicsStyleId) || validStyleIds == null)) geometryObjects.Add(geometryObject); } return geometryObjects.ToArray(); } - public struct XYZWithReference { public XYZ xyz; @@ -328,12 +385,64 @@ public XYZWithReference(XYZ xyz, Reference reference) this.xyz = xyz; this.reference = reference; } + public override string ToString() + { + return xyz.ToString() + " -> " + reference.ToString(); + } + public static XYZWithReference[] StripGeometryObjectsWithReferences(ElementId[] validStyleIds, Options geometryOptions, Element element) + { + + GeometryElement geometryElement = element.get_Geometry(geometryOptions); + if (geometryElement == null) return new XYZWithReference[0]; + List geometryObjectWithReferences = new List(); + geometryObjectWithReferences.AddRange(StripExposedGeometryObjectsWithReferences(validStyleIds, geometryOptions, element)); + GeometryInstance geometryInstance = geometryElement.OfType().FirstOrDefault(); + if (geometryInstance == null) return geometryObjectWithReferences.ToArray(); + IdWithXYZ[] idsWithXYZs = IdWithXYZ.BreakdownGeometryObjects(BreakdownGeometryElementIntoDimensionableGeometryObjects(validStyleIds, geometryInstance.GetInstanceGeometry())); + Lookup<(int, int), IdWithReference> idsWithReferences = IdWithReference.BreakdownGeometryObjects(BreakdownGeometryElementIntoDimensionableGeometryObjects(validStyleIds, geometryInstance.GetSymbolGeometry())) + .ToLookup(idWithReference => (idWithReference.id, idWithReference.secondaryId)) as Lookup<(int, int), IdWithReference>; + + XYZWithReference[] xyzsWithReferences = idsWithXYZs.Select(xyzWithRef => new XYZWithReference(xyzWithRef.xyz, idsWithReferences[(xyzWithRef.id, xyzWithRef.secondaryId)] + .Where(idWithRef => xyzWithRef.secondaryId == idWithRef.secondaryId).FirstOrDefault().reference)).ToArray(); + return xyzsWithReferences; + } + + public static XYZWithReference[] StripExposedGeometryObjectsWithReferences(ElementId[] validStyleIds, Options geometryOptions, Element element) + { + if (element == null) return default; + GeometryObject[] geometryObjects = StripExposedGeometryObjects(validStyleIds, element.get_Geometry(geometryOptions)); + List xyzWithReferences = new List(); + foreach (GeometryObject geometryObject in geometryObjects) + { + if (geometryObject == null) continue; + else if (geometryObject is Solid solid) xyzWithReferences.AddRange(solid.Faces.OfType().SelectMany(face => StripExposedFacesWithReferences(face)).ToArray()); + else if (geometryObject is Point point) xyzWithReferences.Add(new XYZWithReference(point.Coord, point.Reference)); + else if (geometryObject is Curve curve && (validStyleIds.Contains(geometryObject.GraphicsStyleId) || validStyleIds == null)) + { + xyzWithReferences.Add(new XYZWithReference(curve.GetEndPoint(0), curve.GetEndPointReference(0))); + xyzWithReferences.Add(new XYZWithReference(curve.GetEndPoint(1), curve.GetEndPointReference(1))); + } + } + return xyzWithReferences.ToArray(); + } + + public static XYZWithReference[] StripExposedFacesWithReferences(PlanarFace face) + { + Edge[] edges = face.EdgeLoops.OfType().ToArray(); + List xyzWithReferences = new List(); + foreach (Edge edge in edges) + { + if (edge == null) continue; + xyzWithReferences.AddRange(edge.Tessellate().Select(xyz => new XYZWithReference(xyz, face.Reference))); + } + return xyzWithReferences.ToArray(); + } } public struct IdWithXYZ { public int id; - public int secondaryId; //only used for line endpoint indices + public int secondaryId; //only used for line endPoint indices public XYZ xyz; public IdWithXYZ(int id, int secondaryId, XYZ xyz) { @@ -350,11 +459,10 @@ public IdWithXYZ(int id, XYZ xyz) public static IdWithXYZ[] BreakdownGeometryObject(GeometryObject geometryObject) { if (geometryObject == null) return new IdWithXYZ[0]; - if (!geometryObject.IsElementGeometry) return new IdWithXYZ[0]; if (geometryObject is Point point) return new IdWithXYZ[1] { new IdWithXYZ(point.Id, point.Coord) }; - if (geometryObject is Line line) return new IdWithXYZ[2] { - new IdWithXYZ(line.Id, 0, line.GetEndPoint(0)), - new IdWithXYZ(line.Id, 1, line.GetEndPoint(1)) + if (geometryObject is Curve curve) return new IdWithXYZ[2] { + new IdWithXYZ(curve.Id, 0, curve.GetEndPoint(0)), + new IdWithXYZ(curve.Id, 1, curve.GetEndPoint(1)) }; if (geometryObject is PlanarFace planarFace) return new IdWithXYZ[1] { new IdWithXYZ(planarFace.Id, planarFace.Origin) }; return new IdWithXYZ[0]; @@ -368,12 +476,17 @@ public static IdWithXYZ[] BreakdownGeometryObjects(GeometryObject[] geometryObje } return idsWithXYZs.ToArray(); } + public override string ToString() + { + if (secondaryId >= 0) return "( " + id + ", " + secondaryId + " ): " + xyz.ToString(); + return "( " + id + " ): " + xyz.ToString(); + } } public struct IdWithReference { public int id; - public int secondaryId; //only used for line endpoint indices + public int secondaryId; //only used for line endPoint indices public Reference reference; public IdWithReference(int id, int secondaryId, Reference reference) { @@ -392,9 +505,9 @@ public static IdWithReference[] BreakdownGeometryObject(GeometryObject geometryO if (geometryObject == null) return new IdWithReference[0]; if (!geometryObject.IsElementGeometry) return new IdWithReference[0]; if (geometryObject is Point point) return new IdWithReference[1] { new IdWithReference(point.Id, point.Reference) }; - if (geometryObject is Line line) return new IdWithReference[2] { - new IdWithReference(line.Id, 0, line.GetEndPointReference(0)), - new IdWithReference(line.Id, 1, line.GetEndPointReference(1)) + if (geometryObject is Curve curve) return new IdWithReference[2] { + new IdWithReference(curve.Id, 0, curve.GetEndPointReference(0)), + new IdWithReference(curve.Id, 1, curve.GetEndPointReference(1)) }; if (geometryObject is PlanarFace planarFace) return new IdWithReference[1] { new IdWithReference(planarFace.Id, planarFace.Reference) }; return new IdWithReference[0]; @@ -410,6 +523,11 @@ public static IdWithReference[] BreakdownGeometryObjects(GeometryObject[] geomet } return IdsWithReferences.ToArray(); } + public override string ToString() + { + if (secondaryId >= 0) return "( " + id + ", " + secondaryId + " ): " + reference.ToString(); + return "( " + id + " ): " + reference.ToString(); + } } diff --git a/CarsonsAddins/Standalone/DebugGeometryCommand.cs b/CarsonsAddins/Standalone/DebugGeometryCommand.cs new file mode 100644 index 0000000..f53d56c --- /dev/null +++ b/CarsonsAddins/Standalone/DebugGeometryCommand.cs @@ -0,0 +1,98 @@ +using Autodesk.Revit.Attributes; +using Autodesk.Revit.DB; +using Autodesk.Revit.UI; +using CarsonsAddins.Properties; +using CarsonsAddins.Utils; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace CarsonsAddins +{ + [Transaction(TransactionMode.Manual)] + [Regeneration(RegenerationOption.Manual)] + class DebugGeometryCommand : IExternalCommand, ISettingsComponent + { + public const string FolderName = ""; + public const bool IsWIP = false; + public PushButtonData RegisterButton(Assembly assembly) + { + PushButtonData pushButtonData = new PushButtonData("Debug Geometry", "Debug Geometry", assembly.Location, "CarsonsAddins.DebugGeometryCommand") + { + AvailabilityClassName = typeof(Setup.Availablity.Availability_ProjectDocumentAndActiveView).FullName, + ToolTip = "Debugs Element Geometry References." + }; + return pushButtonData; + } + public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) + { + UIDocument uidoc = commandData.Application.ActiveUIDocument; + Reference selectionReference = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element); + if (selectionReference == null) return Result.Cancelled; + Transaction transaction = new Transaction(uidoc.Document); + transaction.Start("Debug Element Geometry"); + try + { + Element element = uidoc.Document.GetElement(selectionReference); + elements.Insert(element); + ElementId[] validStyleIds = GetStyleIds(uidoc.Document); + GeometryUtils.XYZWithReference[] exposedWithView = GeometryUtils.XYZWithReference.StripGeometryObjectsWithReferences(validStyleIds, GeometryUtils.GetGeometryOptions(uidoc.Document.ActiveView), element); + string exposedWithViewString = string.Join("\n", exposedWithView.Select(xyzWR => xyzWR.xyz.ToString() + " -> " + xyzWR.reference.ConvertToStableRepresentation(uidoc.Document)).ToArray()); + TaskDialog.Show("Geometry with View", exposedWithViewString); + GeometryUtils.XYZWithReference[] exposed = GeometryUtils.XYZWithReference.StripGeometryObjectsWithReferences(validStyleIds, GeometryUtils.GetGeometryOptions(), element); + string exposedString = string.Join("\n", exposed.Select(xyzWR => xyzWR.xyz.ToString() + " -> " + xyzWR.reference.ConvertToStableRepresentation(uidoc.Document)).ToArray()); + TaskDialog.Show("Geometry", exposedString); + Connector[] connectors = ConnectionUtils.GetConnectors(element); + Plane plane = uidoc.Document.ActiveView.SketchPlane.GetPlane(); + string[] referenceStrings = connectors.Select(connector => FindReference(exposedWithView, plane, connector.Origin) ?? FindReference(exposed, plane, connector.Origin)).Select(reference => reference?.ConvertToStableRepresentation(uidoc.Document) ?? "NULL").ToArray(); + string output = string.Join("\n", referenceStrings); + output += "\n Center: " + (FindReference(exposedWithView, plane, GeometryUtils.GetOrigin(element.Location)) ?? FindReference(exposed, plane, GeometryUtils.GetOrigin(element.Location)))?.ConvertToStableRepresentation(uidoc.Document) ?? "NULL"; + TaskDialog.Show("Guess Connections", output); + transaction.Commit(); + return Result.Succeeded; + } + catch (Exception ex) + { + message = ex.Message; + return Result.Failed; + } + } + private Reference FindReference(GeometryUtils.XYZWithReference[] xyzReferences, Plane plane, XYZ xyz) + { + Reference reference = xyzReferences.Where(xyzReference => xyz.IsAlmostEqualTo(xyzReference.xyz)).FirstOrDefault().reference; + if (reference != null) return reference; + XYZ projectedXYZ = GeometryUtils.ProjectPointOntoPlane(plane, xyz); + Reference projectedReference = xyzReferences.Where(xyzReference => xyz.IsAlmostEqualTo(GeometryUtils.ProjectPointOntoPlane(plane, xyzReference.xyz))).FirstOrDefault().reference; + return projectedReference; + } + private ElementId[] GetStyleIds(Document doc) //requires that Load Dimension Types has been called first + { + List validStyleIds = new List(); + + if (string.IsNullOrWhiteSpace(MySettings.Default.DimensionStyles_Preferences)) return new ElementId[0]; + BuiltInCategory[] pipingCategories = new BuiltInCategory[] { BuiltInCategory.OST_PipeCurves, BuiltInCategory.OST_PipeFitting, BuiltInCategory.OST_PipeAccessory, BuiltInCategory.OST_MechanicalEquipment, BuiltInCategory.OST_PipeCurvesCenterLine, BuiltInCategory.OST_PipeFittingCenterLine, BuiltInCategory.OST_CenterLines, BuiltInCategory.OST_ReferenceLines }; + GraphicsStyle[] graphicStyles = new FilteredElementCollector(doc).OfClass(typeof(GraphicsStyle)).Cast().Where(gs => pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Id.IntegerValue) || ((gs.GraphicsStyleCategory.Parent != null) && pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Parent.Id.IntegerValue))).ToArray(); + try + { + DimensionStyleNames dimensionStyleNames = JsonConvert.DeserializeObject(MySettings.Default.DimensionStyles_Preferences); + if (dimensionStyleNames.centerlineStyleNames == null) return new ElementId[0]; + foreach (GraphicsStyle graphicsStyle in graphicStyles) + { + if (dimensionStyleNames.centerlineStyleNames.Contains(graphicsStyle.Name)) validStyleIds.Add(graphicsStyle.Id); + } + + } + catch (Exception ex) + { + TaskDialog.Show("Error Loading Dimension Styles from DB", ex.Message); + } + return validStyleIds.ToArray(); + + } + + } +} From 0bcbd0b7373469e4fcf8f7069e877aa6c33b3349 Mon Sep 17 00:00:00 2001 From: Carson Date: Tue, 21 May 2024 16:58:19 -0500 Subject: [PATCH 02/11] Fixed a lot of referencing issues --- CarsonsAddins/Pipeline/Models/DimensionPipeline.cs | 2 +- .../Models/PipingElementReferenceOrderedList.cs | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs b/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs index d44bc01..10c6312 100644 --- a/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs +++ b/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs @@ -96,7 +96,6 @@ public static void CreateDimensions(Document doc, Element[] elements, Element se ReferenceArray primaryReferenceArray = new ReferenceArray(); //ReferenceArray secondaryReferenceArray = new ReferenceArray(); PipingElementReferenceOrderedList referenceSets = new PipingElementReferenceOrderedList(validStyleIds, doc.ActiveView, elements); - referenceSets.SubtractFlanges(); ReferenceArray secondaryReferenceArray = new ReferenceArray(); bool matchesPrimary = true; for (int i = 0; i < referenceSets.nodes.Length; i++) @@ -121,6 +120,7 @@ public static void CreateDimensions(Document doc, Element[] elements, Element se } private static void AddReferences(ref ReferenceArray primaryReferenceArray, ref ReferenceArray secondaryReferenceArray, PipingElementReferenceOrderedList.ReferenceNode node, bool secondaryDimension) { + if (node.isNonConnector || node.mode != PipingElementReferenceOrderedList.FlangeDimensionMode.None) return; if (node.isEdge) { if (node.isLinear) diff --git a/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs b/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs index 18ba14d..ee85353 100644 --- a/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs +++ b/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs @@ -40,7 +40,7 @@ private void PopulateNodes(ElementId[] validStyleIds, View activeView) { Connector connector = ConnectionUtils.GetParallelConnector(ConnectionUtils.GetConnectors(orderedElements[nodes.Length - 1]).Where(con => ConnectionUtils.IsConnectedTo(orderedElements[nodes.Length - 2], con)).FirstOrDefault()); //nodes[nodes.Length - 1].lastReference = GetPseudoConnectorReference(validStyleIds, activeView, plane, connector); - nodes[0].lastConnector = connector; + nodes[nodes.Length - 1].lastConnector = connector; } } @@ -53,6 +53,7 @@ private void PopulateNodes(ElementId[] validStyleIds, View activeView) PopulateNodeReferences(validStyleIds, activeView); FillAdjacentNodeReferences(); SetAdjacentNonLinear(); + SubtractFlanges(); } private void CreateReferenceNode(int index) { @@ -117,7 +118,7 @@ private void PopulateNodeReferences(ElementId[] validStyleIds, View activeView) if (!nodes[i].isLinear) { XYZ origin = nodes[i].origin; - nodes[i].firstReference = FindReference(nodeReferencesWithView[i], plane, origin) ?? FindReference(nodeReferencesWithoutView[i], plane, origin); + nodes[i].centerReference = FindReference(nodeReferencesWithView[i], plane, origin) ?? FindReference(nodeReferencesWithoutView[i], plane, origin); } if (nodes[i].lastConnector != null) { @@ -133,9 +134,9 @@ private void FillAdjacentNodeReferences() { if ((nodes[i].firstReference == null) != (nodes[i + 1].lastReference == null)) { - Reference reference = nodes[i].firstReference ?? nodes[i].lastReference; - nodes[i].firstReference = reference; - nodes[i + 1].lastReference = reference; + Reference reference = nodes[i].lastReference ?? nodes[i + 1].firstReference; + nodes[i].lastReference = reference; + nodes[i + 1].firstReference = reference; } } From 85043143ec9c4e49de77913bf6ab9fd9d5b2c7e3 Mon Sep 17 00:00:00 2001 From: Carson Date: Wed, 22 May 2024 09:44:08 -0500 Subject: [PATCH 03/11] Fixed the reimplementation of dimensioning pipeline tool --- .../Pipeline/Models/DimensionPipeline.cs | 35 +++++---- .../PipingElementReferenceOrderedList.cs | 73 ++++++++++++++----- .../Updaters/ParameterManagerUpdater.cs | 16 +--- 3 files changed, 76 insertions(+), 48 deletions(-) diff --git a/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs b/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs index 10c6312..5958030 100644 --- a/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs +++ b/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs @@ -100,15 +100,15 @@ public static void CreateDimensions(Document doc, Element[] elements, Element se bool matchesPrimary = true; for (int i = 0; i < referenceSets.nodes.Length; i++) { - if (referenceSets.nodes[i].isNonConnector) continue; PipingElementReferenceOrderedList.ReferenceNode node = referenceSets.nodes[i]; + if (node.ignore) continue; - AddReferences(ref primaryReferenceArray, ref secondaryReferenceArray, node, secondaryDimension); - if (node.firstReference != null || node.lastReference != null) matchesPrimary = false; - bool splitDimension = (i == referenceSets.nodes.Length - 1) || (node.mode == PipingElementReferenceOrderedList.FlangeDimensionMode.Ignore || (node.mode == PipingElementReferenceOrderedList.FlangeDimensionMode.Partial && (node.isEdge || node.adjacentNonLinear))); + matchesPrimary = AddReferences(ref primaryReferenceArray, ref secondaryReferenceArray, node, secondaryDimension); + bool splitDimension = node.isEnd || (node.mode == PipingElementReferenceOrderedList.FlangeDimensionMode.Exact || (node.mode == PipingElementReferenceOrderedList.FlangeDimensionMode.Partial && (node.isEdge || node.adjacentNonLinear))); if (splitDimension) { + BuiltInCategory builtInCategory = (node.referenceCount == secondaryReferenceArray.Size) ? node.builtInCategory : BuiltInCategory.OST_PipeCurves; if (!matchesPrimary && secondaryReferenceArray.Size > 1) doc.Create.NewDimension(activeView, secondaryDimensionLine, secondaryReferenceArray, dimensionStyles.GetSecondaryDimensionType(builtInCategory) ?? defaultDimensionType); secondaryReferenceArray.Clear(); @@ -118,37 +118,42 @@ public static void CreateDimensions(Document doc, Element[] elements, Element se } doc.Create.NewDimension(activeView, primaryDimensionLine, primaryReferenceArray, dimensionStyles.primaryDimensionType ?? defaultDimensionType); } - private static void AddReferences(ref ReferenceArray primaryReferenceArray, ref ReferenceArray secondaryReferenceArray, PipingElementReferenceOrderedList.ReferenceNode node, bool secondaryDimension) + private static bool AddReferences(ref ReferenceArray primaryReferenceArray, ref ReferenceArray secondaryReferenceArray, PipingElementReferenceOrderedList.ReferenceNode node, bool secondaryDimension) { - if (node.isNonConnector || node.mode != PipingElementReferenceOrderedList.FlangeDimensionMode.None) return; + if (node.isFlange) return false; + int addedFirst = 0; + int addedCenter = 0; + int addedLast = 0; if (node.isEdge) { if (node.isLinear) { - if (node.isEnd) AddReferenceIfNotNull(ref primaryReferenceArray, node.lastReference); - else if (node.isStart) AddReferenceIfNotNull(ref primaryReferenceArray, node.firstReference); + if (node.isEnd) AddReferenceIfNotNull(ref primaryReferenceArray, node.lastReference, ref addedLast); + else if (node.isStart) AddReferenceIfNotNull(ref primaryReferenceArray, node.firstReference, ref addedFirst); } else if (node.centerReference == null) { - if (node.isStart) AddReferenceIfNotNull(ref primaryReferenceArray, node.lastReference); - else if (node.isEnd) AddReferenceIfNotNull(ref primaryReferenceArray, node.firstReference); + if (node.isStart) AddReferenceIfNotNull(ref primaryReferenceArray, node.lastReference, ref addedLast); + else if (node.isEnd) AddReferenceIfNotNull(ref primaryReferenceArray, node.firstReference, ref addedFirst); } } - AddReferenceIfNotNull(ref primaryReferenceArray, node.centerReference); + AddReferenceIfNotNull(ref primaryReferenceArray, node.centerReference, ref addedCenter); if (secondaryDimension) { - AddReferenceIfNotNull(ref secondaryReferenceArray, node.firstReference); - AddReferenceIfNotNull(ref secondaryReferenceArray, node.centerReference); - AddReferenceIfNotNull(ref secondaryReferenceArray, node.lastReference); + AddReferenceIfNotNull(ref secondaryReferenceArray, node.firstReference, ref addedFirst); + AddReferenceIfNotNull(ref secondaryReferenceArray, node.centerReference, ref addedCenter); + AddReferenceIfNotNull(ref secondaryReferenceArray, node.lastReference, ref addedLast); } + return !(addedFirst == 1 || addedLast == 1); } - private static void AddReferenceIfNotNull(ref ReferenceArray referenceArray, Reference reference) + private static void AddReferenceIfNotNull(ref ReferenceArray referenceArray, Reference reference, ref int counter) { if (referenceArray == null || reference == null) return; referenceArray.Append(reference); + counter ++; } } diff --git a/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs b/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs index ee85353..38727fa 100644 --- a/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs +++ b/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs @@ -10,7 +10,7 @@ namespace CarsonsAddins.Pipeline.Models { class PipingElementReferenceOrderedList { - public enum FlangeDimensionMode { None, Ignore, Partial, Negate } + public enum FlangeDimensionMode { None, Exact, Partial, Negate } public Element[] orderedElements; public ReferenceNode[] nodes; @@ -53,6 +53,7 @@ private void PopulateNodes(ElementId[] validStyleIds, View activeView) PopulateNodeReferences(validStyleIds, activeView); FillAdjacentNodeReferences(); SetAdjacentNonLinear(); + MoveEdges(); SubtractFlanges(); } private void CreateReferenceNode(int index) @@ -73,6 +74,7 @@ private void CreateReferenceNode(int index) bool isLinear = ConnectionUtils.IsLinearElement(element); bool isStart = index == 0; bool isEnd = index == orderedElements.Length - 1; + bool isNonConnector = element.Name == "Non-Connector"; //bool isFlange = ElementCheckUtils.IsPipeFlange(element); nodes[index] = new ReferenceNode { @@ -83,11 +85,35 @@ private void CreateReferenceNode(int index) isEnd = isEnd, isLinear = isLinear, adjacentNonLinear = false, + isNonConnector = isNonConnector, + ignore = isNonConnector, //centerReference = isFlange ? null : (!isLinear) ? DimensioningUtils.GetProjectedCenterReference(GeometryUtils.GetGeometryOptions(), validStyleIds, plane, element) ?? DimensioningUtils.GetProjectedCenterReference(GeometryUtils.GetGeometryOptions(activeView), validStyleIds, plane, element) : null, //firstReference = currentFirstReference, firstConnector = firstConnector - }; + }; } + private void MoveEdges() + { + if (nodes[0].isNonConnector || nodes[0].isFlange) + { + int nextIndex = GetAdjacentElementIndex(1, 1, false, false); + if (nextIndex > 0) + { + for (int i = 0; i < nextIndex; i++) nodes[i].ignore = true; + nodes[nextIndex].isStart = true; + } + } + if (nodes[nodes.Length - 1].isNonConnector || nodes[nodes.Length - 1].isFlange) + { + int previousIndex = GetAdjacentElementIndex(nodes.Length - 2, -1, false, false); + if (previousIndex >= 0) + { + for (int i = nodes.Length - 1; i > previousIndex; i--) nodes[i].ignore = true; + nodes[previousIndex].isEnd = true; + } + } + } + private Reference GetPseudoConnectorReference(ElementId[] validStyleIds, View activeView, Plane plane, Connector connector) { return GeometryUtils.GetPseudoReferenceOfConnector(validStyleIds, GeometryUtils.GetGeometryOptions(activeView), plane, connector) ?? @@ -162,7 +188,7 @@ public void SubtractFlanges() { case (FlangeDimensionMode.None): break; - case (FlangeDimensionMode.Ignore): + case (FlangeDimensionMode.Exact): IgnoreFlange(i); break; case (FlangeDimensionMode.Partial): @@ -180,19 +206,19 @@ private FlangeDimensionMode GetMode(Element element) if (!ElementCheckUtils.IsPipeFlange(element)) return FlangeDimensionMode.None; string familyName = (element as FamilyInstance).Symbol.FamilyName; - if (familyName.Contains("FLG")) return FlangeDimensionMode.Ignore; - if (familyName.Contains("MJ") || familyName.Contains("PO")) return FlangeDimensionMode.Negate; + if (familyName.Contains("FLG")) return FlangeDimensionMode.Exact; + else if (familyName.Contains("MJ") || familyName.Contains("PO")) return FlangeDimensionMode.Negate; return FlangeDimensionMode.Partial; } private void IgnoreFlange(int index) { - if (index < 0 && index >= nodes.Length) return; + if (index < 0 || index >= nodes.Length) return; nodes[index].firstReference = null; nodes[index].lastReference = null; } private void NegateFlange(int index) { - if (index < 0 && index >= nodes.Length) return; + if (index < 0 || index >= nodes.Length) return; nodes[index].firstReference = null; nodes[index].lastReference = null; RemoveLastReference(index - 1); @@ -200,32 +226,37 @@ private void NegateFlange(int index) } private void PartialFlange(int index) { - if (index < 0 && index >= nodes.Length) return; - if (nodes[index].isStart || nodes[index].isEnd || NextToNonLinear(index)) IgnoreFlange(index); + if (index < 0 || index >= nodes.Length) return; + else if (nodes[index].isStart || nodes[index].isEnd || NextToNonLinear(index)) IgnoreFlange(index); else NegateFlange(index); } - private bool NextToNonLinear(int index) => IsPreviousNonLinear(index) || IsNextNonLinear(index); - private bool IsNextNonLinear(int index) + private int GetAdjacentElementIndex(int index, int direction, bool allowNonConnectors, bool allowFlanges) { - if (index < 0 || index >= nodes.Length - 1) return false; - if (nodes[index + 1].isNonConnector) return IsNextNonLinear(index + 1); - return !nodes[index + 1].isLinear; + if (direction == 0 || index < 0 || index >= nodes.Length) return -1; + bool passesFlangeFilter = (allowFlanges || (!allowFlanges && !nodes[index].isFlange)); + bool passesNonConnectorFilter = (allowNonConnectors || (!allowNonConnectors && !nodes[index].isNonConnector)); + if (passesFlangeFilter && passesNonConnectorFilter) return index; + return GetAdjacentElementIndex(index + direction, direction, allowNonConnectors, allowFlanges); } - private bool IsPreviousNonLinear(int index) + private bool NextToNonLinear(int index) { - if (index < 1 || index > nodes.Length - 1) return false; - if (nodes[index - 1].isNonConnector) return IsNextNonLinear(index - 1); - return !nodes[index - 1].isLinear; + if (index < 0 || index >= nodes.Length) return false; + int previousIndex = GetAdjacentElementIndex(index - 1, -1, false, true); + int nextIndex = GetAdjacentElementIndex(index + 1, 1, false, true); + if (previousIndex >= 0 && !nodes[previousIndex].isLinear) return true; + if (nextIndex >= 0 && !nodes[nextIndex].isLinear) return true; + return false; } + private void RemoveLastReference(int index) { - if (index < 0 && index >= nodes.Length) return; + if (index < 0 || index >= nodes.Length) return; if (nodes[index].isNonConnector) RemoveLastReference(index - 1); nodes[index].lastReference = null; } private void RemoveFirstReference(int index) { - if (index < 0 && index >= nodes.Length) return; + if (index < 0 || index >= nodes.Length) return; if (nodes[index].isNonConnector) RemoveFirstReference(index + 1); nodes[index].firstReference = null; } @@ -234,6 +265,7 @@ public struct ReferenceNode //public ElementCheckUtils.PipingCategory pipingCategory; public BuiltInCategory builtInCategory; public FlangeDimensionMode mode; + public bool isFlange => mode != FlangeDimensionMode.None; public XYZ origin; public bool isStart; public bool isEnd; @@ -242,6 +274,7 @@ public struct ReferenceNode public bool isLinear; public bool adjacentNonLinear; public bool isNonConnector; + public bool ignore; public Reference firstReference; public Reference centerReference; public Reference lastReference; diff --git a/CarsonsAddins/Shared/Updaters/ParameterManagerUpdater.cs b/CarsonsAddins/Shared/Updaters/ParameterManagerUpdater.cs index 6c644b4..34229af 100644 --- a/CarsonsAddins/Shared/Updaters/ParameterManagerUpdater.cs +++ b/CarsonsAddins/Shared/Updaters/ParameterManagerUpdater.cs @@ -58,22 +58,12 @@ private void RegisterTriggers() } public void Execute(UpdaterData data) { - if (parameterManager == null) return; + if (parameterManager == null || elementIds.Count == 0) return; ElementId[] deletedElementIds = data.GetModifiedElementIds().Where(elementId => elementIds.Contains(elementId)).ToArray(); ElementId[] modifiedElementIds = data.GetModifiedElementIds().Where(elementId => elementIds.Contains(elementId)).ToArray(); - RemoveStaleReferences(deletedElementIds); - RefreshParameters(modifiedElementIds); - } - - private void RemoveStaleReferences(ElementId[] deletedElementIds) - { - ElementId[] filteredDeletedElementIds = deletedElementIds.Where(id => elementIds.Contains(id)).ToArray(); - parameterManager.RemoveElements(filteredDeletedElementIds); - } - private void RefreshParameters(ElementId[] elementIds) - { - parameterManager.RefreshElements(elementIds); + if (deletedElementIds.Length > 0) parameterManager.RemoveElements(deletedElementIds); + if (modifiedElementIds.Length > 0) parameterManager.RefreshElements(modifiedElementIds); } public string GetAdditionalInformation() From bb5a32d74366f82d03c248afa61f5f488f1207b9 Mon Sep 17 00:00:00 2001 From: Carson Date: Wed, 22 May 2024 17:22:50 -0500 Subject: [PATCH 04/11] Implemented Dimensioning pipe flange modes --- CarsonsAddins/CarsonsAddins.csproj | 8 + CarsonsAddins/CarsonsAddinsApplication.cs | 17 +- .../SimpleFilterDockablePane.xaml.cs | 2 +- .../DimensionSettingsWindow.xaml.cs | 145 +++++++++++------- .../DimensionTypeSelectorControl.xaml.cs | 18 ++- .../ViewModels/FlangeModeSelectorViewModel.cs | 76 +++++++++ .../GraphicsStyleListControl.xaml.cs | 1 + .../Views/DimensionSettingsWindow.xaml | 1 + .../Views/FlangeModeSelectorControl.xaml | 58 +++++++ .../Views/FlangeModeSelectorControl.xaml.cs | 83 ++++++++++ .../Pipeline/Models/DimensionPipeline.cs | 2 +- .../PipingElementReferenceOrderedList.cs | 21 +-- .../Setup/GenericComponentCommands.cs | 13 ++ CarsonsAddins/Shared/Utils/ConnectionUtils.cs | 2 +- .../Shared/Utils/DimensioningUtils.cs | 2 + .../Standalone/DebugGeometryCommand.cs | 2 +- 16 files changed, 371 insertions(+), 80 deletions(-) create mode 100644 CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/FlangeModeSelectorViewModel.cs create mode 100644 CarsonsAddins/Dimensioning/DimensionSettings/Views/FlangeModeSelectorControl.xaml create mode 100644 CarsonsAddins/Dimensioning/DimensionSettings/Views/FlangeModeSelectorControl.xaml.cs diff --git a/CarsonsAddins/CarsonsAddins.csproj b/CarsonsAddins/CarsonsAddins.csproj index dafecb6..78c9813 100644 --- a/CarsonsAddins/CarsonsAddins.csproj +++ b/CarsonsAddins/CarsonsAddins.csproj @@ -109,8 +109,12 @@ + + + FlangeModeSelectorControl.xaml + @@ -205,6 +209,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/CarsonsAddins/CarsonsAddinsApplication.cs b/CarsonsAddins/CarsonsAddinsApplication.cs index cfd33f0..36a0ba8 100644 --- a/CarsonsAddins/CarsonsAddinsApplication.cs +++ b/CarsonsAddins/CarsonsAddinsApplication.cs @@ -33,6 +33,7 @@ using Newtonsoft.Json; using System.Windows.Forms; using System.Runtime.InteropServices; +using CarsonsAddins.GenericCommands; namespace CarsonsAddins { @@ -43,8 +44,6 @@ public partial class CarsonsAddinsApplication : IExternalApplication public static string tmplog = string.Empty; private List componentStates = new List(); private readonly List settingsComponents = new List(); - public static CarsonsAddinsApplication instance { get; private set; } - public CarsonsAddinsApplication() { instance = this; } public Result OnStartup(UIControlledApplication app) { ApplicationIds.Init(); @@ -88,6 +87,7 @@ public Result OnStartup(UIControlledApplication app) pulldownButtonDictionary.Add("Misc", miscComponentsPulldownButton); RegisterComponentPushButtons(assembly, panel, pulldownButtonDictionary); app.ControlledApplication.ApplicationInitialized += RegisterDockablePanes; + app.ControlledApplication.ApplicationInitialized += DummyLaunchDimensionSettingsWindow; return Result.Succeeded; } @@ -124,10 +124,17 @@ private void RegisterComponentPushButtons(Assembly assembly, RibbonPanel panel, } } } - /// /// Registers all of the classes with a SettingsComponent that contain a DockablePane via reflection. /// + private void DummyLaunchDimensionSettingsWindow(object sender, ApplicationInitializedEventArgs e) + { + UIApplication uiapp = new UIApplication(sender as Autodesk.Revit.ApplicationServices.Application); + new ShowWindow().InitWindow(uiapp); + } + /// + /// Registers all of the classes with a SettingsComponent that contain a DockablePane via reflection. + /// private void RegisterDockablePanes(object sender, ApplicationInitializedEventArgs e) { UIApplication uiapp = new UIApplication(sender as Autodesk.Revit.ApplicationServices.Application); @@ -136,9 +143,9 @@ private void RegisterDockablePanes(object sender, ApplicationInitializedEventArg if (!(component is IDockablePaneProvider)) continue; if (component is ISettingsUIComponent uiComponent) { - Type registerCommandType = typeof( GenericCommands.RegisterDockablePane<>).MakeGenericType(uiComponent.GetType()); + Type registerCommandType = typeof( RegisterDockablePane<>).MakeGenericType(uiComponent.GetType()); var registerCommand = Activator.CreateInstance(registerCommandType); - if (registerCommand is GenericCommands.IExecuteWithUIApplication command) command.Execute(uiapp); + if (registerCommand is IExecuteWithUIApplication command) command.Execute(uiapp); } } } diff --git a/CarsonsAddins/Deprecated/SimpleFilter/ViewModels/SimpleFilterDockablePane.xaml.cs b/CarsonsAddins/Deprecated/SimpleFilter/ViewModels/SimpleFilterDockablePane.xaml.cs index a046b92..8604a71 100644 --- a/CarsonsAddins/Deprecated/SimpleFilter/ViewModels/SimpleFilterDockablePane.xaml.cs +++ b/CarsonsAddins/Deprecated/SimpleFilter/ViewModels/SimpleFilterDockablePane.xaml.cs @@ -136,7 +136,7 @@ private void CheckNoneButtonPress(object sender, RoutedEventArgs e) SetAllCategoriesToSelectionState(false); foreach (CategorySelectionItem item in categorySelectionItems) b += item.ToString() + '\n'; - TaskDialog.Show("Comparing Check None Action", "BEFORE: \n " + a + "\n\nAFTER: \n" + b); + TaskDialog.Show("Comparing Check Default Action", "BEFORE: \n " + a + "\n\nAFTER: \n" + b); } private void ApplySelectionButtonPress(object sender, RoutedEventArgs e) diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs index b8b1974..6cbc8bd 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs +++ b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs @@ -1,5 +1,6 @@ using Autodesk.Revit.DB; using Autodesk.Revit.UI; +using CarsonsAddins; using CarsonsAddins.Properties; using CarsonsAddins.Utils; using Newtonsoft.Json; @@ -37,27 +38,15 @@ public partial class DimensionSettingsWindow : Window, ISettingsUIComponent, INo public event PropertyChangedEventHandler PropertyChanged; private DimensionType[] dimensionTypes; private GraphicsStyle[] graphicStyles; + private Family[] allFlangeFamilySymbols; public static DimensionStyles DimensionStylesSettings; - - + private UIDocument uidoc; public DimensionSettingsWindow() { InitializeComponent(); + IsVisibleChanged += DimensionSettingsWindow_IsVisibleChanged; } - - public void Init(UIDocument uidoc) - { - DimensionStylesSettings = new DimensionStyles(); - BuiltInCategory[] pipingCategories = new BuiltInCategory[] {BuiltInCategory.OST_PipeCurves, BuiltInCategory.OST_PipeFitting, BuiltInCategory.OST_PipeAccessory, BuiltInCategory.OST_MechanicalEquipment, BuiltInCategory.OST_PipeCurvesCenterLine, BuiltInCategory.OST_PipeFittingCenterLine, BuiltInCategory.OST_CenterLines, BuiltInCategory.OST_ReferenceLines}; - dimensionTypes = new FilteredElementCollector(uidoc.Document).WhereElementIsElementType().OfClass(typeof(DimensionType)).ToElements().Cast().Where(dt => DimensionStyleType.Linear.Equals(dt.StyleType)).ToArray(); - graphicStyles = new FilteredElementCollector(uidoc.Document).OfClass(typeof(GraphicsStyle)).Cast().Where(gs => pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Id.IntegerValue) || ((gs.GraphicsStyleCategory.Parent != null) && pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Parent.Id.IntegerValue))).ToArray(); - LoadFromDB(); - DimensionTypeSelector.Init(dimensionTypes, ref DimensionStylesSettings); - GraphicsStyleList.Init(graphicStyles, ref DimensionStylesSettings.centerlineStyles); - //DimensionPreviewControl.AddPreviewControlWithCustomView(uidoc.Document); - } - public PushButtonData RegisterButton(Assembly assembly) { return new PushButtonData("Dimension Pipeline Settings", "Dimension Pipeline Settings", assembly.Location, typeof(GenericCommands.ShowWindow).FullName) @@ -66,35 +55,74 @@ public PushButtonData RegisterButton(Assembly assembly) ToolTip = "Settings Window for the Dimension Pipeline Command" }; } - private void LoadFromDB() //requires that Load Dimension Types has been called first + + private void DimensionSettingsWindow_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) + { + if (Visibility == System.Windows.Visibility.Hidden) SaveToDB(); + //else if (Visibility == System.Windows.Visibility.Visible) Refresh(); + } + + public void Init(UIDocument uidoc) + { + this.uidoc = uidoc; + Refresh(); + } + private void Refresh() + { + if (uidoc == null) return; + DimensionStylesSettings = new DimensionStyles(); + LoadFromRevit(); + LoadFromPreferences(); + InitControls(); + } + public void LoadFromRevit() + { + BuiltInCategory[] pipingCategories = new BuiltInCategory[] { BuiltInCategory.OST_PipeCurves, BuiltInCategory.OST_PipeFitting, BuiltInCategory.OST_PipeAccessory, BuiltInCategory.OST_MechanicalEquipment, BuiltInCategory.OST_PipeCurvesCenterLine, BuiltInCategory.OST_PipeFittingCenterLine, BuiltInCategory.OST_CenterLines, BuiltInCategory.OST_ReferenceLines }; + dimensionTypes = new FilteredElementCollector(uidoc.Document).WhereElementIsElementType().OfClass(typeof(DimensionType)).ToElements().Cast().Where(dt => DimensionStyleType.Linear.Equals(dt.StyleType)).ToArray(); + graphicStyles = new FilteredElementCollector(uidoc.Document).OfClass(typeof(GraphicsStyle)).Cast().Where(gs => pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Id.IntegerValue) || ((gs.GraphicsStyleCategory.Parent != null) && pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Parent.Id.IntegerValue))).ToArray(); + Family[] familes = new FilteredElementCollector(uidoc.Document).OfClass(typeof(Family)).ToElements().Cast().ToArray(); + allFlangeFamilySymbols = new FilteredElementCollector(uidoc.Document).OfClass(typeof(Family)).Cast().Where(family => (BuiltInCategory.OST_PipeFitting == (BuiltInCategory) family.FamilyCategory.Id.IntegerValue) && ElementCheckUtils.FlangePartTypes.Contains((PartType)family.get_Parameter(BuiltInParameter.FAMILY_CONTENT_PART_TYPE).AsInteger())).ToArray(); + } + + + private void LoadFromPreferences() //requires that Load Dimension Types has been called first { DimensionStylesSettings = new DimensionStyles(); if (dimensionTypes == null || dimensionTypes.Length == 0) return; - if (string.IsNullOrWhiteSpace(MySettings.Default.DimensionStyles_Preferences)) return; - + try { - DimensionStyleNames dimensionStyleNames = JsonConvert.DeserializeObject(MySettings.Default.DimensionStyles_Preferences); - - - foreach (DimensionType dimensionType in dimensionTypes) + if (!string.IsNullOrWhiteSpace(MySettings.Default.DimensionStyles_Preferences)) { - if (dimensionType.Name == dimensionStyleNames.primaryDimensionTypeName) DimensionStylesSettings.primaryDimensionType = dimensionType; - if (dimensionType.Name == dimensionStyleNames.secondaryPipeDimensionTypeName) DimensionStylesSettings.secondaryPipeDimensionType = dimensionType; - if (dimensionType.Name == dimensionStyleNames.secondaryAccessoryDimensionTypeName) DimensionStylesSettings.secondaryAccessoryDimensionType = dimensionType; - if (dimensionType.Name == dimensionStyleNames.secondaryFittingDimensionTypeName) DimensionStylesSettings.secondaryFittingDimensionType = dimensionType; - if (dimensionType.Name == dimensionStyleNames.secondaryOtherDimensionTypeName) DimensionStylesSettings.secondaryOtherDimensionType = dimensionType; - if (DimensionStylesSettings.foundAllDimensionTypes) break; - } - if (dimensionStyleNames.centerlineStyleNames != null) - { - - foreach (GraphicsStyle graphicsStyle in graphicStyles) + DimensionSettingsModel dimensionStyleNames = JsonConvert.DeserializeObject(MySettings.Default.DimensionStyles_Preferences); + + + foreach (DimensionType dimensionType in dimensionTypes) { - if (dimensionStyleNames.centerlineStyleNames.Contains(graphicsStyle.Name)) DimensionStylesSettings.centerlineStyles.Add(graphicsStyle); + if (dimensionType.Name == dimensionStyleNames.primaryDimensionTypeName) DimensionStylesSettings.primaryDimensionType = dimensionType; + if (dimensionType.Name == dimensionStyleNames.secondaryPipeDimensionTypeName) DimensionStylesSettings.secondaryPipeDimensionType = dimensionType; + if (dimensionType.Name == dimensionStyleNames.secondaryAccessoryDimensionTypeName) DimensionStylesSettings.secondaryAccessoryDimensionType = dimensionType; + if (dimensionType.Name == dimensionStyleNames.secondaryFittingDimensionTypeName) DimensionStylesSettings.secondaryFittingDimensionType = dimensionType; + if (dimensionType.Name == dimensionStyleNames.secondaryOtherDimensionTypeName) DimensionStylesSettings.secondaryOtherDimensionType = dimensionType; + if (DimensionStylesSettings.foundAllDimensionTypes) break; } - }; + if (dimensionStyleNames.centerlineStyleNames != null) + { + + foreach (GraphicsStyle graphicsStyle in graphicStyles) + { + if (dimensionStyleNames.centerlineStyleNames.Contains(graphicsStyle.Name)) DimensionStylesSettings.centerlineStyles.Add(graphicsStyle); + } + }; + if (dimensionStyleNames.flangeModeItems != null) DimensionStylesSettings.flangeModeItems = new List(dimensionStyleNames.flangeModeItems); + } + + + int[] flangeIds = DimensionStylesSettings.flangeModeItems.Select(item => item.elementId).ToArray(); + FlangeModeItem[] defaultFlangeModeItems = allFlangeFamilySymbols.Where(family => !flangeIds.Contains(family.Id.IntegerValue)).Select(family => new FlangeModeItem(family.Id, family.Name, FlangeDimensionMode.Default)).ToArray(); + DimensionStylesSettings.flangeModeItems.AddRange(defaultFlangeModeItems); + } catch (Exception ex) @@ -104,12 +132,17 @@ private void LoadFromDB() //requires that Load Dimension Types has been called f } - - + private void InitControls() + { + DimensionTypeSelector.Init(dimensionTypes, ref DimensionStylesSettings); + GraphicsStyleList.Init(graphicStyles, ref DimensionStylesSettings.centerlineStyles); + FlangeModeSelector.Init(new FlangeModeSelectorViewModel(ref DimensionStylesSettings.flangeModeItems)); + //DimensionPreviewControl.AddPreviewControlWithCustomView(uidoc.Document); + } private void SaveToDB() { if (DimensionStylesSettings == null) return; - DimensionStyleNames dimensionStyleNames = DimensionStylesSettings.GetDimensionStyleNames(GraphicsStyleList.SelectedGraphicStyleNames.ToArray()); + DimensionSettingsModel dimensionStyleNames = DimensionStylesSettings.GetDimensionStyleNames(GraphicsStyleList.SelectedGraphicStyleNames.ToArray()); try { MySettings.Default.DimensionStyles_Preferences = JsonConvert.SerializeObject(dimensionStyleNames); @@ -120,14 +153,6 @@ private void SaveToDB() } } - - protected override void OnClosing(CancelEventArgs e) - { - Hide(); - SaveToDB(); - e.Cancel = true; - } - protected void OnNotifyPropertyChanged([CallerMemberName] string memberName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(memberName)); @@ -144,6 +169,9 @@ public class DimensionStyles public DimensionType secondaryFittingDimensionType; public DimensionType secondaryOtherDimensionType; public List centerlineStyles = new List(); + public List flangeModeItems = new List(); + private Lookup flangeModeLookup => flangeModeItems.ToLookup(item => item.elementId, item => item.Mode) as Lookup; + public FlangeDimensionMode defaultFlangeMode = FlangeDimensionMode.Exact; public DimensionType GetSecondaryDimensionType(BuiltInCategory builtInCategory) { switch (builtInCategory) @@ -154,34 +182,42 @@ public DimensionType GetSecondaryDimensionType(BuiltInCategory builtInCategory) default: return secondaryOtherDimensionType; } } - public DimensionStyleNames GetDimensionStyleNames() + public DimensionSettingsModel GetDimensionStyleNames() { - return new DimensionStyleNames + return new DimensionSettingsModel { primaryDimensionTypeName = primaryDimensionType?.Name ?? string.Empty, secondaryPipeDimensionTypeName = secondaryPipeDimensionType?.Name ?? string.Empty, secondaryAccessoryDimensionTypeName = secondaryAccessoryDimensionType?.Name ?? string.Empty, secondaryFittingDimensionTypeName = secondaryFittingDimensionType?.Name ?? string.Empty, secondaryOtherDimensionTypeName = secondaryOtherDimensionType?.Name ?? string.Empty, - centerlineStyleNames = centerlineStyles?.Select(style => style.Name).Distinct().ToArray() + centerlineStyleNames = centerlineStyles?.Select(style => style.Name).Distinct().ToArray(), + flangeModeItems = flangeModeItems?.Where(item => item.Mode != FlangeDimensionMode.Default).ToArray() }; } - public DimensionStyleNames GetDimensionStyleNames(string[] graphicStyleNames) + public DimensionSettingsModel GetDimensionStyleNames(string[] graphicStyleNames) { - return new DimensionStyleNames + return new DimensionSettingsModel { primaryDimensionTypeName = primaryDimensionType?.Name ?? string.Empty, secondaryPipeDimensionTypeName = secondaryPipeDimensionType?.Name ?? string.Empty, secondaryAccessoryDimensionTypeName = secondaryAccessoryDimensionType?.Name ?? string.Empty, secondaryFittingDimensionTypeName = secondaryFittingDimensionType?.Name ?? string.Empty, secondaryOtherDimensionTypeName = secondaryOtherDimensionType?.Name ?? string.Empty, - centerlineStyleNames = graphicStyleNames + centerlineStyleNames = graphicStyleNames, + flangeModeItems = flangeModeItems?.Where(item => item.Mode != FlangeDimensionMode.Default).ToArray() }; } - + public FlangeDimensionMode GetMode(Element element) + { + if (!(element is FamilyInstance familyInstance) || !ElementCheckUtils.IsPipeFlange(familyInstance)) return FlangeDimensionMode.None; + int familyId = familyInstance?.Symbol?.Family?.Id.IntegerValue ?? -1; + if (familyId == -1) return FlangeDimensionMode.None; + return flangeModeLookup[familyId].FirstOrDefault(); + } } - public struct DimensionStyleNames + public struct DimensionSettingsModel { public string primaryDimensionTypeName; public string secondaryPipeDimensionTypeName; @@ -189,6 +225,7 @@ public struct DimensionStyleNames public string secondaryFittingDimensionTypeName; public string secondaryOtherDimensionTypeName; public string[] centerlineStyleNames; + public FlangeModeItem[] flangeModeItems; } } diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionTypeSelectorControl.xaml.cs b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionTypeSelectorControl.xaml.cs index 0a9f30c..34f0e90 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionTypeSelectorControl.xaml.cs +++ b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionTypeSelectorControl.xaml.cs @@ -27,7 +27,7 @@ public partial class DimensionTypeSelectorControl : UserControl, INotifyProperty { public event PropertyChangedEventHandler PropertyChanged; - private DimensionStyles dimensionStyles = new DimensionStyles(); + private DimensionStyles dimensionStyles; public DimensionType PrimaryDimensionType { @@ -80,8 +80,18 @@ public DimensionType SecondaryOtherDimensionType } } - public ObservableCollection dimensionTypes = new ObservableCollection(); - public ObservableCollection DimensionTypes { get => dimensionTypes; set => dimensionTypes = value; } + public DimensionType[] dimensionTypes = new DimensionType[0]; + public DimensionType[] DimensionTypes + { + get => dimensionTypes; + set + { + if (value == null || dimensionTypes == value) return; + dimensionTypes = value; + OnNotifyPropertyChanged(); + } + + } public DimensionTypeSelectorControl() { @@ -91,7 +101,7 @@ public DimensionTypeSelectorControl() public void Init(DimensionType[] dimensionTypes, ref DimensionStyles currentPreferences) { - DimensionTypes = new ObservableCollection(dimensionTypes); + DimensionTypes = dimensionTypes; dimensionStyles = currentPreferences; NotifyIntialized(); } diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/FlangeModeSelectorViewModel.cs b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/FlangeModeSelectorViewModel.cs new file mode 100644 index 0000000..afc6cd5 --- /dev/null +++ b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/FlangeModeSelectorViewModel.cs @@ -0,0 +1,76 @@ +using Autodesk.Revit.DB; +using Autodesk.Revit.UI; +using CarsonsAddins.Properties; +using CarsonsAddins.Utils; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace CarsonsAddins +{ + public class FlangeModeSelectorViewModel: INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + private DimensioningUtils.FlangeDimensionMode defaultMode = DimensioningUtils.FlangeDimensionMode.Exact; + public DimensioningUtils.FlangeDimensionMode DefaultMode + { + get => defaultMode; + set + { + if (value == DimensioningUtils.FlangeDimensionMode.Default || value == defaultMode) return; + defaultMode = value; + OnNotifyPropertyChanged(); + } + } + private List items = new List(); + public List Items + { + get => items; + set + { + if (value == null || items == value) return; + items = value; + OnNotifyPropertyChanged(); + } + } + + public FlangeModeSelectorViewModel( ref List items) + { + Items = items; + } + + + protected void OnNotifyPropertyChanged([CallerMemberName] string memberName = "") + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(memberName)); + } + } + public class FlangeModeItem + { + public event PropertyChangedEventHandler PropertyChanged; + public int elementId = -1; + public string Name { get; set; } = ""; + public Utils.DimensioningUtils.FlangeDimensionMode Mode { get; set; } = Utils.DimensioningUtils.FlangeDimensionMode.Default; + + + [JsonConstructor] + public FlangeModeItem(int elementId, string name, Utils.DimensioningUtils.FlangeDimensionMode mode) + { + this.elementId = elementId; + Name = name; + Mode = mode; + } + public FlangeModeItem(ElementId elementId, string name, Utils.DimensioningUtils.FlangeDimensionMode mode) + { + this.elementId = elementId.IntegerValue; + Name = name; + Mode = mode; + } + } +} diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/GraphicsStyleListControl.xaml.cs b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/GraphicsStyleListControl.xaml.cs index d73be16..f4433b6 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/GraphicsStyleListControl.xaml.cs +++ b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/GraphicsStyleListControl.xaml.cs @@ -70,6 +70,7 @@ public string ComboboxSelectedGraphicStyleName OnNotifyPropertyChanged(); } } + private Dictionary graphicStylesNameDictionary = new Dictionary(); private List selectedGraphicStyles = new List(); public GraphicsStyleListControl() diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionSettingsWindow.xaml b/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionSettingsWindow.xaml index 4e0f908..bf353c4 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionSettingsWindow.xaml +++ b/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionSettingsWindow.xaml @@ -18,6 +18,7 @@ + diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/Views/FlangeModeSelectorControl.xaml b/CarsonsAddins/Dimensioning/DimensionSettings/Views/FlangeModeSelectorControl.xaml new file mode 100644 index 0000000..8c35e3d --- /dev/null +++ b/CarsonsAddins/Dimensioning/DimensionSettings/Views/FlangeModeSelectorControl.xaml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/Views/FlangeModeSelectorControl.xaml.cs b/CarsonsAddins/Dimensioning/DimensionSettings/Views/FlangeModeSelectorControl.xaml.cs new file mode 100644 index 0000000..ea6313d --- /dev/null +++ b/CarsonsAddins/Dimensioning/DimensionSettings/Views/FlangeModeSelectorControl.xaml.cs @@ -0,0 +1,83 @@ +using Autodesk.Revit.UI; +using CarsonsAddins; +using CarsonsAddins.UICommands; +using CarsonsAddins.Utils; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace CarsonsAddins +{ + /// + /// Interaction logic for FlangeModeSelectorControl.xaml + /// + public partial class FlangeModeSelectorControl : UserControl + { + private CollectionViewSource collectionViewSource; + private FlangeModeSelectorViewModel viewModel; + public FlangeModeSelectorControl() + { + InitializeComponent(); + collectionViewSource = FindResource("FlangeItemsCollection") as CollectionViewSource; + collectionViewSource.GroupDescriptions.Add(new GroupByFlangeModeProperty(DimensioningUtils.FlangeDimensionMode.Exact)); + collectionViewSource.SortDescriptions.Add(new System.ComponentModel.SortDescription("Mode", System.ComponentModel.ListSortDirection.Descending)); + collectionViewSource.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", System.ComponentModel.ListSortDirection.Ascending)); + ModeTextColumn.ItemsSource = Enum.GetValues(typeof(DimensioningUtils.FlangeDimensionMode)); + + } + public void Init(FlangeModeSelectorViewModel viewModel) + { + this.viewModel = viewModel; + DataContext = viewModel; + collectionViewSource.Source = viewModel.Items; + collectionViewSource.GroupDescriptions.Clear(); + collectionViewSource.GroupDescriptions.Add(new GroupByFlangeModeProperty(viewModel.DefaultMode)); + } + + private void SetDefaultMode_Click(object sender, RoutedEventArgs e) + { + if (!(sender is MenuItem menuItem)) return; + if (!(menuItem.Parent is ContextMenu contextMenu)) return; + if (!(contextMenu.DataContext is CollectionViewGroup viewGroup)) return; + string groupName = viewGroup.Name.ToString(); + DimensioningUtils.FlangeDimensionMode mode; + if (Enum.TryParse(groupName, out mode) && viewModel.DefaultMode != mode) + { + viewModel.DefaultMode = mode; + collectionViewSource.GroupDescriptions.Clear(); + collectionViewSource.GroupDescriptions.Add(new GroupByFlangeModeProperty(mode)); + } + } + } + class GroupByFlangeModeProperty : PropertyGroupDescription + { + private DimensioningUtils.FlangeDimensionMode defaultMode = DimensioningUtils.FlangeDimensionMode.Exact; + public GroupByFlangeModeProperty(DimensioningUtils.FlangeDimensionMode defaultMode) : base("Mode") + { + this.defaultMode = defaultMode; + } + public override object GroupNameFromItem(object item, int level, CultureInfo culture) + { + var baseItem = base.GroupNameFromItem(item, level, culture); + if (!(baseItem is DimensioningUtils.FlangeDimensionMode mode)) return "Null"; + return GetGroupName(mode); + } + public string GetGroupName(DimensioningUtils.FlangeDimensionMode mode) + { + DimensioningUtils.FlangeDimensionMode displayMode = (mode == DimensioningUtils.FlangeDimensionMode.Default) ? defaultMode : mode; + return displayMode.ToString() + ((displayMode == defaultMode) ? " ( default )" : ""); + } + } +} diff --git a/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs b/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs index 5958030..01e444c 100644 --- a/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs +++ b/CarsonsAddins/Pipeline/Models/DimensionPipeline.cs @@ -105,7 +105,7 @@ public static void CreateDimensions(Document doc, Element[] elements, Element se matchesPrimary = AddReferences(ref primaryReferenceArray, ref secondaryReferenceArray, node, secondaryDimension); - bool splitDimension = node.isEnd || (node.mode == PipingElementReferenceOrderedList.FlangeDimensionMode.Exact || (node.mode == PipingElementReferenceOrderedList.FlangeDimensionMode.Partial && (node.isEdge || node.adjacentNonLinear))); + bool splitDimension = node.isEnd || (node.mode == FlangeDimensionMode.Exact || (node.mode == FlangeDimensionMode.Partial && (node.isEdge || node.adjacentNonLinear))); if (splitDimension) { diff --git a/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs b/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs index 38727fa..3a3809d 100644 --- a/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs +++ b/CarsonsAddins/Pipeline/Models/PipingElementReferenceOrderedList.cs @@ -3,14 +3,17 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; +using static CarsonsAddins.Utils.DimensioningUtils; + namespace CarsonsAddins.Pipeline.Models { class PipingElementReferenceOrderedList { - public enum FlangeDimensionMode { None, Exact, Partial, Negate } + public Element[] orderedElements; public ReferenceNode[] nodes; @@ -75,11 +78,12 @@ private void CreateReferenceNode(int index) bool isStart = index == 0; bool isEnd = index == orderedElements.Length - 1; bool isNonConnector = element.Name == "Non-Connector"; + FlangeDimensionMode mode = DimensionSettingsWindow.DimensionStylesSettings.GetMode(element); //bool isFlange = ElementCheckUtils.IsPipeFlange(element); nodes[index] = new ReferenceNode { builtInCategory = (BuiltInCategory)element.Category.Id.IntegerValue, - mode = GetMode(element), + mode = mode, origin = GeometryUtils.GetOrigin(element.Location), isStart = isStart, isEnd = isEnd, @@ -186,7 +190,7 @@ public void SubtractFlanges() if (nodes[i].isNonConnector) continue; switch(nodes[i].mode) { - case (FlangeDimensionMode.None): + case (FlangeDimensionMode.Default): break; case (FlangeDimensionMode.Exact): IgnoreFlange(i); @@ -201,15 +205,6 @@ public void SubtractFlanges() } } } - private FlangeDimensionMode GetMode(Element element) - { - if (!ElementCheckUtils.IsPipeFlange(element)) return FlangeDimensionMode.None; - - string familyName = (element as FamilyInstance).Symbol.FamilyName; - if (familyName.Contains("FLG")) return FlangeDimensionMode.Exact; - else if (familyName.Contains("MJ") || familyName.Contains("PO")) return FlangeDimensionMode.Negate; - return FlangeDimensionMode.Partial; - } private void IgnoreFlange(int index) { if (index < 0 || index >= nodes.Length) return; @@ -265,7 +260,7 @@ public struct ReferenceNode //public ElementCheckUtils.PipingCategory pipingCategory; public BuiltInCategory builtInCategory; public FlangeDimensionMode mode; - public bool isFlange => mode != FlangeDimensionMode.None; + public bool isFlange => mode != FlangeDimensionMode.Default; public XYZ origin; public bool isStart; public bool isEnd; diff --git a/CarsonsAddins/Setup/GenericComponentCommands.cs b/CarsonsAddins/Setup/GenericComponentCommands.cs index dfd5b92..fae2f8a 100644 --- a/CarsonsAddins/Setup/GenericComponentCommands.cs +++ b/CarsonsAddins/Setup/GenericComponentCommands.cs @@ -118,6 +118,19 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme /// private static UIApplication uiapp; private static T instance; + + public void InitWindow(UIApplication uiapp) + { + if (uiapp == null) return; + if (instance == null) + { + instance = new T(); + instance.Closing += Window_Closing; + } + instance.Init(uiapp.ActiveUIDocument); + instance.Closing += Window_Closing; + uiapp.Application.DocumentOpened += Application_DocumentOpened; + } public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { try diff --git a/CarsonsAddins/Shared/Utils/ConnectionUtils.cs b/CarsonsAddins/Shared/Utils/ConnectionUtils.cs index e223300..e300bd7 100644 --- a/CarsonsAddins/Shared/Utils/ConnectionUtils.cs +++ b/CarsonsAddins/Shared/Utils/ConnectionUtils.cs @@ -14,7 +14,7 @@ namespace CarsonsAddins.Utils public static class ConnectionUtils { /// - /// Default: None, + /// Default: Default, /// Bell: Female end of the Pipe. /// Spigot: Male end of the Pipe. /// diff --git a/CarsonsAddins/Shared/Utils/DimensioningUtils.cs b/CarsonsAddins/Shared/Utils/DimensioningUtils.cs index 36eaa78..4cedea1 100644 --- a/CarsonsAddins/Shared/Utils/DimensioningUtils.cs +++ b/CarsonsAddins/Shared/Utils/DimensioningUtils.cs @@ -10,6 +10,8 @@ namespace CarsonsAddins.Utils { public static class DimensioningUtils { + + public enum FlangeDimensionMode { None, Default, Exact, Partial, Negate } public static Line GetDimensionSegmentLine(DimensionSegment segment, XYZ direction) { if (segment.Value == null) return null; diff --git a/CarsonsAddins/Standalone/DebugGeometryCommand.cs b/CarsonsAddins/Standalone/DebugGeometryCommand.cs index f53d56c..162f05c 100644 --- a/CarsonsAddins/Standalone/DebugGeometryCommand.cs +++ b/CarsonsAddins/Standalone/DebugGeometryCommand.cs @@ -78,7 +78,7 @@ private ElementId[] GetStyleIds(Document doc) //requires that Load Dimension Typ GraphicsStyle[] graphicStyles = new FilteredElementCollector(doc).OfClass(typeof(GraphicsStyle)).Cast().Where(gs => pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Id.IntegerValue) || ((gs.GraphicsStyleCategory.Parent != null) && pipingCategories.Contains((BuiltInCategory)gs.GraphicsStyleCategory.Parent.Id.IntegerValue))).ToArray(); try { - DimensionStyleNames dimensionStyleNames = JsonConvert.DeserializeObject(MySettings.Default.DimensionStyles_Preferences); + DimensionSettingsModel dimensionStyleNames = JsonConvert.DeserializeObject(MySettings.Default.DimensionStyles_Preferences); if (dimensionStyleNames.centerlineStyleNames == null) return new ElementId[0]; foreach (GraphicsStyle graphicsStyle in graphicStyles) { From 83efe12c6385ae7be7584f4aced0128bc76b12a5 Mon Sep 17 00:00:00 2001 From: Carson McCombs Date: Wed, 17 Jul 2024 15:04:55 -0500 Subject: [PATCH 05/11] Fixed Dimension settings to now correctly save and load settings. --- .../ViewModels/PipeEndPrepBCWindow.xaml.cs | 1 - .../ViewModels/PipeEndPrepWindow.xaml.cs | 2 +- CarsonsAddins/CarsonsAddins.csproj | 70 +++++++++++----- .../DimensionSettingsWindow.xaml.cs | 71 +--------------- .../DimensionTypeSelectorControl.xaml.cs | 11 +-- .../ViewModels/FlangeModeSelectorViewModel.cs | 25 +----- .../ViewModels/PreviewControlWrapper.xaml.cs | 81 ------------------- .../Views/DimensionSettingsWindow.xaml | 15 ++++ .../Views/DimensionTypeSelectorControl.xaml | 26 +++--- .../Views/FlangeModeSelectorControl.xaml | 7 +- .../Views/FlangeModeSelectorControl.xaml.cs | 6 +- .../models/DimensionSettingsModel.cs | 19 +++++ .../models/DimensionStyles.cs | 67 +++++++++++++++ .../models/FlangedModeItem.cs | 30 +++++++ .../Pipeline/Models/DimensionPipeline.cs | 31 ++++--- .../PipingElementReferenceOrderedList.cs | 19 +++-- .../MyApplicationSettingsWindow.xaml.cs | 3 +- .../Standalone/DebugGeometryCommand.cs | 3 +- CarsonsAddins/app.config | 12 ++- CarsonsAddins/packages.config | 5 -- 20 files changed, 266 insertions(+), 238 deletions(-) delete mode 100644 CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/PreviewControlWrapper.xaml.cs create mode 100644 CarsonsAddins/Dimensioning/DimensionSettings/models/DimensionSettingsModel.cs create mode 100644 CarsonsAddins/Dimensioning/DimensionSettings/models/DimensionStyles.cs create mode 100644 CarsonsAddins/Dimensioning/DimensionSettings/models/FlangedModeItem.cs delete mode 100644 CarsonsAddins/packages.config diff --git a/CarsonsAddins/Automation/PipeEndPrep/ViewModels/PipeEndPrepBCWindow.xaml.cs b/CarsonsAddins/Automation/PipeEndPrep/ViewModels/PipeEndPrepBCWindow.xaml.cs index eeab83d..b382805 100644 --- a/CarsonsAddins/Automation/PipeEndPrep/ViewModels/PipeEndPrepBCWindow.xaml.cs +++ b/CarsonsAddins/Automation/PipeEndPrep/ViewModels/PipeEndPrepBCWindow.xaml.cs @@ -3,7 +3,6 @@ using Autodesk.Revit.UI; using CarsonsAddins.Properties; using CarsonsAddins.Utils; -using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; diff --git a/CarsonsAddins/Automation/PipeEndPrep/ViewModels/PipeEndPrepWindow.xaml.cs b/CarsonsAddins/Automation/PipeEndPrep/ViewModels/PipeEndPrepWindow.xaml.cs index c2fe7cf..a004de4 100644 --- a/CarsonsAddins/Automation/PipeEndPrep/ViewModels/PipeEndPrepWindow.xaml.cs +++ b/CarsonsAddins/Automation/PipeEndPrep/ViewModels/PipeEndPrepWindow.xaml.cs @@ -234,7 +234,7 @@ public PipeEndPrepPreferences(string pipeTypeId, string pipeTypeName) this.pipeTypeId = pipeTypeId; this.pipeTypeName = pipeTypeName; } - [JsonConstructor] + [System.Text.Json.Serialization.JsonConstructor] public PipeEndPrepPreferences(string pipeTypeId, string pipeTypeName, string bellEndPrep, string spigotEndPrep) { this.pipeTypeId = pipeTypeId; diff --git a/CarsonsAddins/CarsonsAddins.csproj b/CarsonsAddins/CarsonsAddins.csproj index 78c9813..0fd6dd0 100644 --- a/CarsonsAddins/CarsonsAddins.csproj +++ b/CarsonsAddins/CarsonsAddins.csproj @@ -50,6 +50,10 @@ CarsonsAddins + + enable + 8.0 + @@ -60,22 +64,19 @@ true - - False - ..\..\..\..\..\..\Program Files\Autodesk\Revit 2021\AdWindows.dll + + E:\Revit\Product\Revit 2023\AdWindows.dll - - ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + E:\Revit\Product\Revit 2023\AddIns\PnIDModeler\Newtonsoft.Json.dll - - False - ..\..\..\..\..\..\Program Files\Autodesk\Revit 2021\RevitAPI.dll + + E:\Revit\Product\Revit 2023\RevitAPI.dll - - False - ..\..\..\..\..\..\Program Files\Autodesk\Revit 2021\RevitAPIUI.dll + + E:\Revit\Product\Revit 2023\RevitAPIUI.dll @@ -87,11 +88,7 @@ 3.5 - - ..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll - True - True - + @@ -107,11 +104,13 @@ + + + - FlangeModeSelectorControl.xaml @@ -182,7 +181,6 @@ - SettingsSingleFileGenerator MySettings.Designer.cs @@ -253,7 +251,6 @@ - @@ -267,5 +264,40 @@ + + + + + + 8.0.0 + + + 4.5.1 + + + 4.5.5 + + + 4.5.0 + + + 4.3.1 + + + 6.0.0 + + + 8.0.0 + + + 8.0.4 + + + 4.5.4 + + + 4.5.0 + + \ No newline at end of file diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs index 6cbc8bd..01883f2 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs +++ b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionSettingsWindow.xaml.cs @@ -1,6 +1,7 @@ using Autodesk.Revit.DB; using Autodesk.Revit.UI; using CarsonsAddins; +using CarsonsAddins.Dimensioning.DimensionSettings.Models; using CarsonsAddins.Properties; using CarsonsAddins.Utils; using Newtonsoft.Json; @@ -120,7 +121,7 @@ private void LoadFromPreferences() //requires that Load Dimension Types has been int[] flangeIds = DimensionStylesSettings.flangeModeItems.Select(item => item.elementId).ToArray(); - FlangeModeItem[] defaultFlangeModeItems = allFlangeFamilySymbols.Where(family => !flangeIds.Contains(family.Id.IntegerValue)).Select(family => new FlangeModeItem(family.Id, family.Name, FlangeDimensionMode.Default)).ToArray(); + FlangeModeItem[] defaultFlangeModeItems = allFlangeFamilySymbols.Where(family => !flangeIds.Contains(family.Id.IntegerValue)).Select(family => new FlangeModeItem(family.Id.IntegerValue, family.Name, FlangeDimensionMode.Default)).ToArray(); DimensionStylesSettings.flangeModeItems.AddRange(defaultFlangeModeItems); @@ -160,72 +161,8 @@ protected void OnNotifyPropertyChanged([CallerMemberName] string memberName = "" } - public class DimensionStyles - { - public bool foundAllDimensionTypes => primaryDimensionType != null && secondaryPipeDimensionType != null && secondaryAccessoryDimensionType != null && secondaryFittingDimensionType != null && secondaryOtherDimensionType != null; - public DimensionType primaryDimensionType; - public DimensionType secondaryPipeDimensionType; - public DimensionType secondaryAccessoryDimensionType; - public DimensionType secondaryFittingDimensionType; - public DimensionType secondaryOtherDimensionType; - public List centerlineStyles = new List(); - public List flangeModeItems = new List(); - private Lookup flangeModeLookup => flangeModeItems.ToLookup(item => item.elementId, item => item.Mode) as Lookup; - public FlangeDimensionMode defaultFlangeMode = FlangeDimensionMode.Exact; - public DimensionType GetSecondaryDimensionType(BuiltInCategory builtInCategory) - { - switch (builtInCategory) - { - case BuiltInCategory.OST_PipeCurves: return secondaryPipeDimensionType; - case BuiltInCategory.OST_PipeFitting: return secondaryFittingDimensionType; - case BuiltInCategory.OST_PipeAccessory: return secondaryAccessoryDimensionType; - default: return secondaryOtherDimensionType; - } - } - public DimensionSettingsModel GetDimensionStyleNames() - { - return new DimensionSettingsModel - { - primaryDimensionTypeName = primaryDimensionType?.Name ?? string.Empty, - secondaryPipeDimensionTypeName = secondaryPipeDimensionType?.Name ?? string.Empty, - secondaryAccessoryDimensionTypeName = secondaryAccessoryDimensionType?.Name ?? string.Empty, - secondaryFittingDimensionTypeName = secondaryFittingDimensionType?.Name ?? string.Empty, - secondaryOtherDimensionTypeName = secondaryOtherDimensionType?.Name ?? string.Empty, - centerlineStyleNames = centerlineStyles?.Select(style => style.Name).Distinct().ToArray(), - flangeModeItems = flangeModeItems?.Where(item => item.Mode != FlangeDimensionMode.Default).ToArray() - }; - } - public DimensionSettingsModel GetDimensionStyleNames(string[] graphicStyleNames) - { - return new DimensionSettingsModel - { - primaryDimensionTypeName = primaryDimensionType?.Name ?? string.Empty, - secondaryPipeDimensionTypeName = secondaryPipeDimensionType?.Name ?? string.Empty, - secondaryAccessoryDimensionTypeName = secondaryAccessoryDimensionType?.Name ?? string.Empty, - secondaryFittingDimensionTypeName = secondaryFittingDimensionType?.Name ?? string.Empty, - secondaryOtherDimensionTypeName = secondaryOtherDimensionType?.Name ?? string.Empty, - centerlineStyleNames = graphicStyleNames, - flangeModeItems = flangeModeItems?.Where(item => item.Mode != FlangeDimensionMode.Default).ToArray() - }; - } - public FlangeDimensionMode GetMode(Element element) - { - if (!(element is FamilyInstance familyInstance) || !ElementCheckUtils.IsPipeFlange(familyInstance)) return FlangeDimensionMode.None; - int familyId = familyInstance?.Symbol?.Family?.Id.IntegerValue ?? -1; - if (familyId == -1) return FlangeDimensionMode.None; - return flangeModeLookup[familyId].FirstOrDefault(); - } - } + - public struct DimensionSettingsModel - { - public string primaryDimensionTypeName; - public string secondaryPipeDimensionTypeName; - public string secondaryAccessoryDimensionTypeName; - public string secondaryFittingDimensionTypeName; - public string secondaryOtherDimensionTypeName; - public string[] centerlineStyleNames; - public FlangeModeItem[] flangeModeItems; - } + } diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionTypeSelectorControl.xaml.cs b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionTypeSelectorControl.xaml.cs index 34f0e90..6656c6a 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionTypeSelectorControl.xaml.cs +++ b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/DimensionTypeSelectorControl.xaml.cs @@ -1,4 +1,5 @@ using Autodesk.Revit.DB; +using CarsonsAddins.Dimensioning.DimensionSettings.Models; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -31,7 +32,7 @@ public partial class DimensionTypeSelectorControl : UserControl, INotifyProperty public DimensionType PrimaryDimensionType { - get => dimensionStyles.primaryDimensionType; + get => dimensionStyles?.primaryDimensionType; set { if (value == null || value == dimensionStyles.primaryDimensionType) return; @@ -41,7 +42,7 @@ public DimensionType PrimaryDimensionType } public DimensionType SecondaryPipeDimensionType { - get => dimensionStyles.secondaryPipeDimensionType; + get => dimensionStyles?.secondaryPipeDimensionType; set { if (value == null || value == dimensionStyles.secondaryPipeDimensionType) return; @@ -51,7 +52,7 @@ public DimensionType SecondaryPipeDimensionType } public DimensionType SecondaryFittingDimensionType { - get => dimensionStyles.secondaryFittingDimensionType; + get => dimensionStyles?.secondaryFittingDimensionType; set { if (value == null || value == dimensionStyles.secondaryFittingDimensionType) return; @@ -61,7 +62,7 @@ public DimensionType SecondaryFittingDimensionType } public DimensionType SecondaryAccessoryDimensionType { - get => dimensionStyles.secondaryAccessoryDimensionType; + get => dimensionStyles?.secondaryAccessoryDimensionType; set { if (value == null || value == dimensionStyles.secondaryAccessoryDimensionType) return; @@ -71,7 +72,7 @@ public DimensionType SecondaryAccessoryDimensionType } public DimensionType SecondaryOtherDimensionType { - get => dimensionStyles.secondaryOtherDimensionType; + get => dimensionStyles?.secondaryOtherDimensionType; set { if (value == null || value == dimensionStyles.secondaryOtherDimensionType) return; diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/FlangeModeSelectorViewModel.cs b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/FlangeModeSelectorViewModel.cs index afc6cd5..3e32720 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/FlangeModeSelectorViewModel.cs +++ b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/FlangeModeSelectorViewModel.cs @@ -1,8 +1,8 @@ using Autodesk.Revit.DB; using Autodesk.Revit.UI; +using CarsonsAddins.Dimensioning.DimensionSettings.Models; using CarsonsAddins.Properties; using CarsonsAddins.Utils; -using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -51,26 +51,5 @@ protected void OnNotifyPropertyChanged([CallerMemberName] string memberName = "" PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(memberName)); } } - public class FlangeModeItem - { - public event PropertyChangedEventHandler PropertyChanged; - public int elementId = -1; - public string Name { get; set; } = ""; - public Utils.DimensioningUtils.FlangeDimensionMode Mode { get; set; } = Utils.DimensioningUtils.FlangeDimensionMode.Default; - - - [JsonConstructor] - public FlangeModeItem(int elementId, string name, Utils.DimensioningUtils.FlangeDimensionMode mode) - { - this.elementId = elementId; - Name = name; - Mode = mode; - } - public FlangeModeItem(ElementId elementId, string name, Utils.DimensioningUtils.FlangeDimensionMode mode) - { - this.elementId = elementId.IntegerValue; - Name = name; - Mode = mode; - } - } + } diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/PreviewControlWrapper.xaml.cs b/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/PreviewControlWrapper.xaml.cs deleted file mode 100644 index f2c2323..0000000 --- a/CarsonsAddins/Dimensioning/DimensionSettings/ViewModels/PreviewControlWrapper.xaml.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Autodesk.Revit.DB; -using Autodesk.Revit.UI; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; - - -namespace CarsonsAddins -{ - /// - /// Interaction logic for PreviewControlWrapper.xaml - /// - public partial class PreviewControlWrapper : UserControl - { - public PreviewControl previewControl; - /* - private Document previewDocument; - public Document PreviewDocument - { - get => previewDocument; - set => previewDocument = value; - } - private ElementId viewId = ElementId.InvalidElementId; - public ElementId ViewId - { - get => viewId; - set => viewId = value; - }*/ - - public PreviewControlWrapper() - { - InitializeComponent(); - //AddPreviewControl(previewDocument, ViewId); - } - public void AddPreviewControlWithCustomView(Document doc) - { - if (doc == null) return; - Transaction transaction = new Transaction(doc); - transaction.Start("Create Dimension View"); - try - { - Level level = Level.Create(doc, 0.0); - ElementId floorPlanId = doc.GetDefaultElementTypeId(ElementTypeGroup.ViewTypeFloorPlan); - if (level == null || floorPlanId == ElementId.InvalidElementId) - { - transaction.RollBack(); - return; - } - ViewPlan viewPlan = ViewPlan.Create(doc, floorPlanId, level.Id); - - previewControl = new PreviewControl(doc, viewPlan.Id) - { - IsEnabled = false - }; - - PreviewControlGrid.Children.Add(previewControl); - - - - transaction.Commit(); - } - catch(Exception ex) - { - transaction.RollBack(); - TaskDialog.Show("Error Creating Dimension View", ex.Message); - } - } - public void AddPreviewControl(Document doc, ElementId viewId) - { - if (doc == null || viewId == ElementId.InvalidElementId) return; - previewControl = new PreviewControl(doc, viewId); - PreviewControlGrid.Children.Add(previewControl); - previewControl.IsHitTestVisible = false; - - } - } -} diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionSettingsWindow.xaml b/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionSettingsWindow.xaml index bf353c4..53f5b78 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionSettingsWindow.xaml +++ b/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionSettingsWindow.xaml @@ -19,6 +19,21 @@ + + + + + + + + + + + + + + + diff --git a/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionTypeSelectorControl.xaml b/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionTypeSelectorControl.xaml index 572db8d..d40b981 100644 --- a/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionTypeSelectorControl.xaml +++ b/CarsonsAddins/Dimensioning/DimensionSettings/Views/DimensionTypeSelectorControl.xaml @@ -16,7 +16,7 @@ - + - + - - + + - + @@ -99,7 +98,7 @@ - + @@ -130,7 +129,7 @@