Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

pick 2 vertical points, why getting the modules beside it?

0 REPLIES 0
Reply
Message 1 of 1
TurtleWolf
93 Views, 0 Replies

pick 2 vertical points, why getting the modules beside it?

TurtleWolf
Participant
Participant

I need to pick 2 points in an elevation and know which curtain panels I've picked on; it's seeming to be going too wide with the bounding box? I pick 2 points over module 29 and it keeps giving me module 30 next to it?

TurtleWolf_0-1701358868578.png

 

#region Namespaces
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#endregion

namespace Trinam_23
{
    [Transaction(TransactionMode.Manual)]
    public class Detailing_14 : IExternalCommand
    {
        // Precision threshold for bounding box to prevent selecting nearby modules
        private const double BoundingBoxPrecisionThreshold = 0.02; // Example value, adjust based on requirements

        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Document doc = uidoc.Document;
            View view = doc.ActiveView;
            XYZ viewDirection = view.ViewDirection.Normalize();



            try
            {
                // Ensure a SketchPlane is set for picking points
                SetSketchPlaneForElevationView(doc);

                // Retrieve and list all curtain panels in the view
                string initialPanelList = ListCurtainPanelsInView(doc, view);


                // Prompt user to select two points in the elevation view
                XYZ point1 = uidoc.Selection.PickPoint("Select the first point on the elevation view");
                XYZ point2 = uidoc.Selection.PickPoint("Select the second point on the elevation view");

                // Adjust the bounding box to account for narrow vertical selections
                BoundingBoxXYZ boundingBox = CreateAdjustedBoundingBox(doc, point1, point2);

                // Filter and retrieve curtain panels based on the adjusted bounding box
                List<Element> curtainPanels = FindCurtainPanels(doc, boundingBox);

                if (!curtainPanels.Any())
                {
                    TaskDialog.Show("Result", "No curtain panels found within the selected area.");
                    return Result.Succeeded;
                }

                // Show the list of found curtain panels
                string panelList = GeneratePanelList(curtainPanels);
                //  string logMessage = $"Bounding Box Details:\nMin: {boundingBox.Min}\nMax: {boundingBox.Max}\nView Direction: {viewDirection}";
                //  TaskDialog.Show("Result", panelList + "\n\n" + logMessage);

                // Show the list of found curtain panels along with initial list
                string finalPanelList = GeneratePanelList(curtainPanels);
                string logMessage = $"Initial Curtain Panels:\n{initialPanelList}\n\nSelected Curtain Panels:\n{finalPanelList}\n\nBounding Box Details:\nMin: {boundingBox.Min}\nMax: {boundingBox.Max}\nView Direction: {viewDirection}";
                TaskDialog.Show("Result", logMessage);

                return Result.Succeeded;
            }
            catch (OperationCanceledException)
            {
                message = "Selection canceled by the user.";
                return Result.Cancelled;
            }
            catch (Exception ex)
            {
                message = "An error occurred: " + ex.Message;
                TaskDialog.Show("Error", message);
                return Result.Failed;
            }
        }
        private void SetSketchPlaneForElevationView(Document doc)
        {
            View view = doc.ActiveView;
            // Only set a sketch plane if one is not already set
            if (view.SketchPlane == null)
            {
                using (Transaction trans = new Transaction(doc, "Set SketchPlane"))
                {
                    trans.Start();
                    Plane plane = Plane.CreateByNormalAndOrigin(view.ViewDirection, view.Origin);
                    SketchPlane sketchPlane = SketchPlane.Create(doc, plane);
                    view.SketchPlane = sketchPlane;
                    trans.Commit();
                }
            }
        }
        private BoundingBoxXYZ CreateAdjustedBoundingBox(Document doc, XYZ point1, XYZ point2, double panelWidth = 0.1)
        {
            // Convert feet to Revit internal units (decimal feet to feet, assuming your project is in feet)
            panelWidth = panelWidth / 0.3048; // 1 foot = 0.3048 meters

            // Calculate the horizontal midpoint between point1 and point2
            double midX = (point1.X + point2.X) / 2.0;

            // Adjust minX and maxX based on the midpoint and half the panel width
            double minX = midX - (panelWidth / 2.0);
            double maxX = midX + (panelWidth / 2.0);

            // Calculate the minY, maxY, minZ, and maxZ as before
            double minY = Math.Min(point1.Y, point2.Y);
            double maxY = Math.Max(point1.Y, point2.Y);
            double minZ = Math.Min(point1.Z, point2.Z);
            double maxZ = Math.Max(point1.Z, point2.Z);

            // Create the bounding box
            BoundingBoxXYZ boundingBox = new BoundingBoxXYZ();
            boundingBox.Min = new XYZ(minX, minY, minZ);
            boundingBox.Max = new XYZ(maxX, maxY, maxZ);

            return boundingBox;
        }

