• Aucun résultat trouvé

Génération automatique du moteur de comparaison

4.2 Implémentation du système de comparaison structurelle

4.2.1 Génération automatique du moteur de comparaison

Pour pouvoir implémenter un système de comparaison de modèles d’ouvrages, spécifiés suivant le standard STEP, nous avons besoin d’une bibliothèque permettant de gérer des mo- dèles de données écrits en langage EXPRESS. En effet, une telle bibliothèque permet de char- ger un modèle d’ouvrage, d’en lire les propriétés, éventuellement de les éditer, et de sauver le modèle modifié. Il existe des solutions commerciales, comme ST-Developer c de STEP-Tools [STEP-Tools06b], et EXPRESS Data Manager c de EPM Technology [EPM06]. Ces outils pos- sèdent des fonctionnalités très avancées (transformation de modèles, validation de modèles) mais se révèlent aussi très onéreux. C’est pourquoi il existe une solution développée par l’Uni- versité de Manchester, sous contrat de l’Agence Spatiale Européenne (ESA) : Expressik. Il s’agit d’un produit Open-source (non encore publié à ce jour) pour générer automatiquement des

4.2. Implémentation du système de comparaison structurelle 115

bibliothèques en langage C++, capables de gérer un modèle de données EXPRESS. La biblio- thèque générée respecte la norme ISO 10303-23 (STEP-23) en termes de fonctionnalités.

Expressik Modèle de données EXPRESS Express2Cpp Bibliothèque C++ Cpp Parser ENTITY IfcStair SUBTYPE OF (IfcBuildingElement); ShapeType : IfcStairTypeEnum; END_ENTITY; class IfcStair : public IfcBuildingElement { public: IfcStairTypeEnum getShapeType(); void setShapeType (IfcStairTypeEnum value); }; Dépendance Entrée/Sortie

FIGURE4.2 :Architecture globale de l’application Expressik.

La figure 4.2 représente l’organisation globale de cette application. Cette dernière est divisée en trois paquetages distincts :

• Paquetage Parser : il transforme le fichier d’un modèle de données écrit suivant le lan- gage EXPRESS en une structure hiérarchisée en mémoire, où toutes les informations sont accessibles (y compris les commentaires du fichier EXPRESS).

• Paquetage Cpp : il transforme des concepts de programmation orientée objets en des lignes de code C++, sous la forme usuelle de fichiers d’inclusion ’.h’ et de sources ’.cpp’.

• Paquetage Express2Cpp : il s’agit du coeur de l’application. Il prend en entrée le fichier d’un modèle de données (par exemple, la description EXPRESS du modèle IFC ou IFC- Bridge), et génère les sources d’une bibliothèque C++. Pour cela, ce paquetage utilise naturellement les deux précédents.

L’approche choisie par Expressik est dite Early-binding : la bibliothèque générée n’est ca- pable de gérer qu’un seul modèle de données EXPRESS, mais toutes les méthodes de gestion sont compilées, par conséquent les performances d’accès aux données sont optimisées. Cette ap- proche s’oppose à celle dite Late-binding : la bibliothèque est générique, donc capable de gérer n’importe quel modèle de données, mais les méthodes de gestion sont créées dynamiquement, au chargement du modèle d’ouvrage. Les performances sont donc moins bonnes que dans l’ap- proche Early-binding.

Dans le cadre de nos travaux, et même au-delà, la division MODEVE du CSTB a développé une version simplifiée du paquetage Express2Cpp : Express2LightCpp. En effet, le respect de la norme ISO 10303-23 se révèle suffisamment contraignant pour nuire aux performances de la bibliothèque. En limitant la gestion des héritages aux héritages simples et en ignorant les pro- priétés calculées (attributs DERIVE, clause WHERE, etc. tous les concepts de la catégorie PC, cf. section 2.3.3 du deuxième chapitre), le paquetage Express2lightCpp obtient de meilleurs per- formances et un accès aux données simplifié. Bien qu’il ne respecte cependant pas la norme ISO 10303-23, cela n’entraîne pas de conséquences négatives pour les travaux de cette thèse.

