How to create a wall and place colored rectangles every 600 mm using pyRevit

How to create a wall and place colored rectangles every 600 mm using pyRevit

sHubamyadav016
Enthusiast Enthusiast
139 Views
3 Replies
Message 1 of 4

How to create a wall and place colored rectangles every 600 mm using pyRevit

sHubamyadav016
Enthusiast
Enthusiast

cfguirtdirtdor ftl.

0 Likes
140 Views
3 Replies
Replies (3)
Message 2 of 4

naveen.kumar.t
Autodesk Support
Autodesk Support

Hi @sHubamyadav016 ,

 

Please note that the Revit API rarely supports functionality that is not also available in the user
interface.

Therefore, if the UI does not support a particular feature, the API likely will not either.

It's always beneficial to first research and determine the optimal manual approach to a solution before attempting to implement it programmatically.

I recommend figuring out how to achieve your goal using the Revit UI manually before using the Revit API.

Once you've identified the optimal manual approach, please share the steps you followed in the Revit UI to achieve the desired functionality. I will then assist you in implementing the same via the Revit API.

I hope this clarifies things.


Naveen Kumar T
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 3 of 4

sHubamyadav016
Enthusiast
Enthusiast

guhklfh

0 Likes
Message 4 of 4

naveen.kumar.t
Autodesk Support
Autodesk Support

Hi @sHubamyadav016 ,

 

As I mentioned, I am not an expert in pyRevit, so I am providing the code in C#.

I’m not entirely clear on your requirements. It appears that you are not using a Revit Family, but instead working directly with GeometryCreationUtilities.CreateExtrusionGeometry().

I have created a simple example based on the details you provided. Please review the attached sample code. It is provided for reference only—modify it as needed to suit your specific requirements.

From my observation, you may want to explore the Transform.CreateTranslation() and SolidUtils.CreateTransformed() methods.

namespace Revit_202X
{
    [Transaction(TransactionMode.Manual)]
    public class Class1 : IExternalCommand
    {
        private const double MM_TO_FT = 1.0 / 304.8;

        // Panel dimensions
        private const double PANEL_WIDTH = 600.0 * MM_TO_FT;
        private const double PANEL_HEIGHT = 65.0 * MM_TO_FT;   // thickness
        private const double PANEL_LENGTH = 2400.0 * MM_TO_FT; // extrusion
        private const double PANEL_THICKNESS = 5.0 * MM_TO_FT;

        // Wall dimensions
        private const double WALL_LENGTH = 3600.0 * MM_TO_FT;
        private const double WALL_HEIGHT = 3000.0 * MM_TO_FT;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            Wall wall = null;
            
            // 1. Create wall
            using (Transaction txWall = new Transaction(doc, "Create Wall"))
            {
                txWall.Start();

                Level level = new FilteredElementCollector(doc)
                    .OfClass(typeof(Level))
                    .Cast<Level>()
                    .FirstOrDefault();

                XYZ wallStart = new XYZ(0, 0, 0);
                XYZ wallEnd = new XYZ(WALL_LENGTH, 0, 0);

                wall = Wall.Create(doc, Line.CreateBound(wallStart, wallEnd), level.Id, false);
                wall.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).Set(WALL_HEIGHT);

                txWall.Commit();
            }

            if (wall == null) return Result.Failed;

            
            // 2. Get wall face (exterior or interior)
            PlanarFace targetFace = null;
            XYZ wallNormal = null;

            Options opt = new Options() { ComputeReferences = true, DetailLevel = ViewDetailLevel.Fine };
            GeometryElement geomElem = wall.get_Geometry(opt);

            foreach (GeometryObject obj in geomElem)
            {
                Solid solid = obj as Solid;
                if (solid == null || solid.Faces.Size == 0) continue;

                foreach (Face face in solid.Faces)
                {
                    PlanarFace pf = face as PlanarFace;
                    if (pf == null) continue;

                    // Only vertical faces (ignore top/bottom)
                    if (Math.Abs(pf.FaceNormal.Z) < 0.01)
                    {
                        targetFace = pf;
                        wallNormal = pf.FaceNormal.Normalize();
                        break;
                    }
                }
                if (targetFace != null) break;
            }

