Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How do I get all the outermost walls in the model?

31 REPLIES 31
SOLVED
Reply
Message 1 of 32
718066900
4699 Views, 31 Replies

How do I get all the outermost walls in the model?

I'm sorry, I'm nervous because my English is not very good~

 

How do I get all the outermost walls in the model?

 

It's like a picture shown in the picture::

12.pngthanks!

Tags (1)
31 REPLIES 31
Message 2 of 32
jeremytammik
in reply to: 718066900

Take a look at the `DirectionCalculation` Revit SDK sample and The Building Coder discussion of it
on south facing walls:

 

http://thebuildingcoder.typepad.com/blog/2010/01/south-facing-walls.html

 

That will provide a good starting point for you.

 

It uses the built-in wall function parameter `FUNCTION_PARAM` to filter for exterior walls.

 

I updated the code presented there and added it to The Building Coder samples for you, in the CmdCollectorPerformance.cs module lines L293-L323:

 

https://github.com/jeremytammik/the_building_coder_samples

 

https://github.com/jeremytammik/the_building_coder_samples/blob/master/BuildingCoder/BuildingCoder/C...

 

First, we implement a predicate method `IsExterior` that checks this parameter value to determine whether a wall type is exterior or not:

 

  /// <summary>
  /// Wall type predicate for exterior wall function
  /// </summary>
  bool IsExterior( WallType wallType )
  {
    Parameter p = wallType.get_Parameter(
      BuiltInParameter.FUNCTION_PARAM );

    Debug.Assert( null != p, "expected wall type "
      + "to have wall function parameter" );

    WallFunction f = (WallFunction) p.AsInteger();

    return WallFunction.Exterior == f;
  }

 

With that, you can retrieve all exterior walls with a filtered element collector like this:

 

  /// <summary>
  /// Return all exterior walls
  /// </summary>
  IEnumerable<Element> GetAllExteriorWalls(
    Document doc )
  {
    return new FilteredElementCollector( doc )
      .OfClass( typeof( Wall ) )
      .Cast<Wall>()
      .Where<Wall>( w =>
        IsExterior( w.WallType ) );
  }

 

Since the wall function filter is just checking a parameter value, the performance of this filtering process could be significantly enhanced by using a parameter filter instead of the slow .NET based `IsExterior` method post-processing:

 

http://thebuildingcoder.typepad.com/blog/2010/06/parameter-filter.html

 

Cheers,

 

Jeremy

 



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

Message 3 of 32
jeremytammik
in reply to: 718066900

Published by the Building Coder for posterity as well:

 

http://thebuildingcoder.typepad.com/blog/2018/05/drive-revit-via-a-wcf-service-wall-directions-and-p...

 



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

Message 4 of 32
Revitalizer
in reply to: 718066900

Hi,

 

there is a BuildingEnvelopeAnalyzer class, but there seem to be problems when using it...

 

https://forums.autodesk.com/t5/revit-api-forum/finding-exterior-walls-by-buildingenvelopeanalyzer/m-...

https://forums.autodesk.com/t5/revit-api-forum/filtering-exterior-walls/m-p/5677706

 

Revitalizer

 

 




Rudolf Honke
Software Developer
Mensch und Maschine





Message 5 of 32
718066900
in reply to: jeremytammik

Thank you for such a quick answer, Jeremy!

As mentioned above, this method is judged by the parameters of the wall. However, I hope to judge whether it belongs to the outermost wall through the spatial location of the wall, because most engineers do not want to modify the type of the outermost wall later, which will increase a lot of work.

Message 6 of 32
jeremytammik
in reply to: 718066900

Yup, I fully agree. 

 

I have asked the development team for advice on how to tackle this effectively.

 

Cheers,

 

Jeremy

 



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

Message 7 of 32
jeremytammik
in reply to: 718066900

I heard back from the development team, and they say:

 

