1 /** \file inverse_attr2.cc
2 ** 1-Jul-2012
3 ** Test inverse attributes; uses a tiny schema similar to a subset of IFC2x3
4 **
5 */
6 #include <sc_cf.h>
7 extern void SchemaInit( class Registry & );
8 #include "sc_version_string.h"
9 #include <STEPfile.h>
10 #include <sdai.h>
11 #include <STEPattribute.h>
12 #include <ExpDict.h>
13 #include <Registry.h>
14 #include <errordesc.h>
15 #include <algorithm>
16 #include <string>
17 #ifdef HAVE_UNISTD_H
18 # include <unistd.h>
19 #endif
20 #include <sc_getopt.h>
21 #include "schema.h"
22 
23 ///second way of finding inverse attrs
findInverseAttrs2(InverseAItr iai,InstMgr & instList,Registry & reg)24 bool findInverseAttrs2( InverseAItr iai, InstMgr & instList, Registry & reg ) {
25     const Inverse_attribute * ia;
26     int j = 0;
27     while( 0 != ( ia = iai.NextInverse_attribute() ) ) {
28         cout << "inverse attr #" << j << ", name: " << ia->Name() << ", inverted attr id: " << ia->inverted_attr_id_()
29              << ", from entity: " << ia->inverted_entity_id_() << endl;
30 
31         //now find the entity containing the attribute in question
32         const EntityDescriptor * inv_ed = reg.FindEntity( ia->inverted_entity_id_() );
33         AttrDescItr attr_desc_itr( inv_ed->ExplicitAttr() );
34         const AttrDescriptor * attrDesc;
35         int k = 0;
36         while( 0 != ( attrDesc = attr_desc_itr.NextAttrDesc() ) ) {
37             if( !strcmp( ia->inverted_attr_id_(), attrDesc->Name() ) ) {
38                 cout << "attribute '" << attrDesc->Name() << "' is attribute #" << k
39                      << " of '" << inv_ed->Name() << "'." << endl;
40 
41                 // now go through the instList looking at each instance of
42                 // entity type 'inv_ed', looking for references to 'ed' in the
43                 // attribute described by 'attrDesc'
44                 int l = 0;
45                 SdaiReldefinesbytype * inst;
46                 while( 0 != ( inst = ( SdaiReldefinesbytype * ) instList.GetApplication_instance( inv_ed->Name(), l ) ) ) {
47                     int i = inst->StepFileId();
48                     if( i < l ) {
49                         break;
50                     }
51                     STEPattributeList attrlist = inst->attributes;
52                     if( attrlist.list_length() < k + 1 ) {
53                         return false;
54                     }
55                     STEPattribute sa = attrlist[k];
56                     if( sa.getADesc()->DomainType()->Type() == SET_TYPE ) {
57                         STEPaggregate * aggr = sa.Aggregate();
58                         if( !aggr || aggr->is_null() != 0 ) {
59                             cout << "findInverseAttrs2 FAILED" << endl;
60                             return false;
61                         }
62                     } else {
63                         //something is wrong - it should be an aggregate (specifically, a SET)
64                         return false;
65                     }
66                     l = i;
67                 }
68             }
69             k++;
70         }
71         j++;
72     }
73     return( j != 0 );
74 }
75 
76 
main(int argc,char * argv[])77 int main( int argc, char * argv[] ) {
78     Registry  registry( SchemaInit );
79     InstMgr   instance_list;
80     STEPfile  sfile( registry, instance_list, "", false );
81     bool inverseAttrsFound = false;
82     if( argc != 2 ) {
83         exit( EXIT_FAILURE );
84     }
85     sfile.ReadExchangeFile( argv[1] );
86 
87     if( sfile.Error().severity() <= SEVERITY_INCOMPLETE ) {
88         sfile.Error().PrintContents( cout );
89         exit( EXIT_FAILURE );
90     }
91     //find inverse attribute descriptors
92     //first, find inverse attrs unique to this entity (i.e. not inherited)
93     const EntityDescriptor * ed = registry.FindEntity( "window" );
94     InverseAItr iaIter( &( ed->InverseAttr() ) ); //iterator for inverse attributes
95     if( findInverseAttrs2( iaIter, instance_list, registry ) ) {
96         inverseAttrsFound = true;
97     }
98     //now, find inherited inverse attrs
99     EntityDescItr edi( ed->GetSupertypes() );
100     const EntityDescriptor * super;
101     while( 0 != ( super = edi.NextEntityDesc() ) ) {
102         cout << "supertype " << super->Name() << endl;
103         InverseAItr superIaIter( &( super->InverseAttr() ) );
104         if( findInverseAttrs2( superIaIter, instance_list, registry ) ) {
105             inverseAttrsFound = true;
106         }
107     }
108     if( !inverseAttrsFound ) {
109         cout << "no inverse attrs found" << endl;
110         exit( EXIT_FAILURE );
111     }
112     exit( EXIT_SUCCESS );
113 }
114 
115