Reference for Dimension logic!

nia98bim
Enthusiast
Enthusiast

Reference for Dimension logic!

nia98bim
Enthusiast
Enthusiast

hey all, I want to use new dimension but as I searched in forum there is a need two references to create a new dimension

but Idk what references should be used in the code, I'd appreciate give me a hint about the reference array in dimension logic. 

using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;

namespace WallDimension
{
    [Transaction(TransactionMode.Manual)]
    public class Auto : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            var uiapp = commandData.Application;
            var uidoc = uiapp.ActiveUIDocument;
            var doc = uidoc.Document;
            View vw = doc.ActiveView;

            try
            {
                // Prompt the user to select a wall element
                Reference pickedRef = uidoc.Selection.PickObject(ObjectType.Element, "Select a wall");
                Element selectedElement = uidoc.Document.GetElement(pickedRef);

                // Ensure the selected element has a location curve
                LocationCurve locationCurve = selectedElement.Location as LocationCurve;
                if (locationCurve == null)
                {
                    message = "The selected element does not have a location curve.";
                    return Result.Failed;
                }

                Curve wallCurve = locationCurve.Curve;
                XYZ startPoint = wallCurve.GetEndPoint(0);
                XYZ endPoint = wallCurve.GetEndPoint(1);
                Line wallLine = Line.CreateBound(startPoint, endPoint);
               

                // Retrieve references from the wall geometry
                ReferenceArray refArray = new ReferenceArray();

                refArray.Append(pickedRef);
                //what should add for reference
                refArray.Append(pickedRef);


                using (Transaction trans = new Transaction(doc, "Create Wall Dimension"))
                {
                    trans.Start();

                    Dimension newDimension = doc.Create.NewDimension(vw, wallLine, refArray);

                    trans.Commit();
                }

                return Result.Succeeded;
            }
            catch (Exception e)
            {
                message = e.Message;
                return Result.Failed;
            }
        }
    }
}

 

0 Likes
Reply
Accepted solutions (1)
478 Views
5 Replies
Replies (5)

Moustafa_K
Collaborator
Collaborator

when you draw a dimension on the UI not via API, you usually select to references, can be face of Wall A and a paralel Face of Wall B.

These 2 Faces have reference by which you can supply it to the create dimension method.

 

in your code, you only used the picked Reference and you used the same to fill the array, which has no meaning.

 

With that said, I suggest you look over the SDK samples of how it is done as well as on Revit ApiDoc

 

Let us know your findings

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes

perry.swoboda
Advocate
Advocate

Hi nia98bim,

You certainly have picked a difficult task.  The references that you are looking for can be derived from the wall geometry, as Moustafa_K said.  But he linked the wrong example.  You might find this one closer to what you need.

Create Dimension 

Good luck!

0 Likes

Moustafa_K
Collaborator
Collaborator

Thanks for picking that, 🙂 , I updated the link for the sake of accuracy

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes

nia98bim
Enthusiast
Enthusiast

@Moustafa_K @perry.swoboda 

hey thank you for your attention.

I checked out the sampel and I tried to use two references from start point and end point of wall but also it doesn't work for invalid references

 

using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;

namespace Wall_dimen
{
    [Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        ExternalCommandData m_revit = null;    // Store external command
        string m_errorMessage = "";            // Store error message
        List<Wall> m_walls = new List<Wall>(); // Store the walls selected

        /// <summary>
        /// Implement this method as an external command for Revit.
        /// </summary>
        public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements)
        {
            m_revit = revit;

            try
            {
                // Initialize the command by finding walls in the selection
                if (!Initialize())
                {
                    message = m_errorMessage;
                    return Result.Failed;
                }

                // Add dimensions from the start to the end of each selected wall
                if (!AddDimensions())
                {
                    message = m_errorMessage;
                    return Result.Failed;
                }

                return Result.Succeeded;
            }
            catch (Exception e)
            {
                message = e.Message;
                return Result.Failed;
            }
        }

