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