Nous avons choisi d’implémenter le système de comparaison structurelle suivant la même dé- marche Early-binding : la bibliothèque C++ associée au comparateur est générée automatique- ment pour un modèle de données, à partir de sa description EXPRESS. Par conséquent, le code pour chaque type d’entité est compilé, les performances sont donc optimisées. La bibliothèque C++ générée devient alors compatible avec celle créée par Express2LightCpp. L’organisation globale des ces applications est représentée sur la figure 4.3.

Expressik (version CSTB) Modèle de données EXPRESS Express2LightCpp BibliothèqueC++ Cpp Parser ENTITY IfcStair SUBTYPE OF (IfcBuildingElement); ShapeType : IfcStairTypeEnum; END_ENTITY; class IfcStair : public IfcBuildingElement { public: IfcStairTypeEnum getShapeType(); void setShapeType (IfcStairTypeEnum value); }; Comparator Generator Variante 2 Fichiers squelettes (Templates) Assistant structurel Comparateur C++ Variante 1 Dépendance Entrée/Sortie

FIGURE4.3 :Architecture générale pour la génération du système de comparaison.

En entrée, le générateur a besoin de la description EXPRESS du modèle de données (évi- demment identique à celle utilisée pour générer la bibliothèque C++ qui gère les modèles d’ou- vrage), ainsi que d’assistants (qui seront détaillés à la section 4.2.3). Ensuite, cette architecture autorise deux variantes :

1. L’utilisation de fichiers squelettes (template) en entrée : ils stockent la structure statique des sources de la bibliothèque C++. Les éléments dynamiques, qui dépendent de la des- cription EXPRESS du modèle de données, sont localisés dans ces fichiers par des balises XML. La mise en oeuvre du générateur est plus rapide au début, mais cette technique se révèle moins flexible pour générer un code avec des dépendances complexes au modèle EXPRESS.

2. L’utilisation du paquetage Expressik Cpp : ce paquetage permet de générer n’importe quel algorithme en C++. La flexibilité est donc maximale mais la mise en oeuvre du générateur plus fastidieuse, car une ligne de code C++ générée peut correspondre à une dizaine de lignes de code dans le générateur.

4.2. Implémentation du système de comparaison structurelle 117

approche utilisant des fichiers squelettes, certaines limitations nous ont conduit à considérer dans un deuxième temps l’approche du paquetage Cpp, en particulier lors de l’implémentation de l’analyse sémantique, étude abordée à la section 4.3.

Variante 1 : Fichiers squelettes XML Variante 2 : Code Java avec paquetage 'Cpp'

<template> [...] <header> #ifndef <USN/>_STATE_COMPARATOR_H #define <USN/>_STATE_COMPARATOR_H #include "Comparator.h"

class <USN/>_COMPARATOR_DLL_DEF NidComparator; class <USN/>_COMPARATOR_DLL_DEF StateComparator

: public Comparator { public:

NidComparator* nidCompare;

StateComparator(unsigned int groupId); ~StateComparator() {}

<idEntities>

virtual bool visit<ECN/>(<SN/>::<ECN/>* p_<ECN/>); </idEntities>

<nidEntities>

virtual bool visit<ECN/>(<SN/>::<ECN/>* p_<ECN/>); </nidEntities> }; #endif </header> [...] </template> package comparator.statecomparator import expressik.parser.* import expressik.cpp.* [...] ClassDatatype scClass = new ClassDatatype("StateComparator"); scClass.setExported(true, dllDef);

Variable groupId = new Variable("groupId",CPP.INT); scClass.addConstructor(new Constructor(groupId)); scClass.addDestructor(new Destructor());

for(int i=0;i < idEntities.length; i++) { Function visit =

new Function("visit" + idEntities[i].getName()); visit.setDatatype(CPP.BOOL);

visit.setModifier(Modifier.VIRTUAL); Variable param =

new Variable("p_" + idEntities[i].getName(), idEntities[i].getDatatype()); visit.addParameter(param); scClass.addFunction(visit); [...] } [...]

FIGURE4.4 :Comparaison de deux méthodes pour la structure du comparateur structurel

Après avoir défini la façon d’implémenter le système de comparaison, il convient d’étudier le contenu de cette implémentation, les différentes classes du système, la communisation entre elles, ainsi que leurs méthodes.