            if (targetFace == null)
            {
                TaskDialog.Show("Error", "No wall face found.");
                return Result.Failed;
            }

            
            // 3. Create base panel geometry
            Solid basePanel = CreatePanelSolid();

            
            // 4. Place panels on wall face
            using (Transaction txPanels = new Transaction(doc, "Place Panels"))
            {
                txPanels.Start();

                // Wall edge direction
                EdgeArrayArray edgeLoops = targetFace.EdgeLoops;
                XYZ wallDir = null;
                foreach (EdgeArray loop in edgeLoops)
                {
                    foreach (Edge e in loop)
                    {
                        IList<XYZ> pts = e.Tessellate();
                        if (pts.Count >= 2)
                        {
                            XYZ vec = (pts[1] - pts[0]);
                            if (Math.Abs(vec.Z) < 0.01) // horizontal edge
                            {
                                wallDir = vec.Normalize();
                                break;
                            }
                        }
                    }
                    if (wallDir != null) break;
                }

                if (wallDir == null) wallDir = XYZ.BasisX;

                // Panel placement start point (lower-left of face bounding box)
                BoundingBoxUV bb = targetFace.GetBoundingBox();
                XYZ origin = targetFace.Evaluate(new UV(bb.Min.U, bb.Min.V));

                int numPanels = (int)(WALL_LENGTH / PANEL_WIDTH);

                for (int i = 0; i < numPanels; i++)
                {
                    XYZ alongWall = origin + wallDir * (i * PANEL_WIDTH);

                    // Push panel slightly off the wall surface
                    XYZ moveVec =
                        alongWall
                        + wallNormal * (PANEL_HEIGHT) // thickness offset
                        + XYZ.BasisZ * ((WALL_HEIGHT - PANEL_LENGTH) / 2.0); // vertical centering

                    Transform move = Transform.CreateTranslation(moveVec);
                    Solid panelSolid = SolidUtils.CreateTransformed(basePanel, move);

                    DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                    ds.ApplicationId = "Revit_Panel_Placement";
                    ds.ApplicationDataId = Guid.NewGuid().ToString();
                    ds.SetShape(new GeometryObject[] { panelSolid });
                }

                txPanels.Commit();
            }

            return Result.Succeeded;
        }

        private Solid CreatePanelSolid()
        {
            List<XYZ> pts = new List<XYZ>()
            {
                new XYZ(0, 0, 0),
                new XYZ(PANEL_WIDTH, 0, 0),
                new XYZ(PANEL_WIDTH, PANEL_HEIGHT, 0),
                new XYZ(PANEL_WIDTH - PANEL_THICKNESS, PANEL_HEIGHT, 0),
                new XYZ(PANEL_WIDTH - PANEL_THICKNESS, PANEL_THICKNESS, 0),
                new XYZ(PANEL_THICKNESS, PANEL_THICKNESS, 0),
                new XYZ(PANEL_THICKNESS, PANEL_HEIGHT, 0),
                new XYZ(0, PANEL_HEIGHT, 0)
            };

            CurveLoop loop = new CurveLoop();
            for (int i = 0; i < pts.Count; i++)
            {
                XYZ p1 = pts[i];
                XYZ p2 = pts[(i + 1) % pts.Count];
                loop.Append(Line.CreateBound(p1, p2));
            }

            return GeometryCreationUtilities.CreateExtrusionGeometry(
                new List<CurveLoop>() { loop },
                XYZ.BasisZ,
                PANEL_LENGTH
            );
        }
    }
}

2.png1.png


Naveen Kumar T
Developer Technical Services
Autodesk Developer Network

0 Likes