C#-Revit:解决原始类别为墙体的Part构件长度与方向获取问题
Hey Hugo, great question—dealing with Part elements in Revit can be frustrating because they strip away some of the direct geometric properties their parent elements have. Luckily, you don’t need to mess with IFC GUIDs to get the length and direction you need. Here are two straightforward approaches:
1. Use the Part's Host Property (Most Reliable)
Since your Parts are derived from original Wall elements, you can directly access the parent wall via the Part.Host property. Once you have the original wall, you can pull its LocationCurve to get length and direction—no complex lookups required.
Here’s a quick C# example:
// Assume 'wallParts' is your collection of Parts with original category "Walls" foreach (Part part in wallParts) { // Get the parent element that this Part was created from Element hostElement = part.Host; if (hostElement is Wall originalWall) { LocationCurve wallLocation = originalWall.Location as LocationCurve; if (wallLocation != null) { // Get wall length directly from the curve double wallLength = wallLocation.Curve.Length; // Get the direction vector of the wall's curve XYZ wallDirection = wallLocation.Curve.Direction; // Use these values as needed } } }
This method is preferred because it uses the original wall’s precise geometric data, so you avoid any calculation errors from parsing the Part’s geometry directly.
2. Fallback: Parse the Part's Geometry (If Host Isn't Accessible)
In rare cases where the Host property might be null (e.g., some specialized Part creation workflows), you can extract the necessary data from the Part’s geometry. Wall Parts are typically extruded solids, so you can analyze the bounding box or solid geometry to find length and direction.
Example code:
Options geometryOptions = new Options { ComputeReferences = true, IncludeNonVisibleObjects = false }; foreach (Part part in wallParts) { GeometryElement partGeometry = part.get_Geometry(geometryOptions); foreach (GeometryObject geoObj in partGeometry) { if (geoObj is Solid solid && solid.Volume > 0) // Ignore empty solids { BoundingBoxXYZ bbox = solid.GetBoundingBox(); XYZ dimensions = bbox.Max - bbox.Min; // Determine which axis represents the wall's length double xLength = Math.Abs(dimensions.X); double yLength = Math.Abs(dimensions.Y); double zLength = Math.Abs(dimensions.Z); XYZ lengthDirection; double wallLength; if (xLength > yLength && xLength > zLength) { lengthDirection = XYZ.BasisX * Math.Sign(dimensions.X); wallLength = xLength; } else if (yLength > xLength && yLength > zLength) { lengthDirection = XYZ.BasisY * Math.Sign(dimensions.Y); wallLength = yLength; } else { lengthDirection = XYZ.BasisZ * Math.Sign(dimensions.Z); wallLength = zLength; } // Use length and direction here break; // Exit loop once we find the valid solid } } }
Just note that this method relies on the Part’s bounding box, which might not be perfect if the Part has complex cuts or modifications—but for standard wall Parts, it should work well.
Hope these solutions save you some time!
内容的提问来源于stack exchange,提问作者HugoG

