LearnRevitAPI
Jan 12, 2024
Cut Element with Line
Recently I was making FIlledRegion tools, and I really wanted to make a Saw Cut with a line through regions.
As simple as it sounds, It actually took some time to come up with the workflow that works, and I want to share it with you.
It can be applied to other elements like Floors and Ceilings as well, so I think it's quite useful for you to know
💡 Let's learn how to cut elements with line.
Workflow
Firstly, let's brainstorm the workflow so you understand the steps and then we will go into coding part.
Here are the steps we will go through:
- Select FilledRegion and DetialLine
- Create infinite plane from Line
- Create temp Geometry from boundaries
- Cut Geometry with plane in both directions
- Get Outline of new geometries
- Recreate FilledRegions
These are the steps that I will explain to cut an element with a line.
Select Elements
There are different methods to select our elements. To make it the best user experience it's worth using ISelectionFilter, as it will limit elements that can be selected and avoid mistakes by selecting wrong elements.
Also I use forms.WarningBar from pyRevit to make it clearer for the user what needs to be selected while having an orange bar on the top.
Here are my custom ISelectionFilter classes:
Now we can combine it all together to prompt user to select multiple Regions and a single Detail Line with selection.PickObject / selection.PickObjects.
I also added Try/Except statements to avoid crashing, and if statement to check if we get any elements.
Create Infinite Plane from Line
Now we can convert a line into an infinite Plane that will be used to cut any geometry.
We can get Start and End point by using Curve.GetEndPoint method. And to make a plane we need 3 points to use Plane.CreateByThreePoints.
So I will get middle point of the line and change Z coordinate to be a bit higher. This will be enough for creating a plane.
Let's make it a function and create our plane
Also when we will start cutting our geometry, we need to get results from both sides of the line, so we can create 2 new Filled Regions on each side of the line.
For that we will need to mirror our plane, so we can get results from both sides later when we start cutting.
Here is a function to mirror a plane direction.
Create Geometry from Regions
New we can iterate through all FilledRegions and create geometry from them.
We will use FilledRegion.GetBoundaries to get outline. And then we can use GeometryCreationUtilities.CreateExtrusionGeometry to make it a 3D Shape by extrucing this outline up.
Cut Geometry with Plane
✂️ Once we have Geometry and a Plane we can start cutting.
We will use BooleanOperationsUtils.CutWithHalfSpace method for that. We can provide Geometry and a Plane and it will return us resulting geometry.
💡 This is also where we will need to flip our Plane to get second part!
Test Geometry
So now we should have 2 new Geometries. Before going any further we might want to test if we get correct results.
We can create a DirectShape from these geometries to create 3D shapes in Revit UI. This is a step that is useful during development but should be commented out in production.
💡 P.S. Don't forget Transaction!
Get New Geo Outline
Once you know that your new geometries are correct, we can start working backwards to create FIlledRegions again.
First of all let's get Geometry Outlines. I will be looking for the Top face of the geometry and then get its Outline using Face.GetEdgesAsCurveLoops
Create new FilledRegions
Now we have everything we need to Create new FilledRegions after the Cut, and delete the initial Region.
We will use FilledRegion.Create method and Document.Delete
We will also make sure that we use the same Region type by getting it with .GetTypeId
Here is the final Step
✨ Final Code
So let's put it all together in a single snippet to avoid confusion and misunderstanding!
Because the code snippet is a bit too long for a Newsletter I will paste it in this Blog Post:
✨ Check New Tools in EF-Tools
Join Newsletter
📩 You will be added to Revit API Newsletter
Join Us!
which is already read by 7400+ people!