Solid from a door familyInstance

Hello,
Is it possible to transform a solid with Volume 0 into a Solid?
The solid that creates the opening in a wall?
I can retrieve the openings, but not the one from a family instance.


python script:

import sys
import clr
clr.AddReference("RevitAPI")
import Autodesk 
from Autodesk.Revit.DB import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

ope=UnwrapElement(IN[0])
opt = Options()
opt.IncludeNonVisibleObjects = True
def _sol(geo):
    a=[]
    geoSet = geo.get_Geometry(opt)
    for g in geoSet:
        if isinstance(g, Solid):
            return g.ToProtoType()
        else:
            if isinstance(g, GeometryInstance):
                for gi in g.GetInstanceGeometry():
                    a.append(gi)
                return a


OUT = [_sol(o) for o in ope]

Thank you in advance.
Sincerely,
christian.stan

Hi,

Here’s an example by checking the GraphicsStyleId of invisible lines

import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument


assemblies = System.AppDomain.CurrentDomain.GetAssemblies()
dynamo_asm = next((a for a in assemblies if a.GetName().Name == 'DynamoCore'),None)
dynamo_version = str(dynamo_asm.GetName().Version)
dynamo_version = tuple(int(x) for x in dynamo_version.split("."))
print('dynamo_version', dynamo_version)

import itertools
    
def get_CutLinesOpenning(e):
    lines = []
    opt = Options()
    opt.IncludeNonVisibleObjects = True
    geoSet = e.get_Geometry(opt)
    for g in geoSet:
        if isinstance(g, GeometryInstance):
            for gi in g.GetInstanceGeometry():
                if isinstance(gi, Line):
                    if gi.GraphicsStyleId == ElementId.InvalidElementId:
                        # get horizontal Lines
                        vect = gi.ComputeDerivatives(0.5, True).BasisX
                        if abs(vect.Z) < 0.001:
                            lines.append(gi.ToProtoType())
    opt.Dispose()
    return lines
    
def compute_cutSolid(cutLines):
    DSCutSolid = None
    cutLines.sort(key = lambda x : x.StartPoint.Z, reverse = True)
    #
    for idx, (key_, group) in enumerate(itertools.groupby(cutLines, key = lambda x : round(x.StartPoint.Z, 2))):
        if idx == 0:
            top = key_
            if dynamo_version >= (2,16,0):
                top_loopCurve = DS.PolyCurve.ByJoinedCurves([x for x in group], 0.001, False, 0)
            else:
                top_loopCurve = DS.PolyCurve.ByJoinedCurves([x for x in group])
        # get bottom curves (iterate to the end)  and compute solid
        else:
            bottom = key_
            try:
                DSCutSolid = DS.Curve.ExtrudeAsSolid(top_loopCurve, Vector.ByCoordinates(0,0,-1), abs(top - bottom))
            except Exception as ex:
                print(ex)
    return DSCutSolid

e = UnwrapElement(IN[0])

cutLines = get_CutLinesOpenning(e)

OUT = compute_cutSolid(cutLines)
1 Like

Hi,
Thank you very much for the suggested approach: start with lines and rebuild a solid (it’s a shame I can’t access it).
I’ve varied it, but it’s still your approach.
Thank you very much.

import sys
import clr
clr.AddReference("RevitAPI")
import Autodesk 
from Autodesk.Revit.DB import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

ope=UnwrapElement(IN[0])
opt = Options()
opt.IncludeNonVisibleObjects = True
def _sol(geo):
    a=[]
    geoSet = geo.get_Geometry(opt)
    for g in geoSet:
        if isinstance(g, Autodesk.Revit.DB.Solid):
            return g.ToProtoType()
        else:
            if isinstance(g, GeometryInstance):
                for gi in g.GetInstanceGeometry():
                    if isinstance(gi, Autodesk.Revit.DB.Line):
                        a.append(gi)
                nivz=[x.Evaluate(0.5,True).Z for x in a]
                ht_extrusion=(max(nivz)-min(nivz))*0.3048
                a.sort(key = lambda x : x.Evaluate(0.5,True).Z, reverse = True)
                b=a[0:4]
                polycurv=DS.PolyCurve.ByJoinedCurves([b.ToProtoType() for b in b])
                solidfamily=DS.Curve.ExtrudeAsSolid(polycurv , DS.Vector.ByCoordinates(0,0,-1.0) , ht_extrusion)
                return solidfamily

OUT = [_sol(o) for o in ope]

Sincerely,
Christian.stan

1 Like