Announcements

Starting in December, we will archive content from the community that is 10 years and older. This FAQ provides more information.

Creating Holes inside Filled Regions

Anonymous

Creating Holes inside Filled Regions

Anonymous
Not applicable

Hello everyone,

 

I am a co-op programming student at an architecture firm and I am currently working on an add-in that creates shadows that are filled regions. The way the shadow is created is by using the ExtrusionAnalyzer.Create() method, which takes the solid, a 0,0,0 plane, and the sun ray vector that is taken from the sun settings (Credits go to the very kind Jeremy Tammik from his blog post here: https://thebuildingcoder.typepad.com/blog/2013/06/sun-direction-shadow-calculation-and-wizard-update...

 

I am also using the clipper library to do boolean operations such as subtracting a buildings' footprint from the shadow that it casts, and outlining intersecting shadows from 2 buildings.

 

However my main problem comes when I am creating my Filled Regions. It seems that it will only ever take 1 list of continuous loops, which means I am not able to create holes in my filled regions, nor am I able to have 2 or more sets of boundaries for the FilledRegion.Create() method, since the way it seems that clipper handles the boolean operations only makes it return 1 list of continuous curves that are connected. An example can be seen below, with the circled area being when I want a hole to be:

 

Filled Regions created using my appFilled Regions created using my appBuildings being used to test my appBuildings being used to test my app

So to reiterate my question: Is it possible to create a filled region with holes or multiple separated boundaries programmatically?

 

I am using Revit 2018.3 and the Revit 2018.2 SDK

 

Thank you for reading through my post.

0 Likes
Reply
Accepted solutions (1)
3,597 Views
6 Replies
Replies (6)

jeremytammik
Autodesk
Autodesk
Accepted solution

Dear Mohsen,

 

Thank you for your interesting query, appreciation for the blog, and for moving this discussion out from our private email conversation here into the public discussion forum.

 

First question: is it possible to create a filled region with holes or multiple separated boundaries manually through the user interface?

 

If not, the Revit API will probably not support this either.

 

If yes, generate such a model manually and use RevitLookup to analyse the filled region geometry in detail.

 

Maybe you can discover how such loops are arranged and stored in the manually generated case, and maybe that will give us hints on how to achieve the same programmatically as well.

 

I hope this helps.

 

Best regards,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Anonymous
Not applicable

I have managed to figure this out, though with some interesting notes:

 

It seems that Revit automatically detects if the boundaries passed into a filled region are representing holes or not. For example, if a closed loop of curves is found within another closed loop of curves, Revit will automatically render it as a hole. However, boundaries that are touching or intersecting each other will prevent the filled region from being created and will cause Revit to throw an error. This is something to note because though the clipper library supports such an arbitrary case, Revit does not. 

 

What I was doing before was returning only 1 path of closed loops (a contour according to the clipper library terminology), which was incorrect. Instead I iterated through all of the paths returned from the clipper object that does the Boolean functions and was able to collect all of the boundaries that I needed to render more correct shadows.

0 Likes

jeremytammik
Autodesk
Autodesk

Thank you very much for discovering and describing the solution.

 

Can you provide a minimal sample code snippet illustrating the creation of a filled region with a hole in it?

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

Anonymous
Not applicable

Hi Jeremy,

 

Here is the minimum code snippet for creating a Filled Region with holes in it. I put the name for the draft view and region type as Level 1 Shadows and Shadow Proposed as it was already available in my document, but you can change it to whatever is convenient for you.

 

var doc = ActiveUIDocument.Document;
//Getting the view where we want the filled region to be drawn var draftView = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).First(n=>n.Name=="Level 1 Shadows");
//Getting the region type for the filled region var regionType = new FilteredElementCollector(doc).OfClass(typeof(FilledRegionType)).First(f=>f.Name=="Shadow Proposed"); //Boundaries of the filled region List<CurveLoop> profileLoops = new List<CurveLoop>();

//Coordinates of the outer loop XYZ[] points = new XYZ[5]; points[0] = new XYZ(0.0,0.0,0.0); points[1] = new XYZ(100.0,0.0,0.0); points[2] = new XYZ(100.0,100.0,0.0); points[3] = new XYZ(0.0,100.0,0.0); points[4] = new XYZ(0.0,0.0,0.0);
//Connecting the points of the outer loop CurveLoop outerLoop = new CurveLoop(); for (int i = 0; i < 4; i++)
{ Line line = Line.CreateBound(points[i], points[i+1]); outerLoop.Append(line); }
//Adding outer loop to the boundaries of the filled region profileLoops.Add(outerLoop);

//Coordinates of the inner loop XYZ[] points2 = new XYZ[5]; points2[0] = new XYZ(25.0,25.0,0.0); points2[1] = new XYZ(50.0,25.0,0.0); points2[2] = new XYZ(50.0,50.0,0.0); points2[3] = new XYZ(25.0,50.0,0.0); points2[4] = new XYZ(25.0,25.0,0.0);
//Connecting the points of the inner loop CurveLoop innerLoop = new CurveLoop(); for (int i = 0; i < 4; i++) { Line line = Line.CreateBound(points2[i], points2[i+1]); innerLoop.Append(line);
}
//Adding the inner loop to the filled region profileLoops.Add(innerLoop);
//Creating the filled region Transaction tr = new Transaction(doc,"Create Filled Region"); tr.Start(); var region = FilledRegion.Create(doc,regionType.Id,draftView.Id,profileLoops); tr.Commit();

 

 

 

jeremytammik
Autodesk
Autodesk

Dear Mohsen,

 

Thank you very much!

 

Looks perfect, and will hopefully be useful for others encountering this issue.

 

Best regards,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

MiguelVJC82W
Enthusiast
Enthusiast

Did "FilledRegion.Create" change again, I can no longer get the code above to work. I am using Revit 2021. I keep getting an error saying "Boundaries are self-intersecting" no matter what I try. 

0 Likes