iTwin / imodel-transformer

API for exporting an iModel's parts and also importing them into another iModel
MIT License
3 stars 2 forks source link

Filtering a Subject results in an Error #147

Open ViliusRuskys opened 7 months ago

ViliusRuskys commented 7 months ago

Consider this Subject hierarchy:

root_Subject ^ Subject_A ^ Subject_B ^ PhysicalPartition_1

Lets say a user wants to filter out Subject_A and all of the data that it owns (including elements modeled by PhysicalPartition_1) One way to do it would be to add Subject_A to the excluded element list by calling excludeElement(<Subject_A id>) which effectively makes it so that Subject_A, Subject_B and PhysicalPartition_1 will be excluded as well because transformer will not step into this hierarchy branch anymore. However, the PhysicalModel_1 that is modeling PhysicalPartition_1 is not aware of this hierarchy. Models are queried and exported by their modeling hierarchy instead. In this case thePhysicalModel_1 is a sub-model of repository model (which models root_Subject). When the transformer calls this.exportSubModels(IModel.repositoryModelId); it tries to export PhysicalModel_1 and fails to do so because the Partition element was filtered out.

To workaround this we need to add the PhysicalPartition_1 id into excluded element list. This works because ExportModel will only be invoked if its partition element is not excluded. For that I wrote a ECSql query that recursively selects all Subjects in a hierarchy.

WITH RECURSIVE child_of_subject(subjectId) AS 
(
    SELECT ECInstanceId FROM bis.Subject WHERE ECInstanceId IN(<TOP SUBJECT ID>)
    UNION
    SELECT s.ECInstanceId FROM bis.Subject s INNER JOIN child_of_subject ON s.Parent.Id = child_of_subject.subjectId
)
SELECT * FROM child_of_subject

Running this will fetch all of the subjects' ids that are beneath the "TOP SUBJECT ID" (including itself). I then queried all child elements of these subjects which selected all of their child partitions and added them to excluded element list.