21 sept. 2019

[Dynamo+=Python] Voyez le Changement!








Au sommaire de la visibilité des changements entre 2 modèles et la gestion du changement de méthodes entre plusieurs versions de SDK (API Revit) 


Ne travaillant essentiellement qu'avec des modèles liés et des familles hébergées par face, l'un des avantages, c'est lorsque vient une mise à jour de la maquette Archi (maquette liée), soit les instances suivent la modification si la référence a été déplacée ou Revit m'alerte si celle-ci a été supprimée.


Cependant il est quand même utile de voir ces différences, par exemple si une porte a été rajoutée ou déplacée dans la maquette Archi, on ne verra pas forcément l'information lors de la mise à jour de la maquette liée et donc aucune information sur l'éventuel bloc de secours ou interrupteur à repositionner.



Quelques outils qui existent pour comparer 2 maquettes (liste non exhaustive)



  • BIM 360 (payant)
  • Navisworks (payant)
  • Script_Dynamo DataShape (gratuit)
  • quelques plugins comme Metamorphosis  (gratuit ou payant)
  • d'autres plugins en cours de développement 


En attendant de passer à BIM360 sur tous les projets 😁 et après avoir testé quelques solutions, j'ai fini par développer une solution seulement basée sur la comparaison des Id des éléments et de leur localisation.

Je n'ai pas nécessairement besoin d'avoir une comparaison basée sur la géométrie des éléments et/ou leurs paramètres et puis si je peux éviter d'extraire la géométrie complexe d'une centaine de porte de ce type, c'est mieux 😀😆





L'action du script est une résultante de comparaison de 2 dictionnaires de type 
{Id : Localisation} ou {Id : [Localisation, Symbol.Name] } ou encore {Id : BoundingBox } entre l'ancienne maquette et la nouvelle. Le résultat s'affiche sous forme de listes et de couleurs.


Dans les grandes lignes du script...


  • Après les "imports",  on définit et on récupère les variables importantes dont la version de Revit en cours ainsi que la liste des fenêtres ouvertes :
#after all imports...

link_model = UnwrapElement(IN[0])
apply_color = IN[1]
doclink = link_model.GetLinkDocument()
open_views = [doc.GetElement(view.ViewId) for view in uidoc.GetOpenUIViews()]

#get SDK version 

#for memory: app = DocumentManager.Instance.CurrentUIApplication.Application 
sdk_number = int(app.VersionNumber)
#Set color for element change location
color_change = Autodesk.Revit.DB.Color(255,0,0)
#Set color for new element 
color_new = Autodesk.Revit.DB.Color(255,0,255)
#Get Uni fillpatern
fillpatt = FilteredElementCollector(doc).OfClass(FillPatternElement).ToElements()
unifillid = [f.Id for f in fillpatt if f.Name == 'Uni'][0]


  • On collectionne les éléments des 2 maquettes (l'instance de la maquette liée "n-1" est récupèrer via le noeud "Links" du package Rhythm)

coll_in = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
collink = FilteredElementCollector(doclink).WhereElementIsNotElementType().ToElements()





  • La fonction pour coloriser les éléments selon la version de Revit

def overridecolor(element, rvtcolor, fillpatternid, view):
    if sdk_number < 2019:
        gSettings = OverrideGraphicSettings()
        gSettings.SetProjectionFillColor(rvtcolor)
        gSettings.SetProjectionFillPatternId(fillpatternid)
        gSettings.SetProjectionLineColor(rvtcolor)
        gSettings.SetProjectionLineWeight(10)
        gSettings.SetCutFillColor(rvtcolor)
        gSettings.SetCutFillPatternId(fillpatternid)

  TransactionManager.Instance.EnsureInTransaction(doc)
        view.SetElementOverrides(element.Id, gSettings)

        TransactionManager.Instance.TransactionTaskDone()
        return element
    else:
        gSettings = OverrideGraphicSettings()
        gSettings.SetSurfaceForegroundPatternColor(rvtcolor)
        gSettings.SetSurfaceForegroundPatternId(fillpatternid)
        gSettings.SetProjectionLineColor(rvtcolor)
        gSettings.SetProjectionLineWeight(10)
        gSettings.SetCutForegroundPatternColor(rvtcolor)
        gSettings.SetCutForegroundPatternId(fillpatternid)

        TransactionManager.Instance.EnsureInTransaction(doc)
        view.SetElementOverrides(element.Id, gSettings)

        TransactionManager.Instance.TransactionTaskDone()
        return element  



  • Puis on compare les dictionnaires avec des boucles classiques.
  • Et enfin on applique la fonction ci-dessus avec une couleur différente selon si les éléments sont nouveaux ou déplacés.

 Aperçu en vidéo





  • Note sur les Dictionnaires 
Avec Dynamo Il est tout à fait possible de travailler avec des dictionnaires Python, néanmoins pour les attribuer à la variable OUT, il est nécessaire de passer par des Dictionnaires DotNet   avec en plus une petite spécificité  "In Dynamo 2.0, keys can only be strings"





Néanmoins il est toujours possible de convertir un dictionnaire Python en liste




0 commentaires:

Enregistrer un commentaire