22 janv. 2023

[Dynamo += Python] Obtenir un Solide d'ouverture (Portes/Fenêtres)

 





Obtenir la géométrie d'ouverture d'une porte ou d'une fenêtre dans Revit peut-être un défi, surtout lorsque l'on a une multitude de paramètres de dimensions dans la famille. 


if this article is not in your language, use the Google Translate widget ⬈ (bottom of page for Mobile version )

À défaut d'analyser chaque paramètre afin de trouver les dimensions d'ouverture HxLxP, analysons la géométrie de l'élément, plus particulièrement les géométries non visibles.

Voici un exemple
 d'extraction de la géométrie d'ouverture d'une porte (ou d'une fenêtre) en analysant uniquement le style des lignes géométriques. 







le code Python (compatible avec tous les moteurs Python)



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)

Note :
On remarquera le changement de la méthode
PolyCurve.ByJoinedCurves() depuis Dynamo 2.16

0 commentaires:

Enregistrer un commentaire