18 juin 2021

[Dynamo+=Python] Visualisation de Géométries Transitoires


https://pxhere.com/fr/photo/639131


Analyse de trajectoire, analyse de couverture de signal, analyse de points ou de surface, aide a la sélection, autant de taches ou l'affichage de géométries transitoire (avec ou sans couleurs) peut être d'une très grande aide au sein de la modélisation sous Revit.

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


Parmi les méthodes pour afficher temporairement des géométries (Solids) on retrouve :


  • Exemple avec AVF Display

voici un simple exemple  avec  Autodesk.Revit.DB.Analysis, ou le script permet visualiser les points de sélection précédents sur une surface (a chaque clic).

Le principe de création pour afficher une géométrie temporaire via AVF est le suivant : 





Note :

  • dans cet exemple une seule couleur est défini (couple FieldDomainPointsByUV  + FieldValues)
  • pour rappel la plage de couleur est défini dans le Style d'affichage de l'Analyse





import clr
import sys
import math
import System
from System.Collections.Generic import List

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import *

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
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
sys.path.append(pf_path + '\\IronPython 2.7\\Lib')

import traceback
    
def decoCreateAvfDisplayStyle2(func):
    def wrapper(*args, **kwargs):
        view = args[0]
        tg = TransactionGroup(doc, func.__name__)
        tg.Start()
        filter = System.Predicate[System.Object](lambda x : x.Name == "Paint_Preview")
        analysisDisplayStyle = List[Element](FilteredElementCollector(doc).OfClass(AnalysisDisplayStyle).ToElements()).Find(filter)
        if view.AnalysisDisplayStyleId == ElementId.InvalidElementId or analysisDisplayStyle is None :
            t = Transaction(doc, "Paint_Preview")
            t.Start()
            coloredSurfaceSettings = AnalysisDisplayColoredSurfaceSettings()
            coloredSurfaceSettings.ShowGridLines = False
            colorSettings = AnalysisDisplayColorSettings()
            legendSettings = AnalysisDisplayLegendSettings()
            legendSettings.ShowLegend = False
            analysisDisplayStyle = AnalysisDisplayStyle.CreateAnalysisDisplayStyle( doc, "Paint_Preview", coloredSurfaceSettings, colorSettings, legendSettings )
            view.AnalysisDisplayStyleId  = analysisDisplayStyle.Id
            t.Commit()
        # function Wrapp
        ret = func(*args, **kwargs) 
        tg.RollBack()            
        tg.Dispose()    
        return ret      
    return wrapper         

def createSphere(center, radius = 0.15):
    frame = Frame(center, XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ)
    arc = Arc.Create( center - radius * XYZ.BasisZ, center + radius * XYZ.BasisZ, center + radius * XYZ.BasisX )
    line = Line.CreateBound(arc.GetEndPoint( 1 ), arc.GetEndPoint( 0 ) )  
    halfCircle = CurveLoop.Create(List[Curve]([arc, line]))
    sphere = GeometryCreationUtilities.CreateRevolvedGeometry(frame, List[CurveLoop]([halfCircle ]) , 0, 2 * math.pi)
    return sphere

