|
|
| Emplacement du menu |
|---|
| Gestion → Outils de rapport → Rapport BIM |
| Ateliers |
| BIM |
| Raccourci par défaut |
| Aucun |
| Introduit dans la version |
| 1.2 |
| Voir aussi |
| Aucun |
Le BIM Rapport est un outil permettant de générer des nomenclatures et des rapports de données à partir d'un modèle FreeCAD. Il utilise un langage de requête de type SQL pour sélectionner, filtrer et agréger des données, offrant ainsi une alternative déclarative aux autres outils de planification. Au final, il permet aux utilisateurs de créer et de remplir automatiquement une feuille de calcul avec les données recueillies à partir du modèle.
Vous pourriez utiliser l'outil BIM Rapport lorsque vous devez effectuer les opérations suivantes :
Le Rapport BIM se compose de trois éléments principaux : l'objet Report dans l'arborescence, la feuille de calcul cible pour les résultats et le panneau des tâches où vous configurez le rapport.
Lorsque vous créez un nouveau rapport, deux nouveaux objets apparaissent dans l'arborescence : l'objet Report, qui stocke tous vos paramètres, et la feuille de calcul ReportResult qui lui est associée.
Un double-clic sur l'objet DonnéesReport ouvre le panneau des tâches, qui est l'espace de travail principal pour la modification de votre rapport. Le panneau est divisé en deux zones principales : Rapport des requêtes et Éditeur de requêtes.

Cette section est toujours visible en haut du panneau des tâches et vous donne un résumé de toutes les requêtes (ou « instructions ») qui composent votre rapport.
La principale fonction est un tableau répertoriant chaque requête. À partir de là, vous pouvez voir et modifier directement la Description et activer/désactiver les options clés pour chaque requête :
Étiquette, Surface) comme ligne d'en-tête pour les résultats de cette requête.Double-cliquez sur une ligne de requête pour ouvrir la requête et la modifier. Appuyez sur F2 sur une ligne de requête pour modifier la description de la requête sans charger l'éditeur complet.
Sous le tableau se trouvent les boutons Ajouter,
Supprimer,
Dupliquer ou
Modifier la requête sélectionnée.
Enfin, le menu déroulant Modèles de rapport vous permet de charger des rapports complets et préconfigurés, tels que Nomenclature des pièces et surfaces.
Cette section apparaît au bas du panneau des tâches lorsque vous sélectionnez une requête et cliquez sur Modifier la sélection. C'est ici que vous écrivez et configurez une requête SQL.