BuildingEnvelopeAnalyzer is supposed to be a reliable method to achieve this.

 

If there are problems with the results, this should be filed as a problem report. 

 

For us to do so, please submit a minimal reproducible case:

 

http://thebuildingcoder.typepad.com/blog/about-the-author.html#1b

 

To perform your own geometric analysis, you could also look for walls which don't have bounding rooms on both sides. This is easy, assuming rooms have been set in the model.

 

Cheers,

 

Jeremy

 



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

Message 8 of 32
718066900
in reply to: Revitalizer

Thank you very much!

But it doesn't seem to reach what I expected.

Message 9 of 32
718066900
in reply to: jeremytammik

Thank you for such, Jeremy!

I use the following code:

private void Execute3(Selection sel, List<Wall> elements2)
        {
            BuildingEnvelopeAnalyzerOptions buildingEnvelopeAnalyzerOptions = new BuildingEnvelopeAnalyzerOptions();
            buildingEnvelopeAnalyzerOptions.AnalyzeEnclosedSpaceVolumes = false;
            buildingEnvelopeAnalyzerOptions.OptimizeGridCellSize = true;
            //buildingEnvelopeAnalyzerOptions.GridCellSize = elements2[0].get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).AsDouble();
            //Level level = doc.GetElement(elements2[0].LevelId) as Level;
            //double _height = level.ProjectElevation;
            buildingEnvelopeAnalyzerOptions.GridCellSize = 2600/304.8;
            
            List<Wall> exteriorWalls = new List<Wall>();
            Document m_doc = doc;
            BuildingEnvelopeAnalyzer analyzer = BuildingEnvelopeAnalyzer.Create(m_doc, buildingEnvelopeAnalyzerOptions);
            if (null != analyzer)
            {
                IList<LinkElementId> linkIds = analyzer.GetBoundingElements();

                if (linkIds.Count > 0)
                {
                    foreach (LinkElementId linkId in linkIds)
                    {
                        if (linkId.HostElementId != ElementId.InvalidElementId)
                        {
                            Wall hostWall = m_doc.GetElement(linkId.HostElementId) as Wall;
                            if (null != hostWall)
                            {
                                exteriorWalls.Add(hostWall);
                            }
                        }
                        else if (linkId.LinkedElementId != ElementId.InvalidElementId)
                        {
                            RevitLinkInstance rvtInstance = m_doc.GetElement(linkId.LinkInstanceId) as RevitLinkInstance;
                            if (null != rvtInstance)
                            {
                                Wall linkWall = rvtInstance.Document.GetElement(linkId.LinkedElementId) as Wall;
                                if (null != linkWall)
                                {
                                    exteriorWalls.Add(linkWall);
                                }
                            }
                        }
                    }
                }
            }
            List<ElementId> ids = (from _id in exteriorWalls select _id.Id).ToList();
            sel.SetElementIds(ids);
        }

 

121.png

It is not normal to get the expected results.

I submitted an annex .

Message 10 of 32
jeremytammik
in reply to: 718066900

Yet another workaround was suggested: Place some room separation lines outside the building envelope and create a huge room around the entire building. Then, it’s just a matter of getting room boundaries, filtering out the RSLs, appending the remaining elements to your list, deleting the room and RSLs, and moving up to the next level. It may not work for some bad modelling cases, but catches most.

 



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

Message 11 of 32
jeremytammik
in reply to: 718066900

Dear Feng Wang,

 

Thank you for your report and reproducible case.

 

Sorry to hear that the BuildingEnvelopeAnalyzer does not return the expected result.

 

I logged the issue REVIT-131862 [BuildingEnvelopeAnalyzer returns wrong walls -- 14230846] with our development team for this on your behalf as it requires further exploration and possibly a modification to our software. Please make a note of this number for future reference.

 

You are welcome to request an update on the status of this issue or to provide additional information on it at any time quoting this change request number.

 

Best regards,

 

Jeremy

 



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