        /// <summary>
        /// Initialize the command by finding walls in the selection.
        /// </summary>
        bool Initialize()
        {
            // Get UIDocument from ExternalCommandData
            UIDocument uidoc = m_revit.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            // Prompt user to select a wall
            Reference pickedRef = uidoc.Selection.PickObject(ObjectType.Element, "Select a wall");
            Element elem = doc.GetElement(pickedRef);

            if (!(elem is Wall))
            {
                m_errorMessage = "Please select a wall.";
                return false;
            }

            Wall wall = elem as Wall;

            // Clear previous selections
            m_walls.Clear();

            // Add selected wall to the list
            m_walls.Add(wall);

            return true;
        }

        /// <summary>
        /// Add dimensions from the start to the end of each selected wall.
        /// </summary>
        bool AddDimensions()
        {
            // Get UIDocument from ExternalCommandData
            UIDocument uidoc = m_revit.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            Transaction transaction = new Transaction(doc, "Add Dimensions");
            transaction.Start();

            try
            {
                foreach (Wall wall in m_walls)
                {
                    // Get the location curve of the wall
                    LocationCurve locationCurve = wall.Location as LocationCurve;
                    if (locationCurve == null)
                    {
                        m_errorMessage = $"Failed to get location curve for wall {wall.Name}.";
                        continue; // Skip to the next wall
                    }

                    Curve wallCurve = locationCurve.Curve;

                    // Create a dimension line from the start to the end of the wall
                    XYZ startPoint = wallCurve.GetEndPoint(0);
                    XYZ endPoint = wallCurve.GetEndPoint(1);

                    Line dimensionLine = Line.CreateBound(startPoint, endPoint);

                    // Create a ReferenceArray for the start and end points of the wall
                    ReferenceArray referenceArray = new ReferenceArray();
                    referenceArray.Append(wallCurve.GetEndPointReference(0));
                    referenceArray.Append(wallCurve.GetEndPointReference(1));

                    // Create a dimension between start and end points of the wall
                    Dimension newDimension = doc.Create.NewDimension(
                        doc.ActiveView,
                        dimensionLine,
                        referenceArray);
                }

                transaction.Commit();
                return true;
            }
            catch (Exception ex)
            {
                m_errorMessage = $"Failed to create dimensions: {ex.Message}";
                transaction.RollBack();
                return false;
            }
        }
    }
}

do you have any idea about what references exactly need in my code to create dimension?

regards,

0 Likes

Moustafa_K
Collaborator
Collaborator
Accepted solution

yes location curve has no reference. One of the possible ways is to loop through the geometry of the wall, and extract a face, you know, that has the edges you want to dimension. in your case you want the connecting edges of the wall, the start and end Trims of the wall.

 

so if you loop through the geometry you get the bottom face, and from the bottom face you extract the edges, the smallest 2 edges are those for the trims, and the largest are for the length ( assuming your wall like 20mm thickness with a length more than 20mm)  you need to know what are you measuring to align your algorithm

 

see this example:

var geo = wall.get_Geometry(
    new Options()
    {
        View = UiDoc.ActiveGraphicalView,
        ComputeReferences = true, // this is important since we need references for measuring
        IncludeNonVisibleObjects = false
    }
);

var solid = geo.OfType<Solid>().First();
var bottomFace = solid
    .Faces.OfType<Face>()
    .Where(o => o.ComputeNormal(new UV(.5, .5)).Z < 0) // get bottom face
    .First();

var ordered = bottomFace
    .EdgeLoops.OfType<EdgeArray>()
    .SelectMany(o => o.OfType<Edge>())
    .OrderBy(o => ((Edge)o).ApproximateLength);
// first 2 smallest opposit
// last 2 longest opposit

// Create a ReferenceArray for the start and end points of the wall
ReferenceArray referenceArray = new ReferenceArray();
referenceArray.Append(ordered.ElementAt(0).Reference);
referenceArray.Append(ordered.ElementAt(1).Reference);

// Create a dimension between start and end points of the wall
Dimension newDimension = doc.Create.NewDimension(
    doc.ActiveView,
    ordered.ElementAt(2).AsCurve() as Line,
    referenceArray
);
Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1