Étiquette, Surface).Le bouton Enregistrer enregistre les modifications apportées à la requête chargée. Lorsque la case
Enregistrer et suivant est cochée et que le bouton
Enregistrer est enfoncé, en plus de l'opération d'enregistrement, une nouvelle requête est créée pour une édition plus fluide. Le bouton ❌ Annuler ferme l'éditeur de requêtes sans enregistrer les modifications apportées.
Ce petit tutoriel vous guide dans la création d'une nomenclature complète pour une pièce, depuis une simple liste jusqu'à un rapport en plusieurs parties avec des totaux calculés.
Tout d'abord, créons une liste simple de tous les espaces et de leurs superficies.
Liste des pièces.Space et les trie par ordre alphabétique.SELECT Label, Area FROM document WHERE IfcType = 'Space' ORDER BY Label ASC
Maintenant, ajoutons une deuxième requête pour calculer la superficie totale.
Surface totale.SELECT 'Total Usable Area', SUM(Area) FROM document WHERE IfcType = 'Space'
Le pipelining vous permet d'enchaîner des requêtes, où le résultat d'une requête devient l'entrée de la suivante. Cela est essentiel pour les sélections hiérarchiques complexes, comme lors de l'utilisation de la fonction CHILDREN(). Comme il n'est pas récursif, il ne trouve que les descendants directs.
Par exemple, pour trouver toutes les portes situées au « rez-de-chaussée », vous devez effectuer une requête en plusieurs étapes, car les portes sont des enfants des murs, qui sont eux-mêmes des enfants du sol.
Find Ground Floor.SELECT * FROM document WHERE Label = 'Ground Floor'
Find Walls on Floor.SELECT * FROM CHILDREN(SELECT * FROM document) WHERE IfcType = 'Wall'
Find Doors in Walls.SELECT Label, Width, Height FROM CHILDREN(SELECT * FROM document) WHERE IfcType = 'Door'
Comprendre le résultat : la feuille de calcul finale n'affichera que les résultats de la dernière requête du pipeline (la liste des portes). Les deux premières requêtes agissent comme des filtres intermédiaires dont les résultats sont transmis en mémoire mais ne sont pas affichés dans la feuille de calcul, ce qui vous permet d'obtenir un rapport final clair et précis.
Cette section fournit une référence détaillée pour le dialecte SQL utilisé par l'outil BIM Rapport.
Remarque: la référence la plus récente pour toutes les clauses et fonctions est toujours disponible dans l'interface utilisateur en cliquant sur le bouton Aide dans l'éditeur du panneau des tâches du rapport.
SELECT : spécifie les colonnes de données à renvoyer. Vous pouvez utiliser * pour sélectionner un identifiant par défaut pour tous les objets.FROM : spécifie la source des données. Dans une seule requête, il s'agit toujours de document. Dans un pipeline, document est un espace réservé pour les données de l'étape précédente. Vous pouvez également utiliser la fonction CHILDREN().WHERE : filtre les objets en fonction de conditions.GROUP BY : regroupe les lignes qui ont les mêmes valeurs en lignes récapitulatives, généralement utilisées avec des fonctions d'agrégation.ORDER BY : trie les résultats finaux. Peut être suivi de ASC (ascendant, par défaut) ou DESC (descendant). Prend en charge le tri par plusieurs colonnes.AS : crée un alias (un nom personnalisé) pour une colonne dans la clause SELECT, par exemple SELECT Area AS "My Area".
Le dialecte a des règles spécifiques pour l'utilisation des expressions (comme les fonctions ou l'arithmétique) dans les clauses GROUP BY et ORDER BY.
GROUP BY : lorsque vous effectuez un regroupement par expression, vous devez répéter l'expression entière dans la clause GROUP BY. L'utilisation d'un alias provenant de la liste SELECT n'est pas prise en charge.
SELECT TYPE(*) … GROUP BY TYPE(*)
SELECT TYPE(*) AS BimType … GROUP BY BimType
ORDER BY : à l'inverse, le tri par expression brute n'est pas pris en charge. Pour trier par le résultat d'une expression, vous devez d'abord l'inclure dans la liste SELECT avec un alias AS, puis faire référence à cet alias dans la clause ORDER BY.
SELECT Label, LOWER(Label) AS sort_key … ORDER BY sort_key
SELECT Label … ORDER BY LOWER(Label)
Le dialecte comprend une bibliothèque de fonctions intégrées pour la manipulation et l'analyse des données.
| Catégorie | Fonction | Description |
|---|---|---|
| Agrégat | COUNT(property|*)
|
Compte le nombre d'objets. COUNT(*) compte toutes les lignes ; COUNT(property) compte les lignes où la propriété spécifiée n'est pas NULL.
|
SUM(propriété)
|
Calcule la somme d'une propriété numérique. | |
MIN(propriété)
|
Trouve la valeur minimale d'une propriété numérique. | |
MAX(propriété)
|
Trouve la valeur maximale d'une propriété numérique. | |
| Hiérarchique | PARENT(*)
|
Renvoie le parent architecturalement significatif d'un objet (par exemple, le mur dans lequel se trouve une fenêtre), en ignorant de manière transparente les groupes génériques. |
CHILDREN(sous-requête)
|
Fonction utilisée dans la clause FROM. Renvoie tous les enfants des objets trouvés par la sous-requête, en résolvant à la fois les relations de contenance (.Group) et d'hébergement (.Hosts). Cette fonction n'est pas récursive. Pour trouver les petits-enfants ou les descendants plus éloignés, enchaînez plusieurs étapes CHILDREN() à l'aide d'un pipeline.
| |
CHILDREN_RECURSIVE(sous-requête, max_depth=15)
|
Une fonction utilisée dans la clause FROM. Renvoie tous les objets descendants des résultats de la sous-requête en parcourant de manière récursive la hiérarchie. Elle ignore de manière transparente les groupes génériques. Une option max_depth peut être spécifiée.
| |
| Utilitaire | TYPE(*)
|
Renvoie le type de l'objet visible par l'utilisateur, tel que déterminé par son proxy (par exemple, Wall, Space, Part::Box).
|
CONVERT(quantity, 'unit')
|
Convertit un objet Quantité FreeCAD en une nouvelle unité et le renvoie sous forme de nombre brut. Exemple : CONVERT(Area, 'm^2').
| |
| Chaîne | LOWER(propriété)
|
Convertit une propriété texte en minuscules. |
UPPER(propriété)
|
Convertit une propriété texte en majuscules. | |
CONCAT(val1, val2, …)
|
Concatène plusieurs valeurs et propriétés texte en une seule chaîne. |
Vous pouvez accéder à n'importe quelle propriété d'un objet, y compris aux structures de données imbriquées.
Label, IfcTypeShape.Volume, Placement.Base.zPARENT().
PARENT(*).Label, PARENT(*).PARENT(*).Height
| Type | Opérateurs | Description |
|---|---|---|
| Comparaison | =, !=, >, <, >=, <=
|
Opérateurs de comparaison standard. |
LIKE
|
Correspondance de motifs sans distinction de casse. Utilisez % pour plusieurs caractères et _ pour un seul caractère.
| |
IS NULL, IS NOT NULL
|
Vérifie si une propriété a une valeur. | |
IN (valeur1, valeur2, …)
|
Vérifie si la valeur d'une propriété figure dans une liste donnée de littéraux. | |
| Logique | AND, OR
|
Utilisé dans la clause WHERE pour combiner plusieurs conditions.
|
| Arithmétique | +, -, *, /
|
Effectue des calculs sur des propriétés numériques. Respecte la priorité standard des opérateurs ; utilisez () pour la remplacer.
|
') et doubles (") peuvent tous deux être utilisés pour les littéraux textuels (chaînes de caractères). Par exemple, WHERE Label = 'Wall' et WHERE Label = "Wall" sont équivalents.--, et les commentaires sur plusieurs lignes, qui sont encadrés par /* … */.
Cette section fournit une série de requêtes pratiques que vous pouvez utiliser directement ou modifier pour vos rapports.
Sélection de tous les éléments structurels (colonnes et poutres) :
SELECT Label, IfcType
FROM document
WHERE IfcType IN ('Column', 'Beam')
ORDER BY IfcType, Label
Sélection de tous les murs dont le nom contient « Exterior » :
SELECT Label, Length, Height
FROM document
WHERE IfcType = 'Wall' AND Label LIKE '%Exterior%'
Compter tous les objets BIM, regroupés par type :
SELECT IfcType, COUNT(*)
FROM document
WHERE IfcType IS NOT NULL
GROUP BY IfcType
ORDER BY IfcType ASC
Obtenir un métré complet pour tous les murs :
Cette requête calcule le nombre total de murs, leur longueur combinée, ainsi que les hauteurs minimale et maximale des murs.
SELECT
COUNT(*) AS "Total Count",
SUM(Length) AS "Total Length (mm)",
MIN(Height) AS "Min Height (mm)",
MAX(Height) AS "Max Height (mm)"
FROM document
WHERE IfcType = 'Wall'
Liste de tous les objets situés directement au « rez-de-chaussée » :
Cela utilise la fonction CHILDREN() pour interroger le contenu d'un objet conteneur spécifique.
SELECT Label, IfcType
FROM CHILDREN(SELECT * FROM document WHERE Label = 'Ground Floor')
ORDER BY IfcType
Liste toutes les portes et le mur spécifique dans lequel elles se trouvent :
Cela utilise la fonction PARENT() pour trouver l'hôte de chaque porte.
SELECT
Label AS "Door_Name",
PARENT(*).Label AS "Host_Wall_Name"
FROM document
WHERE IfcType = 'Door'
ORDER BY "Host_Wall_Name"
Trouve toutes les fenêtres du « rez-de-chaussée » (en vérifiant le grand-parent) :
Cette requête recherche les fenêtres, vérifie leur parent (le mur), puis vérifie le parent de ce mur (le sol).
SELECT Label
FROM document
WHERE IfcType = 'Window' AND PARENT(*).PARENT(*).Label = 'Ground Floor'
Générer une nomenclature complète des pièces et des espaces :
Cette requête génère une liste formatée de tous les espaces, regroupés par étage auquel ils appartiennent, avec leur superficie convertie en mètres carrés.
SELECT
PARENT(*).Label AS "Floor",
Label AS "Room Name",
CONVERT(Area, 'm^2') AS "Area (m²)"
FROM document
WHERE IfcType = 'Space'
ORDER BY "Floor", "Room Name"
Lorsque vous sélectionnez une propriété qui comporte des unités (une « Quantité »), telle que « Longueur » ou « Surface », le moteur du rapport BIM renvoie la valeur numérique brute de cette propriété telle qu'elle est stockée en interne dans le document FreeCAD. Les unités internes de FreeCAD sont toujours basées sur les millimètres (mm).
Cela signifie que le résultat par défaut sera en mm pour la longueur, mm² pour la surface et mm³ pour le volume, quels que soient votre schéma d'unités actuel ou vos préférences utilisateur. L'en-tête de colonne généré automatiquement reflétera correctement cette unité interne.
Exemple : comportement par défaut
Si vous exécutez cette requête simple sur un espace de 1 mètre sur 1 mètre :
SELECT Label, Area FROM document WHERE IfcType = 'Space'
La feuille de calcul obtenue affichera :
Surface (mm²)1000000,0<span id="Using_CONVERT()">
CONVERT()Pour obtenir les résultats dans les unités souhaitées, vous pouvez utiliser la fonction CONVERT(), qui permet de contrôler explicitement le résultat. Pour obtenir la superficie en mètres carrés, modifiez la requête comme suit :
SELECT Label, CONVERT(Area, 'm^2') AS "Area (m²)" FROM document WHERE IfcType = 'Space'
Cette requête produit désormais le résultat dans l'unité souhaitée :
Superficie (m²)1,0L'utilisation de CONVERT() garantit que le résultat de votre rapport est sans ambiguïté et que tous les calculs que vous effectuez dans la requête (par exemple, SUM(CONVERT(Area, 'm^2'))) sont mathématiquement corrects.
Un objet Arch Report expose les propriétés suivantes à l'utilisateur.
Report
SUM(Length) dans le rapport sera automatiquement mise à jour après le recalcul. Sur les modèles très volumineux, il peut être souhaitable de désactiver cette option pour des raisons de performances lors de modifications importantes. Si AutoUpdate est défini sur False, le rapport peut être mis à jour manuellement à tout moment en cliquant avec le bouton droit sur l'objet Report dans l'arborescence et en sélectionnant Recalculer, ou en appuyant sur le bouton global Recalculer.
Le moteur du rapport BIM est entièrement accessible via Python, ce qui vous permet d'intégrer ses fonctions avancées de requête dans vos propres scripts et automatisations.
Il s'agit de la fonction principale permettant d'exécuter une requête SQL simple et directe. Elle prend une chaîne de requête en entrée et renvoie une liste des objets DocumentObjects de FreeCAD qui correspondent à la requête. Si la requête n'est pas valide ou ne trouve aucun objet, elle renvoie une liste vide et affiche une erreur dans la console.
Exemple : obtenir tous les objets Wall dont le nom contient « Exterior ».
import FreeCAD
import Arch
# This query selects all Wall objects whose Label contains the substring "Exterior"
query = "SELECT * FROM document WHERE IfcType = 'Wall' AND Label LIKE '%Exterior%'"
exterior_walls = Arch.selectObjects(query)
# The result is a list of FreeCAD objects
FreeCAD.Console.PrintMessage(f"Found {len(exterior_walls)} exterior walls.\n")
for wall in exterior_walls:
FreeCAD.Console.PrintMessage(f"- {wall.Label} (Length: {wall.Length})\n")
Pour des sélections plus complexes, en plusieurs étapes, vous pouvez utiliser cette fonction pour exécuter un pipeline. Elle prend une liste d'objets ArchSql.ReportStatement et renvoie la liste finale des objets DocumentObjects de FreeCAD résultant du pipeline complet.
Cela équivaut, au niveau du programme, à cocher la case "Utiliser en mode de pipeline" dans l'interface utilisateur.
Exemple : trouver toutes les portes au « rez-de-chaussée »
Il s'agit d'un problème hiérarchique classique qui nécessite plusieurs étapes. L'objectif est de trouver les « petits-enfants » (les portes) d'un « grand-parent » (l'étage). Comme la fonction CHILDREN() n'est pas récursive, nous devons enchaîner plusieurs étapes dans un pipeline.
'Ground Floor'.import FreeCAD
import Arch
import ArchSql
# Step 1: Define the pipeline statements.
# The ReportStatement class must be imported from the ArchSql module.
# Statement 1: Find the parent 'Ground Floor' object.
# Output of this step: [Ground_Floor_Object]
stmt1 = ArchSql.ReportStatement(
query_string="SELECT * FROM document WHERE Label = 'Ground Floor'"
)
# Statement 2: Find the direct children of the floor (walls, spaces, etc.).
# is_pipelined=True tells this to run on the output of stmt1.
# Output of this step: [Wall_Object_1, Wall_Object_2, Space_Object_1, …]
stmt2 = ArchSql.ReportStatement(
query_string="SELECT * FROM CHILDREN(SELECT * FROM document)",
is_pipelined=True
)
# Statement 3: Find the children of the objects from the previous step.
# This finds the doors and windows hosted by the walls.
# Output of this step: [Door_Object, Window_Object_1, …]
stmt3 = ArchSql.ReportStatement(
query_string="SELECT * FROM CHILDREN(SELECT * FROM document)",
is_pipelined=True
)
# Statement 4: Filter the final list to keep only the doors.
# This runs on the output of stmt3.
# Final Output: [Door_Object]
stmt4 = ArchSql.ReportStatement(
query_string="SELECT * FROM document WHERE IfcType = 'Door'",
is_pipelined=True
)
# Step 2: Execute the full pipeline.
pipeline_statements = [stmt1, stmt2, stmt3, stmt4]
doors_on_floor = Arch.selectObjectsFromPipeline(pipeline_statements)
# The result is the final list of door objects.
FreeCAD.Console.PrintMessage(f"Found {len(doors_on_floor)} doors on the ground floor.\n")
for door in doors_on_floor:
FreeCAD.Console.PrintMessage(f"- {door.Label}\n")
Pour le débogage, la création de scripts ou le partage de votre travail avec d'autres personnes, vous pouvez obtenir un résumé complet et lisible de la configuration d'un rapport directement à partir de la console Python.
La logique personnalisée et le contenu détaillé d'un rapport BIM sont stockés dans son objet proxy. L'accès à l'attribut .Proxy permet d'obtenir une impression complète de toutes les requêtes et de leurs requêtes SQL. Il s'agit d'un moyen pratique de copier l'intégralité de la définition de votre rapport dans le presse-papiers afin de la partager sur un forum ou dans un rapport de bogue.
Mode d'emploi :
obj.print(obj.Proxy)
Exemple de résultat :
>>> print(obj.Proxy)
BIM Report: 'My Door Schedule' (2 statements)
--- Statement [1]: Find All Walls on Ground Floor ---
SELECT *
FROM CHILDREN(SELECT * FROM document WHERE Label = 'Ground Floor')
WHERE IfcType = 'Wall'
--- Statement [2]: Final Door Schedule (Pipelined, Header) ---
SELECT
Tag,
COUNT(*) AS "Count"
FROM
document
GROUP BY
Tag