Message 12 of 32
jeremytammik
in reply to: 718066900

After further discussion with the development team, they asked: Is the building model enclosed? It needs to be in order for the analyzer to work. In other words, do you have Roof and Floor elements to form enclosed spaces in the model?

 



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

Message 13 of 32
718066900
in reply to: jeremytammik

Thank you very much, Jeremy tammik!
    There is no closure (no ceiling, floor).
    Because I want to get the outermost wall to automatically create ceiling and floor.

    Getting the outermost wall can do more automation.

Message 14 of 32
718066900
in reply to: jeremytammik

I tried again
Even closed, you can't get the result right.

 

I want to get the outermost wall to automatically create ceiling and floor.

Getting the outermost wall can do more automation.

thanks!

Message 15 of 32
jeremytammik
in reply to: 718066900

The development team replied to this as well, and say:

 

If the building is "open" upward and downward, in theory, all walls are exposed to the outside, and therefore all of them are "exterior". In this case, maybe it is better to go by the Function parameter of the walls.

 

Cheers,

 

Jeremy

 



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

Message 16 of 32
718066900
in reply to: jeremytammik

Thank you again, dear Jeremy! I have taken up your time.
Is it possible to realize this idea through a geometric algorithm?
This is a problem that bothers me.

Message 17 of 32
jeremytammik
in reply to: 718066900

Dear Feng Wang,

 

Yes, this is certainly possible.

 

It is also an interesting computational geometry task.

 

Many different approaches can be taken.

 

I would love to discover a really reliable approach that works under all circumstances.

 

Here is an idea for one that comes to mind right now on the fly:

 

You can easily determine whether a given point lies within a given polygon:

 

https://www.ics.uci.edu/~eppstein/161/960307.html

 

I also implemented that for the Revit API:

 

http://thebuildingcoder.typepad.com/blog/2010/12/point-in-polygon-containment-algorithm.html

 

http://thebuildingcoder.typepad.com/blog/2012/08/room-in-area-predicate-via-point-in-polygon-test.ht...

 

Now, if you have all your walls, their location curves (if they are non-linear, things get trickier), and endpoints, and are sure that they all form closed polygons, you could determine the maximal polygon enclosing all others by choosing the one that contains the maximum number of wall endpoints.

 

You might also be able to use some library providing 2D polygon or Boolean operations for this.

 

Some such libraries, other options and helpful ideas are discussed in The Building Coder topic group on 2D Booleans and Adjacent Areas:

 

http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.2

 

Oh yes, and we recently discussed determining the outermost loop of a face:

 

http://thebuildingcoder.typepad.com/blog/2017/10/disjunct-outer-loops-from-planar-face-with-separate...

 

That is a similar problem.

 

Cheers,

 

Jeremy

 



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

Message 18 of 32
jeremytammik
in reply to: 718066900

Please try adding the extra outermost room as suggested above and let us know how that goes.

 

Thank you!

 

Cheers,

 

Jeremy

 



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

Message 19 of 32
jeremytammik
in reply to: jeremytammik

I tried it out manually in your sample model, and it seems to work perfectly!

 

Add room separation lines around the outside of the building:

room_separation_lines.png

  

Create a room around the building using them:

 

room_around_building.png

This can easily be achieved programatically as well.

 

Now all you need to do is retrieve the room boundary, eliminate the exterior separation line boundary segments, delete the separation lines and room, and you are done.

  

Please share your code with us once you have it done.

 

I am looking forward to seeing that.

 

Thank you.

 

Cheers,

 

Jeremy

 



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

Message 20 of 32
718066900
in reply to: jeremytammik

Hi,

I have already created the room according to the method you provided, and successfully acquired the wall.

The attachment is the code file I submitted.
The code is simple, and the quality of the code looks bad.
I'm glad to talk to you.

 

I still want to do it with geometric algorithms.
If you have a good algorithm, can you share it

thank you.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community