        private List<Element> FindCurtainPanels(Document doc, BoundingBoxXYZ boundingBox)
        {
            Outline outline = new Outline(boundingBox.Min, boundingBox.Max);
            BoundingBoxIntersectsFilter filter = new BoundingBoxIntersectsFilter(outline);

            FilteredElementCollector collector = new FilteredElementCollector(doc)
                .OfClass(typeof(FamilyInstance))
                .OfCategory(BuiltInCategory.OST_CurtainWallPanels)
                .WherePasses(filter);

            return collector.ToList();
        }
        private string GeneratePanelList(IEnumerable<Element> curtainPanels)
        {
            StringBuilder sb = new StringBuilder("Found curtain panels with 'Module Number':\n");
            foreach (Element panel in curtainPanels)
            {
                Parameter param = panel.LookupParameter("Module Number");
                string moduleNumber = param?.AsValueString() ?? "N/A";
                sb.AppendLine($"Panel ID: {panel.Id.IntegerValue}, Module Number: {moduleNumber}");
            }

            return sb.ToString();
        }

        private string ListCurtainPanelsInView(Document doc, View view)
        {
            // Retrieve all curtain panels in the view
            IList<Element> curtainPanelsInView = new FilteredElementCollector(doc, view.Id)
                .OfCategory(BuiltInCategory.OST_CurtainWallPanels)
                .WhereElementIsNotElementType()
                .ToElements();

            StringBuilder sb = new StringBuilder();

            // Determine the bounding box for each curtain panel
            foreach (Element panel in curtainPanelsInView)
            {
                BoundingBoxXYZ boundingBox = panel.get_BoundingBox(view);
                sb.AppendLine($"Panel ID: {panel.Id}, Module Number: {GetModuleNumber(panel)}");
                sb.AppendLine($"Min: {boundingBox.Min}");
                sb.AppendLine($"Max: {boundingBox.Max}");
                sb.AppendLine();
            }

            return sb.ToString().Trim();
        }
        private string GetModuleNumber(Element element)
        {
            Parameter param = element.LookupParameter("Module Number");
            return param?.AsValueString() ?? "N/A";
        }

    }
}




0 Likes

pick 2 vertical points, why getting the modules beside it?

I need to pick 2 points in an elevation and know which curtain panels I've picked on; it's seeming to be going too wide with the bounding box? I pick 2 points over module 29 and it keeps giving me module 30 next to it?

TurtleWolf_0-1701358868578.png

 

#region Namespaces
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#endregion

namespace Trinam_23
{
    [Transaction(TransactionMode.Manual)]
    public class Detailing_14 : IExternalCommand
    {
        // Precision threshold for bounding box to prevent selecting nearby modules
        private const double BoundingBoxPrecisionThreshold = 0.02; // Example value, adjust based on requirements

        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Document doc = uidoc.Document;
            View view = doc.ActiveView;
            XYZ viewDirection = view.ViewDirection.Normalize();