@decoCreateAvfDisplayStyle2
def surfaceSelection(view):
    """Pick points on the face with preview with AVF"""
    sfm = SpatialFieldManager.GetSpatialFieldManager(doc.ActiveView) 
    if sfm is None:
        sfm = SpatialFieldManager.CreateSpatialFieldManager(doc.ActiveView, 1)      
    sfm.Clear() 
    resultSchema = AnalysisResultSchema("Schema Name" , "Preview_Selection")
    schemaIndex = sfm.RegisterResult(resultSchema)
    
    flag = True
    error = None
    outgpoints = []
    TaskDialog.Show("Selection", "Select points on face, tap Esc to Finish")
    while flag:
        try:
            reference = uidoc.Selection.PickObject(ObjectType.Face, "Select points on face, tap Esc to Finish")
            selectface = doc.GetElement(reference).GetGeometryObjectFromReference(reference)
            outgpoints.append(reference.GlobalPoint.ToPoint() )
            # code for draw and paint selected Points
            sphere = createSphere(reference.GlobalPoint)
            for face in sphere.Faces:
                idx = sfm.AddSpatialFieldPrimitive(face, Transform.Identity)
                uvPts = List[UV]()
                bbuv = face.GetBoundingBox()
                uvPts.Add(bbuv.Min)
                pnts = FieldDomainPointsByUV(uvPts)
                #   
                doubleList = List[System.Double]([10.0])
                vals = FieldValues(List[ValueAtPoint]([ValueAtPoint(doubleList)]))
                sfm.UpdateSpatialFieldPrimitive(idx, pnts, vals, schemaIndex)

        except:
            error = traceback.format_exc()
            flag = False
            break
    sfm.Clear() 
    return outgpoints, error
    
view = doc.ActiveView
gpoints, error = surfaceSelection(view)
OUT = gpoints, error

le même exemple avec la fonction surfaceSelection modifiée avec une coloration de la surface sélectionnée (2 couleurs reparties depuis le point de sélection)

  
@decoCreateAvfDisplayStyle2
def surfaceSelection(view):
    """Pick points on the face with preview with AVF"""
    sfm = SpatialFieldManager.GetSpatialFieldManager(doc.ActiveView) 
    if sfm is None:
        sfm = SpatialFieldManager.CreateSpatialFieldManager(doc.ActiveView, 1)      
    sfm.Clear() 
    resultSchema = AnalysisResultSchema("Schema Name" , "Preview_Selection")
    schemaIndex = sfm.RegisterResult(resultSchema)
    
    flag = True
    error = None
    outgpoints = []
    TaskDialog.Show("Selection", "Select points on face, tap Esc to Finish")
    while flag:
        try:
            reference = uidoc.Selection.PickObject(ObjectType.Face, "Select points on face, tap Esc to Finish")
            selectface = doc.GetElement(reference).GetGeometryObjectFromReference(reference)
            outgpoints.append(reference.GlobalPoint.ToPoint() )
            interResult = selectface.Project(reference.GlobalPoint)
            # code for only paint select surface
            idx = sfm.AddSpatialFieldPrimitive(reference)
            uvPts = List[UV]()
            bbuv = selectface.GetBoundingBox()
            uvPts.Add(bbuv.Min)
            # uvPts.Add((bbuv.Min + bbuv.Max) * 0.5)
            # OR 
            uvPts.Add(interResult.UVPoint)
            uvPts.Add(bbuv.Max)
            pnts = FieldDomainPointsByUV(uvPts)
            #   
            doubleListA = List[System.Double]([10.0])
            doubleListB = List[System.Double]([0.0])
            vals = FieldValues(List[ValueAtPoint]([ValueAtPoint(doubleListA), ValueAtPoint(doubleListB), ValueAtPoint(doubleListA)]))
            sfm.UpdateSpatialFieldPrimitive(idx, pnts, vals, schemaIndex)   

        except:
            import traceback
            error = traceback.format_exc()
            flag = False
            break
    sfm.Clear() 
    return outgpoints, error


  • Exemple plus "Electrique" avec TransientDisplay

Ci-dessous un exemple en vidéo utilisant la méthode "SetForTransientDisplay" cette méthode n'est pas publique, mais elle a le mérite d'exister (Dynamo utilise cette méthode)

Ici l'affichage des géométries transitoires est utilisé pour choisir  un tracé d'une  boucle de détection incendie (prévisualisation de plusieurs choix possible).

Ensuite vient le process classique : création du système → création des fils (avec raccordement des Indicateurs d'Action) → numérotation automatique des points de détections etc...




Sources diverses sur le sujet des Géométries Transitoire

0 commentaires:

Enregistrer un commentaire