22 déc. 2025

[Dynamo += Python] des « BoundingBox » alignées

 


Parmi les fonctions les plus cool de Dynamo ... ByMinimum.Volume.


#DynamoBIM #Python #RevitAPI  #BoundingBox    #AutodeskExpertElite #AutodeskCommunity 

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

Dans l'écosystème des API de géométrie, la gestion des boîtes englobantes se limite souvent aux axes X, Y et Z du projet. Cependant, pour analyser des objets avec une rotation ou des géométries complexes, le fonction ByMinimum.Volume devient un outil formidable.

Un des avantage de cette fonction c'est que l'objet retourné de type Autodesk.DesignScript.Geometry.BoundingBox contient les données sur la transformation de celle ci.

Nous allons voir comment exploiter la donnée de transformation de ce nœud, à la fois en DesignScript pour reconstruire des axes géométriques et en Python pour automatiser des boîtes de coupe parfaitement alignées.

  • Exemple 1

Exemple en DesignScript pour retrouver les coordonnées d'une "BoundingBox" alignée.





cs = bb.ContextCoordinateSystem;
pt1_before_cs = bb.MinPoint.Transform(cs.Inverse());
pt3_before_cs = bb.MaxPoint.Transform(cs.Inverse());
pt2_before_cs = Point.ByCoordinates(pt1_before_cs.X, pt3_before_cs.Y, pt1_before_cs.Z);
pt4_before_cs = Point.ByCoordinates(pt3_before_cs.X, pt1_before_cs.Y, pt1_before_cs.Z);
// transformed points
pt1 = bb.MinPoint;
pt2 = pt2_before_cs.Transform(cs);
pt3 = Point.ByCoordinates(bb.MaxPoint.X, bb.MaxPoint.Y, bb.MinPoint.Z);
pt4 = pt4_before_cs.Transform(cs);
// out list point
bottom_points = [pt1, pt2, pt3, pt4];

En faisant la moyenne des points extrêmes, nous pouvons ainsi retrouver la ligne d'axe.

Exemple : un mur générique issu d'un IFC

cs = bb.ContextCoordinateSystem;
pt1_before_cs = bb.MinPoint.Transform(cs.Inverse());
pt3_before_cs = bb.MaxPoint.Transform(cs.Inverse());
pt2_before_cs = Autodesk.DesignScript.Geometry.Point.ByCoordinates(
						pt1_before_cs.X, pt3_before_cs.Y, pt1_before_cs.Z
						);
pt4_before_cs = Autodesk.DesignScript.Geometry.Point.ByCoordinates(
						pt3_before_cs.X, pt1_before_cs.Y, pt1_before_cs.Z
						);
// transformed points
pt1 = bb.MinPoint;
pt2 = pt2_before_cs.Transform(cs);
pt3 = Autodesk.DesignScript.Geometry.Point.ByCoordinates(
						bb.MaxPoint.X, bb.MaxPoint.Y, bb.MinPoint.Z
						);
pt4 = pt4_before_cs.Transform(cs);
// out list point
bottom_points = [pt1, pt2, pt3, pt4];
// axis line
ptmid1 = Autodesk.DesignScript.Geometry.Point.ByCoordinates(
						(pt1.X + pt2.X) / 2,
						(pt1.Y + pt2.Y) / 2,
						pt1.Z
						);
ptmid2 = Autodesk.DesignScript.Geometry.Point.ByCoordinates(
						(pt3.X + pt4.X) / 2,
						(pt3.Y + pt4.Y) / 2,
						pt1.Z
						);
axis_line = Autodesk.DesignScript.Geometry.Line.ByStartPointEndPoint(
						ptmid1,
						ptmid2
						);




  • Exemple 2 

Nous pouvons aussi l'utiliser au sein d'un nœud Python ou ZeroTouch (C#).

Dans cet exemple nous faisons une boite de coupe alignée sur un élément (chemin de câble) en mappant les vecteurs de transformation Dynamo vers ceux de la BoundingBox de l'API Revit.




code Python

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

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument

def set_SectionBox(view3d, ds_bbx):
    margin = XYZ(0.05, 0.05, 0.05)
    # convert bbx
    tf_view = view3d.CropBox.Transform
    cs = ds_bbx.ContextCoordinateSystem
    tf = Transform.Identity
    tf.BasisX  = cs.XAxis.ToXyz()
    tf.BasisY  = cs.YAxis.ToXyz()
    tf.BasisZ  = XYZ.BasisZ #coord_system.ZAxis.ToXyz()
    tf.Origin  = cs.Origin.ToXyz()
    ptmax_before_cs = ds_bbx.MaxPoint.Transform(cs.Inverse())
    ptmin_before_cs = ds_bbx.MinPoint.Transform(cs.Inverse())
    newbox = BoundingBoxXYZ()
    newbox.Max = ptmax_before_cs.ToXyz().Add(margin)
    newbox.Min = ptmin_before_cs.ToXyz().Subtract(margin)
    newbox.Transform = tf
    view3d.SetSectionBox(newbox)

views = UnwrapElement(IN[0])
ds_bboxes = IN[1]

TransactionManager.Instance.EnsureInTransaction(doc)
if isinstance(IN[0], list):
    if isinstance(IN[1], list): OUT = [set_SectionBox(x, y) for x, y in zip(views, ds_bboxes)]
    else: OUT = [set_SectionBox(x, ds_bboxes) for x in views]
else:
    if isinstance(IN[1], list): OUT = set_SectionBox(views, ds_bboxes[0])
    else: OUT = set_SectionBox(views, ds_bboxes)
TransactionManager.Instance.TransactionTaskDone()

OUT = views


Ressources 





🎁🎄❄️ Bonnes fêtes de fin d’année à tous ! ❄️🎄🎁✨



« Moins les gens ont d'idées à exprimer, plus ils parlent fort. »
François Mauriac

0 commentaires:

Enregistrer un commentaire