[BlenderBIM] Authoring IFC Files for Revit

edited June 2022 in General

I have been playing around with Blender BIM Addon and immersing myself in documentation, videos, IFC docs, etc.
You guys are going in the right direction and it's only a matter of time until BB becomes a serious contender!

I want to create IFC files that can be opened in Revit where objects are properly represented as families, or at least not generic models/DirectShapes. The source data, old Revit files (2013) or CAD files are translated using FME .

  • FME is able to read the Revit files and output data in a variety of formats, but their IFC Writer does not support IFC Materials and Types at this time.
  • I am hoping to import either a formatted spreadsheet or an incomplete IFC file that I can modify in BB and /or the IfcCsv tool.
  • The idea is to get as close as possible to replicating the original Revit model.
  • Whatever is missing could be added/fixed using the Revit API.

Is there a way to add IfcWallType, or any Type in BB currently?
From what I can tell, if the IFC file does not have Types to begin with, you can't add them.

Thanks,

Loren

Comments

  • @geometrygym (Jon Mirschin) might be the person who can help explain what's needed here. He's previously done parametric ifc based revit families. I'll be interested to see if anyone here wants to put developer time into making .IFC files that Revit likes.

  • Why not start with authoring the IFC directly from Revit 2013? It should export type relationships.
    I started developing the GG IFC importer for revit 2012, there are improvements and aspects since but the fundamentals are not that different.
    I can't remember the version of Revit when IFC export was open sourced, I suspect it might not be practical or possible to refactor the current code to work in Revit 2013 but it could be worth considering if the outcome is worth it.

    I take it you can't upgrade the 2013 file into modern versions of revit?

  • The BlenderBIM Add-on can indeed support types, and in fact so long as you follow the various undocumented Revit rules of "what Revit likes to see in an IFC" you can recreate parametric native-looking Revit models from IFC. @fbpyr has been doing this for quite some time.

    For example, if you simply model a wall as a mesh in Blender, it won't come through natively in Revit. However, if you model the wall as an extruded solid, or better yet as a type with material layers, then that data will come through into Revit.

    Adding types is very similar to adding regular objects, instead of assigning it an IfcElement, choose IfcElementType and then pick your type class. For a parametric wall, you'd want no geometry, so assign an IfcWallType to an "empty" Blender object. From there you can add your material layer set. Once done, whenever you add a wall instance / occurrence of that type, it will parametrically follow the material layer set rules and usage you've setup.

    The latest builds of the BlenderBIM Add-on actually come with a "Demo Template" you can use when starting up a fresh project. It comes with a bunch of example parametric walls, beams, columns, and furniture with 2D data as well (which if you play your cards right, you can actually get into Revit).

    LorenJanF
  • Oh, I just read that you're converting old source data, in that case there is the potential for it to be done quite fast if we're lucky. You'd add the missing types, and you can then assign types in bulk. Then you'd just bulk select things like walls and so on and bulk convert them from meshes into solids if they aren't already.

  • Thanks Everybody for the info!
    Yes, I am very interested in developing something that can generate an IFC file to essentially create an entire building in Revit from nothing but data. I call it the "InstaBuilding" and the process currently goes like this:
    [CAD floorplans, Excel table with level names and heights] >> FME >>Excel File>>Dynamo>>BAM! InstaBuilding!
    Very cool but slow. I started to code an add-in to replace my Dynamo graph when it occurred to me "why not IFC?" Easier said than done.

    A more recent experiment was using FME to read an older Revit project into an IFC file. The earliest version of Revit I have is 2018, and the 2013 file would not cooperate. I am very much in agreement with @Moult 's infamous blog post! The amount of time and money put into the model must have been quite a lot. It is a matter of principal for me to preserve this data.

    So far, I have been able to create Revit models for the walls and HVAC, but only geometry (BReps). The file has no IfcWallType or Material objects. FME can't make it happen yet and that's where BlenderBIM comes in.

    I will make an "empty" Blender object into a Type and see how it goes. Types should map to their respective wall name, I am guessing. The curtain walls are going to be fun as well. I have seen at least one web page talking about Revit/Ifc "secrets", but if you have a favorite, I would be curious.
    Stay Tuned!

  • @Loren as you find useful tips/links etc please add them to the wiki for reference and so we all can find them.
    There's a list of pages here: https://wiki.osarch.org/index.php?title=Category:Autodesk_Revit

    You can use the wiki as your personal notepad so the information is there.

  • @Loren you might be interested in... https://gitlab.com/osarch/FreeMVD_WorkFlow
    @yorik and I started this a number of years ago, to suss out what does/doesn't import into Revit, and other BIM programs, Blender and Freecad included. It's an ongoing exercise, and is always involving.
    Feel free to push any additional tests or modify anything you'd like.

    Bedson
  • Excellent! I will check those out. I was able to add an IfcWallType last night, so we shall see if it works in Revit. My thinking is that the easier it is to round trip, the more likely users will try open source apps who would otherwise be reluctant to do so.

    duncan
  • Unfortunately, as you probably know, roundtripping with Revit, has a very low, hard ceiling. :) I banged my head many times over the years. :)

  • edited March 2022

    Yes, it’s very frustrating and sadly ironic that the originator of IFC is not stepping up to provide a way to roundtrip. It’s almost like they want to keep things proprietary. Hmmmm.

    In your postings on the AutoDesk ifc plug-in git , I believe the person replying is the main PM for IFC development at AutoDesk, Angel Sosa? I doubt he has any control over the direction AutoDesk is going, but the notion of “completely replacing Open IFC with a similar technology to Link IFC. ” , raises a red flag for me. To have no plan to support imports with IFC4 and going their own way makes me wonder if they are doing this to prevent projects authored by non-AutoDesk applications from being the basis of a Revit model. “Referencing” is a weak response to the major problem of their domination.
    I look to IFC as a solution for future-proofing and what AutoDesk is doing undermines that. Users are completely dependent on their software without any real options once the project/building is finished. So, what to do?
    One idea is to use a hybrid approach where you create an IFC file with objects that can import ok, along with data that can be used by the Revit API ( via Dynamo, Addin, or PyRevit) to close the gap. I still need to grok exactly how it handles IFC, but based on my previous experiments, it’s worth looking at.

    Nigel
  • Question for the BlenderBimAddon devs: I want to add many wall types and materials to a large ifc file. Doing it manually through the interface would take a long time. Is there a way to do this via the IFCcsv feature? If so, is there a way to generate a CSV file with all available info?

  • Unfortunately not. IfcCSV can only edit, not add. What you describe sounds like you might want to write a script. It may not be hard, but it's your call :) We are here to help if you can describe exactly what the script should do.

  • Challenge accepted! I will have to research this and understand IfcOpenShell more, but here is how I think it could work:
    Script will read an external CSV file with IfcWallType data and an incomplete IFC file. IfcWallType data from CSV will be appended to the IFC file with ID#. Looping through each IfcWall, it would map it's respective IfcWallType. IfcWallType ID# is placed in IfcWall object by the comma delimiter number. Revit Wall/FamilyType name can be the common key. The script should return a modified IFC file. Not sure if it should be done inside Blender or just console.

    The IfcWallType data comes from a Revit file translated into IFCWallType object format and then writing to CSV using FME. I can either include a GUID at this point, or maybe do it in the script. There are probably a bunch of issues not factored in, but this project seems doable to me.
    Safe Software (dev of FME) is apparently working on providing Type and Material support for their IFC Writer, but there is no ETA. It's a nice challenge for me, so if anything, my Python skills will improve!
    Feel free to get back to me with questions or suggestions. Once I have some content, I will throw it in GitHub for whoever is curious.

  • The approach seems sound. If you haven't already, check out the code examples here for IfcOpenShell: https://wiki.osarch.org/index.php?title=IfcOpenShell_code_examples

    The API will also be very, very useful to do things correctly. These functions in particular:

    ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType")
    ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type)
    

    There are similarly API functions for materials, but I'd have to ask what type of materials are these - simple 1 wall = 1 material, or layered materials with thicknesses and so on?

  • OK perfect. I saw the assign_type function but didn't catch the create_entity. I think at first will keep it simple, then get fancier with the materials. Thanks for your help!

  • Wanted to give an update and had a few questions.
    In BB, I started using the Python text editor and was able to do a few basic things, but it crashed a number of times. The Blender documentation talks about a log file, but I could not find it. How do you usually do it?
    I'm using a basic Thinkpad, but it seems to have enough resources for what I am doing. Is the Spreadsheet window part of BB or native to Blender? I noticed that when looking at the object vertices, etc., the units seems to stay metric even though I set them as imperial. Also, it would be nice to select them an have them identified in the 3DViewer.

    It occurred to me that instead of importing an IFC file into BB, I could run IfcOpenShell scripts directly from the source application, which is FME. I was able to create an IfcWall entry, which showed up in the translation log, but need to figure out how the geometry is translated

    My initial goal is to author an IFC file of just one wall that can be read correctly in Revit and build from there.

    FME has the ability to create IFC files, but they lack Types and Materials at this time.
    Would you suggest using IfcOpenShell to change the output file and add missing stuff, or author it from scratch?

    On one hand, FME sets up the IfcProject, IfcBuilding, etc. On the other, doing it from scratch gives more control and would be a cleaner process. The script would be pretty involved if it were to handle all elements of a building, but the geometry and attributes for each object would already be there. Any feedback is appreciated.

  • @Loren you might feel that your efforts could be useful here: https://speckle.guide/user/blender.html
    The project there is moving IFC based data to Speckle using Blender. From Speckle then it can be pushed to Revit (or whatever else).

  • Thanks @duncan , I'll check it out. Speckle was actually suggested to me by FME people, but I never really "got" it. I will take another look.

  • edited March 2022

    Short version of Speckle:
    Software A Data is pulled -> Speckle server -> Software A data is pushed into Software B
    For example
    Rhino layer specified as Wall geometry -> Speckle server -> Walls made in Revit with specified properties
    ... and it keeps the data updated.

  • Pretty amazing it can do all that. I would have to convince my IT counterparts to do some major hoop jumping (we would probably have our own server), but if it works and can play nicely with all the other apps, it may be worth it.

  • I don't see a category for troubleshooting, so will stick to this thread:
    Getting an error with my script when using "by_type" which I can't figure out:

    Python Exception : Expected EntityInstance for attribute IfcPropertySet.OwnerHistory, got [#24=IfcOwnerHistory(#23,#2,$,$,$,$,$,1648172609)]

    Here is my script:
    import fme
    import fmeobjects
    import ifcopenshell
    class FeatureProcessor(object):
    def init(self):
    pass
    def input(self, feature):
    ifc_file = ifcopenshell.open(feature.getAttribute(r'_dataset'))
    filename = 'RVT_ExportTest1_WallsOnlyIfc4.ifc'
    walls = ifc_file.by_type('IfcWall')
    ownhist = ifc_file.by_type('IfcOwnerHistory')
    pset_wc = ifc_file.create_entity('IfcPropertySet', ifcopenshell.guid.new(), ownhist, 'Pset_Wall_Common', None, IsExternal='T')
    for w in walls:
    wtName = w[2]
    ifc_file.create_entity('IfcWallType', ifcopenshell.guid.new(), ownhist, wtName, None, None, (pset_wc), None, None, None, 'STANDARD')
    self.pyoutput(feature)
    def close(self):
    ifc.write(filename)

    I have tried adding a [0] after the 'ownhist' variable statement but got "attribute out of bounds"
    Also tried "ifc_file.by_id(24)" but no dice.

    Any ideas?

  • Any ideas?

    If I understood what you're trying to achieve in the above code:
    1. For each wall in your file, create a wall type, and set its name being the same as the wall
    2. Assign the wall type to your wall.
    3. Create a Property set named "Pset_WallCommon" and add it to the wall type.
    4. Every pset created has a "IsExternal" being set as true "T".

    Using the api takes care of the owner history for you. In general, it takes care of most (not to say all) IFC details for you. Very powerful IFC authoring when you start getting into it.

    Lets try this script, based on the above four points:

    import ifcopenshell
    import ifcopenshell.api
    file_path = "Your_file.ifc"
    file = ifcopenshell.open(file_path )
    walls = file.by_type("IfcWall")
    
    for wall in walls:
        # Create a wall type, and set its name being the same as the wall 
        wall_type = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcWallType", predefined_type="STANDARD", name=wall.Name)
        # Assign the wall type to the wall
        ifcopenshell.api.run("type.assign_type", file, related_object=wall, relating_type=wall_type)
        # Create a pset and add it to the wall type
        pset = ifcopenshell.api.run("pset.add_pset", file, name="Pset_Wall_Common", product=wall_type)
        # Edit your pset's properties
        ifcopenshell.api.run("pset.edit_pset", file, pset=pset, properties={"IsExternal": "T"})
    
    file.write(file_path)
    

    Here we go :) Hope this give you a better idea on how the api can be used

  • Hi @SigmaDimensions ,
    Very interesting, I didn't realize you should import the api as well. You are also using syntax that is a little different than I have seen. Will need to grok on it for a bit. Just to be clear: I want wall types associated with each wall. Does it automatically consolidate or skip duplicates? Thanks for the info, I was starting to run out of steam!

  • Hey @Loren!

    I want wall types associated with each wall.

    Yes that's what I understood you were after : every single wall in the file to be associated with a newly created wall type.
    This seems weird at first glance, since you would normally have a wall type being assigned to multiple walls.

    Does it automatically consolidate or skip duplicates?

    What do you mean by this ? Perhaps you need a few conditional statements to skip walls based on your needs.

    The syntax was new to me once, but honestly it is well designed and it grows on you - so I'll try to better explain what the api function does and how to use it:
    It is for interacting with the IFC database based on use cases you may need, in an abstract way.
    The usecases are organised in modules. For example, your first use case was to add a rooted entity. This is thus in the root module, and you can use the create_entity usecase. We can write:
    ifcopenshell.api.run("root.create_entity", file, **settings).

    If you read what the settings are for the create_entity usecase here :
    you can see the settings ifc_class, predefined_type, name.

    You can then run it and it takes care of the guid for you, the owner history, schema versions and other IFC implementation details we shouldn't dwell on!

    Hope this helps, there's always someone around when you're in need!

    theoryshawbrunopostle
  • Sorry, I didn’t explain that clearly enough: One wall type for multiple walls (of the same type).
    The reason: Although FME has an Ifc Writer, it doesn't create Types or Materials.

    The code samples wiki page and this IfcOpenShellAcademy post do not mention the api. Those were the two pages I based my code on! Even the API-Documentation doesn't have api in it, except for the title! It would be nice to refer to something that had the same structure as the GitHub code.

    The way the api is structured around use-cases makes sense.
    My use-case is to create Ifc files from scratch with data derived from two different sources: Corrupt Revit files and processed CAD floor plans. Using FME, I am able to translate the data and geometry into any format. At first I let FME's IfcWriter do most of the authoring, taking the output, adding walltypes and anything else missing. That is still a useful process, but recently, one of the FME experts advised me to create a **plugin **that would function as a _custom _Ifc Writer. That is another level of complexity, but it would give me more control from the beginning instead of fixing it after the fact.

    FME processes data differently than coding: Each piece of data (object, geometry, wall, raster image, etc) is an individual feature with attributes. They flow through the workspace one-by-one, like an assembly line. Looping is rarely needed. It's very powerful by itself, but you can add python scripts for more functionality. Referencing my screenshots from above, inside the PythonCaller transformer is a script where you can reference attributes from features directly into the script by double-clicking:
    That is just one of several ways to use python in FME.

    To that end:

    • If the api creates owner history and other "details" automatically, how does it get IfcPerson, Organization, Address, etc?
    • If the function of the api is to interact with the Ifc database (do you mean file?), does it require an Ifc file to start with?
    • Should I be able to author an Ifc file from scratch solely by using the api?
    • Looking at your code for the walltype, it looks like it is all key=value pairs and the "file" reference. No positional arguments allowed?

    Thank you for the insights. I am starting to understand what to look for. If you know of any more code samples, that would be very helpful.

    Have a great weekend!

  • edited June 2022

    Hello everybody,
    I've been making progress. For those interested, here is my GitHub repository. This will be my first project in GitHub. File organization TBD.
    So far, I've created walls that import Revit as a Family Type, using this as a template with a number of property and material sets. For now, I am reading in a simple Revit model as test data. At some point I will hook up FME Workspace no-code stuff that interprets CAD floor plans into Revit data.

    Because Revit is so problematic with IFC, especially geometry, I am looking to limit it to extrusions or bounding boxes. Can I get away with ignoring all geometry and just reference Families/Family Types? Stay tuned.
    By embedding Revit-centric data, like API arguments or DesignScript commands, I could use them later in a plugin or Dynamo script. That's the idea anyway. Feedback appreciated!
    Thanks
    Loren

Sign In or Register to comment.