Hi there,
Im coming with a background of the Revit API with C# and python.
I am wondering if is there a way to take out some functions from Dynamo and use their implementation with the Revit API.
Alternatively, maybe look “under the hood” of Dynamo and see how a specific function is implemented.
To be more specific, for some reason in the Revit API the ExecuteBooleanOperation method doesn’t work, but in Dynamo it does (its called Solid.ByUnion).
Apparently the issue with ExecuteBooleanOperation in the Revit API is familiar and all the suggested solutions for it requires complicated workarounds which I’m trying to avoid. I’m also trying to avoid writing my add-in using Dynamo as its going to be long and I’m not fluent in it.
I tried Running a python script up until the point where I have to use the Solid.ByUnion node, but the node did not accept my array of Solid instances. it seems that the type of Solid in Dynamo is not the same type as Solid in the Revit API. Im not sure about it but it seems like the Dynamo does not uses the same classes as the the Revit API
So if possible and someone can point me in the right direction on how to extract a function from Dynamo please.
The Dynamo geometry library is different than the Revit one. Revit has it’s own kernel, with limitations around stuff like element size (everything needs to be greater than 1/128 of a inch, but smaller than 22 miles), while Dynamo uses an implementation of ASM which is the same code as several other products. ASM has it’s own limitations (geometry scaling as one example), but since it’s built for geometry it has a lot which it can do that Revit cannot.
As a result the ‘solid’ you have in the Revit API is not going to be the same as the ‘solid’ you get in Dynamo - it’s like a solid in AutoCAD differs from a solid in Revit. This also means that the functions will not port over to Revit without first converting thr objects from Revit classes to Dynamo one, and then back again after you perform the function. The level of effort in such conversions is high, and the frequency of updates is also extreme (every point release for Revit is a potential break in the conversion process). Further, ASM is not open source and cannot be used directly with any tools - Dynamo doesn’t even ship with it (you have to have an Autodesk product installed which contains ASM to get geometry in Dynamo).
All of that is to say, you can’t reproduce the function using Dynamo’s code, nor can you call the Dynamo function on the Devot geometry.
However I can confirm that the Revit API method you’re looking at works for all geometric shapes which Revit supports, or at least every shape I have seen. Can you share a minimal code sample and Revit file to reproduce the issue you are having?
Thanks for your response,
I’m adding an ExternalCommand.
It seems that I cant upload a .rvt file, so to recreate the issue, using the Construction Template I created a new minimal project that only has 2 walls modeled with nothing else besides them, and ran the command.
The issue I mentioned persisted (error below code).
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System.Collections.Generic;
using System.Linq;
namespace Union
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
class UnionCommand : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
Document doc = uidoc.Document;
IList<Wall> allWalls = new FilteredElementCollector(doc).OfClass(typeof(Wall)).WhereElementIsNotElementType().Cast<Wall>().ToList();
IList<Solid> strWallSolids = allWalls.SelectMany(wall => getGeometryObjectsForWall(wall)).ToList();
BooleanOperationsUtils.ExecuteBooleanOperation(strWallSolids[0], strWallSolids[1], BooleanOperationsType.Union);
return Result.Succeeded;
}
/// <summary>
/// a getter function to extract and get all solids from a wall.
/// </summary>
private IList<Solid> getGeometryObjectsForWall(Wall wall)
{
Options geoOptions = new Options();
geoOptions.IncludeNonVisibleObjects = true;
return wall.get_Geometry(geoOptions).OfType<Solid>().ToList();
}
}
}
Also this is the error I recieved:
Failed to perform the Boolean operation for the two solids. This may be due to geometric inaccuracies in the solids, such as slightly misaligned faces or edges. If so, eliminating the inaccuracies by making sure the solids are accurately aligned may solve the problem. This also may be due to one or both solids having complexities such as more than two faces geometrically meeting along a single edge, or two coincident edges, etc. Eliminating such conditions, or performing a sequence of Boolean operations in an order that avoids such conditions, may solve the problem.
Bumped your trust level so you should be able to post a file now - if not you can use a 3rd party service such as dropbox, onedrive, box, google drive, wetransfer, etc…
Looks like your function for getGeometryObjectsForWall is returning a list of solids for each wall, which I think might be causing issues… I’ll try and put some Python together as I don’t have VS working at the moment…