            try
            {
                // Ensure a SketchPlane is set for picking points
                SetSketchPlaneForElevationView(doc);

                // Retrieve and list all curtain panels in the view
                string initialPanelList = ListCurtainPanelsInView(doc, view);


                // Prompt user to select two points in the elevation view
                XYZ point1 = uidoc.Selection.PickPoint("Select the first point on the elevation view");
                XYZ point2 = uidoc.Selection.PickPoint("Select the second point on the elevation view");

                // Adjust the bounding box to account for narrow vertical selections
                BoundingBoxXYZ boundingBox = CreateAdjustedBoundingBox(doc, point1, point2);

                // Filter and retrieve curtain panels based on the adjusted bounding box
                List<Element> curtainPanels = FindCurtainPanels(doc, boundingBox);

                if (!curtainPanels.Any())
                {
                    TaskDialog.Show("Result", "No curtain panels found within the selected area.");
                    return Result.Succeeded;
                }

                // Show the list of found curtain panels
                string panelList = GeneratePanelList(curtainPanels);
                //  string logMessage = $"Bounding Box Details:\nMin: {boundingBox.Min}\nMax: {boundingBox.Max}\nView Direction: {viewDirection}";
                //  TaskDialog.Show("Result", panelList + "\n\n" + logMessage);

                // Show the list of found curtain panels along with initial list
                string finalPanelList = GeneratePanelList(curtainPanels);
                string logMessage = $"Initial Curtain Panels:\n{initialPanelList}\n\nSelected Curtain Panels:\n{finalPanelList}\n\nBounding Box Details:\nMin: {boundingBox.Min}\nMax: {boundingBox.Max}\nView Direction: {viewDirection}";
                TaskDialog.Show("Result", logMessage);

                return Result.Succeeded;
            }
            catch (OperationCanceledException)
            {
                message = "Selection canceled by the user.";
                return Result.Cancelled;
            }
            catch (Exception ex)
            {
                message = "An error occurred: " + ex.Message;
                TaskDialog.Show("Error", message);
                return Result.Failed;
            }
        }
        private void SetSketchPlaneForElevationView(Document doc)
        {
            View view = doc.ActiveView;
            // Only set a sketch plane if one is not already set
            if (view.SketchPlane == null)
            {
                using (Transaction trans = new Transaction(doc, "Set SketchPlane"))
                {
                    trans.Start();
                    Plane plane = Plane.CreateByNormalAndOrigin(view.ViewDirection, view.Origin);
                    SketchPlane sketchPlane = SketchPlane.Create(doc, plane);
                    view.SketchPlane = sketchPlane;
                    trans.Commit();
                }
            }
        }
        private BoundingBoxXYZ CreateAdjustedBoundingBox(Document doc, XYZ point1, XYZ point2, double panelWidth = 0.1)
        {
            // Convert feet to Revit internal units (decimal feet to feet, assuming your project is in feet)
            panelWidth = panelWidth / 0.3048; // 1 foot = 0.3048 meters

            // Calculate the horizontal midpoint between point1 and point2
            double midX = (point1.X + point2.X) / 2.0;

            // Adjust minX and maxX based on the midpoint and half the panel width
            double minX = midX - (panelWidth / 2.0);
            double maxX = midX + (panelWidth / 2.0);

            // Calculate the minY, maxY, minZ, and maxZ as before
            double minY = Math.Min(point1.Y, point2.Y);
            double maxY = Math.Max(point1.Y, point2.Y);
            double minZ = Math.Min(point1.Z, point2.Z);
            double maxZ = Math.Max(point1.Z, point2.Z);

            // Create the bounding box
            BoundingBoxXYZ boundingBox = new BoundingBoxXYZ();
            boundingBox.Min = new XYZ(minX, minY, minZ);
            boundingBox.Max = new XYZ(maxX, maxY, maxZ);

            return boundingBox;
        }

        private List<Element> FindCurtainPanels(Document doc, BoundingBoxXYZ boundingBox)
        {
            Outline outline = new Outline(boundingBox.Min, boundingBox.Max);
            BoundingBoxIntersectsFilter filter = new BoundingBoxIntersectsFilter(outline);

            FilteredElementCollector collector = new FilteredElementCollector(doc)
                .OfClass(typeof(FamilyInstance))
                .OfCategory(BuiltInCategory.OST_CurtainWallPanels)
                .WherePasses(filter);

            return collector.ToList();
        }
        private string GeneratePanelList(IEnumerable<Element> curtainPanels)
        {
            StringBuilder sb = new StringBuilder("Found curtain panels with 'Module Number':\n");
            foreach (Element panel in curtainPanels)
            {
                Parameter param = panel.LookupParameter("Module Number");
                string moduleNumber = param?.AsValueString() ?? "N/A";
                sb.AppendLine($"Panel ID: {panel.Id.IntegerValue}, Module Number: {moduleNumber}");
            }

            return sb.ToString();
        }

        private string ListCurtainPanelsInView(Document doc, View view)
        {
            // Retrieve all curtain panels in the view
            IList<Element> curtainPanelsInView = new FilteredElementCollector(doc, view.Id)
                .OfCategory(BuiltInCategory.OST_CurtainWallPanels)
                .WhereElementIsNotElementType()
                .ToElements();

            StringBuilder sb = new StringBuilder();

            // Determine the bounding box for each curtain panel
            foreach (Element panel in curtainPanelsInView)
            {
                BoundingBoxXYZ boundingBox = panel.get_BoundingBox(view);
                sb.AppendLine($"Panel ID: {panel.Id}, Module Number: {GetModuleNumber(panel)}");
                sb.AppendLine($"Min: {boundingBox.Min}");
                sb.AppendLine($"Max: {boundingBox.Max}");
                sb.AppendLine();
            }

            return sb.ToString().Trim();
        }
        private string GetModuleNumber(Element element)
        {
            Parameter param = element.LookupParameter("Module Number");
            return param?.AsValueString() ?? "N/A";
        }

    }
}




0 REPLIES 0

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report