Update width of a Curtain Panel

Update width of a Curtain Panel

george1985
Collaborator Collaborator
342 Views
3 Replies
Message 1 of 4

Update width of a Curtain Panel

george1985
Collaborator
Collaborator

Hello,

Is it possible to update the width of a Curtain Panel, via Revit API?

For example, I would like to update the width of the following Curtain Panel, from 3000 to 4000 (no curtain grids are pinned, by the way):

george1985_0-1740942864120.png


Another user already tried to update the width via BuiltInParameter.CURTAIN_WALL_PANELS_WIDTH parameter.
I tried the same code, and realized that both Curtain Panel's Width and Height parameter values are ReadOnly. Regardless of the fact that curtain grids are not pinned:

george1985_1-1740942923298.png

 

 

Does anyone else have an idea how the upper Curtain Panel width, could be updated?

Thank you very much in advance for the help.

0 Likes
Accepted solutions (1)
343 Views
3 Replies
Replies (3)
Message 2 of 4

jeremy_tammik
Alumni
Alumni

The standard approach to address such a task programmatically goes like this:

  

  • Set up your BIM manually in the UI
  • Perform the required modification manually in the UI
  • Analyse the resulting changes in the Revit database in the elements, their properties and relationships using RevitLookup and other db exploration tools

  

The knowledge of the manual modification steps and the resulting db changes will help determine how to achieve the same programmatically.

  

So, how do you perform this modification manually in the UI?

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 4

jeremy_tammik
Alumni
Alumni
Accepted solution

I went ahead and asked Gemini for you as described in my blog.; I asked for the manual approach to start with. However, due to my persona prompt, it jumped straight in to describing the API approach instead. I don't know whether it is the proper way to go or partly hallucination, but it may well help provide some guidance for you either way:

   

   

Alright, let's tackle this curtain panel width modification challenge. It's a common request, and while it might seem straightforward, the Revit API's handling of curtain panels and grids can introduce some nuances.

Understanding the Challenge

Curtain panels are inherently tied to curtain grids. Directly changing a curtain panel's width often means adjusting the grid lines that define it. We need to consider:

  1. Grid Line Manipulation: How to identify and modify the correct grid lines.
  2. Panel Constraints: How to ensure the panel remains within its constraints after width changes.
  3. Parameter Access: How to access and potentially adjust parameters related to width (if applicable).

Solution Approach

We'll break down the solution into steps, providing code snippets and explanations:

1. Identifying the Curtain Panel and its Grid Lines

C#
 
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System.Linq;

public void ModifyCurtainPanelWidth(Document doc, UIDocument uidoc, Element panel)
{
    if (panel is CurtainPanel curtainPanel)
    {
        // Get the host curtain system.
        Element host = doc.GetElement(curtainPanel.HostElementId);
        if (host is CurtainSystem curtainSystem)
        {
            // Get the grid line ids that define the panel.
            IList<ElementId> gridLineIds = curtainPanel.GetEdges().Select(edge => edge.Curve.Reference.ElementId).ToList();

            // Filter for vertical grid lines.
            List<GridLine> verticalGridLines = gridLineIds
                .Select(id => doc.GetElement(id) as GridLine)
                .Where(gridLine => gridLine != null && gridLine.Curve is Line line && line.Direction.IsAlmostEqualTo(XYZ.BasisU))
                .ToList();

            // Proceed if we have two vertical grid lines (defining the width).
            if (verticalGridLines.Count == 2)
            {
                ModifyGridLines(doc, verticalGridLines, 4000.0 / 304.8); // 4000 mm, converted to feet
            }
        }
    }
}

Explanation:

  • We first check if the selected element is a CurtainPanel.
  • We retrieve the CurtainSystem host.
  • curtainPanel.GetEdges() provides the edges, and we extract the GridLine IDs.
  • We filter for vertical GridLine instances by checking the curve direction.
  • We convert the desired width (4000 mm) to feet (Revit's internal units).

2. Modifying the Grid Lines

C#
 
private void ModifyGridLines(Document doc, List<GridLine> verticalGridLines, double targetWidthFeet)
{
    using (Transaction t = new Transaction(doc, "Modify Curtain Panel Width"))
    {
        t.Start();

        // Sort grid lines by X coordinate.
        verticalGridLines.Sort((g1, g2) => ((Line)g1.Curve).Origin.X.CompareTo(((Line)g2.Curve).Origin.X));

        GridLine firstGridLine = verticalGridLines[0];
        GridLine secondGridLine = verticalGridLines[1];

        // Get the current width in feet.
        double currentWidthFeet = Math.Abs(((Line)secondGridLine.Curve).Origin.X - ((Line)firstGridLine.Curve).Origin.X);

        // Calculate the required translation.
        double translationFeet = targetWidthFeet - currentWidthFeet;

        // Translate the second grid line.
        XYZ translationVector = new XYZ(translationFeet, 0, 0);
        ElementTransformUtils.MoveElement(doc, secondGridLine.Id, translationVector);

        t.Commit();
    }
}

Explanation:

  • We use a transaction to ensure atomicity.
  • We sort the grid lines by their X coordinate to determine which grid line to move.
  • We calculate the difference between the target width and the current width.
  • We use ElementTransformUtils.MoveElement() to translate the second grid line.
  • The transaction is committed.

3. Considerations and Improvements

  • Error Handling: Add checks for null values, invalid input, and potential exceptions.
  • Parameter Access: If the curtain panel has width parameters, consider modifying those directly (if possible). However, directly modifying the parameter of a panel that is driven by the grid, is often not possible.
  • Grid Line Locking: Check if the grid lines are locked. If so, unlock them before modification.
  • Curved Grids: For curved curtain grids, the logic will be more complex and require curve manipulation.
  • Unit Conversion: Always be mindful of unit conversions between millimeters and feet.
  • Selection: Create a method that allows the user to select a curtain panel instead of sending in a panel element.
  • Edge cases: The code provided assumes that the curtain panel is defined by 2 vertical gridlines. If this assumption is false, the code will fail.
  • The Building Coder: The Building Coder has many examples of working with grids, and curtain systems. Search that resource for additional information.

Complete Example (with Selection)

C#
 
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Linq;

public void ModifySelectedCurtainPanelWidth(Document doc, UIDocument uidoc)
{
    try
    {
        Reference selection = uidoc.Selection.PickObject(ObjectType.Element, "Select a curtain panel");
        Element panel = doc.GetElement(selection);
        ModifyCurtainPanelWidth(doc, uidoc, panel);
    }
    catch (Autodesk.Revit.Exceptions.OperationCanceledException)
    {
        // User cancelled selection.
    }
    catch (Exception ex)
    {
        TaskDialog.Show("Error", ex.Message);
    }
}

// ... (ModifyCurtainPanelWidth and ModifyGridLines methods as above)

This comprehensive approach should provide a solid foundation for modifying curtain panel widths. Remember to adapt the code to your specific needs and always test thoroughly.

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 4 of 4

george1985
Collaborator
Collaborator

Hi Jeremy,

 

Thank you very much!

 

I would have never guessed that we should move the grid line via Api.
Taken into account that in Revit UI, we change the value of the dimension line, to achieve the same result.