mttFetchBondgraph.m 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. function model = mttFetchBondgraph(filename)
  2. mttAssert(mttFileExists(filename),...
  3. ['File "',filename,'" not found']) ;
  4. mttNotify([' ...processing ',filename]) ;
  5. mttWriteNewLine ;
  6. model.bondgraph = filename ;
  7. content = mttReadFile(filename) ;
  8. L = length(content) ;
  9. N = 1 ;
  10. processing = (N<=L) ;
  11. while processing
  12. jump = 1 ;
  13. line = mttClipText(content{N}) ;
  14. if ~isempty(line)
  15. no_string_terminator = isempty(findstr('\001',line)) ;
  16. if no_string_terminator
  17. if mttIsNumericText(line)
  18. numbers = round(str2num(line)) ; % only interested in integer values
  19. if numbers(1)==2 % ... line definition
  20. forward_arrow = numbers(14)~=0 ;
  21. reverse_arrow = numbers(15)~=0 ;
  22. arrow = (forward_arrow | reverse_arrow) ;
  23. depth = numbers(7) ;
  24. is_visible = rem(depth,10)==0 ;
  25. if is_visible
  26. mttAssert(~arrow,...
  27. ['Line ',num2str(N),': Arrows are not recognised in bond graphs']) ;
  28. number_of_points = numbers(16) ;
  29. coordinate_string = [] ;
  30. M = 0 ;
  31. matching = 1 ;
  32. while matching
  33. M = M + 1 ;
  34. if isempty(coordinate_string)
  35. coordinate_string = content{N+M} ;
  36. else
  37. coordinate_string = [coordinate_string,' ',content{N+M}] ;
  38. end
  39. mttAssert(mttIsNumericText(coordinate_string),...
  40. ['Line ',num2str(N+M),': Coordinates not recognised']) ;
  41. coordinates = str2num(coordinate_string) ;
  42. matching = length(coordinates)<2*number_of_points ;
  43. end
  44. mttAssert(length(coordinates)==2*number_of_points,...
  45. ['Line ',num2str(N+1),': Wrong number of coordinates']) ;
  46. jump = jump + M ;
  47. if number_of_points==2
  48. model = create_line(model,coordinates) ;
  49. elseif number_of_points>2
  50. model = create_bond(model,coordinates) ;
  51. end
  52. else
  53. jump = jump + forward_arrow + reverse_arrow ;
  54. end
  55. end
  56. end
  57. else
  58. [last_word,first_part] = mttDetachText(line,' ') ;
  59. if mttIsNumericText(first_part)
  60. numbers = round(str2num(first_part)) ; % only interested in integer values
  61. if numbers(1)==4 % ... text definition
  62. depth = numbers(4) ;
  63. is_visible = rem(depth,10)==0 ;
  64. if is_visible
  65. coordinates = numbers(12:13) ;
  66. text = mttCompressText(mttCutText(last_word,'\001')) ;
  67. identifier = mttCutText(text,'[') ;
  68. qualifier = mttExtractText(text,'[',']') ;
  69. name.label = [] ;
  70. name.domain = [] ;
  71. name.domain_item = [] ;
  72. name.class = [] ;
  73. name.object = [] ;
  74. if isempty(identifier)
  75. name.label = qualifier ;
  76. model = create_label(model,name,coordinates) ;
  77. else
  78. [name.domain,name.domain_item] = mttCutText(qualifier,'::') ;
  79. [name.class,name.object] = mttCutText(identifier,':') ;
  80. model = create_object(model,name,coordinates) ;
  81. end
  82. end
  83. end
  84. end
  85. end
  86. end
  87. N = N + jump ;
  88. processing = (N<=L) ;
  89. end
  90. model = incorporate_anonymous_objects(model) ;
  91. model = identify_causal_assignments(model) ;
  92. model = identify_object_binding(model) ;
  93. model = identify_object_interfaces(model) ;
  94. model = associate_external_domains(model) ;
  95. model = tidy_up(model) ;
  96. function model = create_line(model,coordinates)
  97. next = 1 + mttGetFieldLength(model,'line') ;
  98. model.line(next).xy1 = coordinates(1:2) ;
  99. model.line(next).xy2 = coordinates(3:4) ;
  100. model.line(next).mid = (coordinates(1:2)+coordinates(3:4))/2 ;
  101. function model = create_bond(model,coordinates)
  102. next = 1 + mttGetFieldLength(model,'bond') ;
  103. N = length(coordinates) ;
  104. q1 = coordinates(N-1:N) ; p1 = coordinates(1:2) ;
  105. p2 = coordinates(3:4) ; q2 = coordinates(N-3:N-2) ;
  106. p3 = coordinates(5:6) ; q3 = coordinates(N-5:N-4) ;
  107. ps = norm(p2-p1) ; qs = norm(q2-q1) ;
  108. orientation = sign(ps-qs) ;
  109. switch orientation
  110. case 1, % harpoon points forward
  111. xy1 = p1 ; xy2 = q2 ; v1 = p2-p1 ; v2 = q2-q3 ; harpoon = q1-q2 ;
  112. case -1, % harpoon points backward
  113. xy1 = p2 ; xy2 = q1 ; v1 = q2-q1 ; v2 = p2-p3 ; harpoon = p1-p2 ;
  114. end
  115. harpoon_side = sign_cross_product(v2,harpoon) ;
  116. mttAssert(~(orientation==0 | harpoon_side==0),...
  117. ['Ambiguous bond orientation between[',num2str(xy1),'] and [',num2str(xy2),']']) ;
  118. model.bond(next).xy1 = xy1 ;
  119. model.bond(next).xy2 = xy2 ;
  120. model.bond(next).v1 = v1 ;
  121. model.bond(next).v2 = v2 ;
  122. model.bond(next).harpoon = harpoon ;
  123. model.bond(next).harpoon_side = harpoon_side ;
  124. model.bond(next).from.obj = [] ;
  125. model.bond(next).from.interface = [] ;
  126. model.bond(next).to.obj = [] ;
  127. model.bond(next).to.interface = [] ;
  128. model.bond(next).flow = [] ;
  129. model.bond(next).effort = [] ;
  130. model.bond(next).unicausal = [] ;
  131. model.bond(next).domain = [] ;
  132. model.bond(next).domain_item = [] ;
  133. function model = create_label(model,name,coordinates)
  134. inner_name = mttExtractText(name.label,'<','>') ;
  135. if isempty(inner_name)
  136. label_name = name.label ;
  137. is_inline = 0 ;
  138. else
  139. label_name = inner_name ;
  140. is_inline = 1 ;
  141. end
  142. mttValidateName(label_name) ;
  143. next = 1 + mttGetFieldLength(model,'label') ;
  144. model.label(next).name = label_name ;
  145. model.label(next).is_inline = is_inline ;
  146. model.label(next).xy = coordinates ;
  147. function model = create_object(model,name,coordinates)
  148. global mtt_environment
  149. domain_names = mttGetFieldNames(mtt_environment,'domain') ;
  150. is_anonymous = 0 ;
  151. if isempty(name.object)
  152. switch name.class
  153. case {'0','1'},
  154. is_anonymous = 1 ;
  155. case 'SS',
  156. mttAssert(~isempty(name.object),...
  157. 'Anonymous "SS" object') ;
  158. otherwise,
  159. name.object = name.class ;
  160. end
  161. end
  162. if is_anonymous
  163. next = 1 + mttGetFieldLength(model,'anonymous') ;
  164. model.anonymous(next).class = name.class ;
  165. model.anonymous(next).xy = coordinates ;
  166. else
  167. object_names = mttGetFieldNames(model,'obj') ;
  168. if ~isempty(object_names)
  169. mttAssert(~ismember(name.object,object_names),...
  170. ['Repeated object: "',name.object,'"']) ;
  171. end
  172. switch name.class
  173. case {'0','1'},
  174. mttValidateName(name.object) ;
  175. mttAssert(~ismember(name.object,{'in','out'}),...
  176. 'Junctions cannot use reserved port names') ;
  177. case {'SS','Se','Sf','De','Df'},
  178. mttValidateName(name.object) ;
  179. if isempty(name.domain) | isempty(mtt_environment)
  180. model = setfield(model,'obj',name.object,'domain',[]) ;
  181. model = setfield(model,'obj',name.object,'domain_item',[]) ;
  182. else
  183. mttAssert(ismember(name.domain,domain_names),...
  184. ['Unrecognised domain "',name.domain,'"']) ;
  185. dom = getfield(mtt_environment,'domain',name.domain,'dom') ;
  186. item = getfield(mtt_environment,'domain',name.domain,'item') ;
  187. if isempty(item)
  188. public_domain = getfield(mtt_environment,'public_domain',{dom}) ;
  189. item_names = mttGetFieldNames(public_domain,'item') ;
  190. mttAssert(ismember(name.domain_item,item_names),...
  191. ['Item "',name.domain_item,'" not found in public domain "',name.domain,'"']) ;
  192. item_name = name.domain_item ;
  193. else
  194. mttAssert(isempty(name.domain_item),...
  195. ['Item unspecified in public domain "',name.domain,'"']) ;
  196. item_name = item ;
  197. end
  198. model = setfield(model,'obj',name.object,'domain',dom) ;
  199. model = setfield(model,'obj',name.object,'domain_item',item_name) ;
  200. end
  201. otherwise,
  202. mttValidateName(name.class) ;
  203. mttValidateName(name.object) ;
  204. mttAssert(~ismember(name.object,{'in','out'}),...
  205. 'Objects cannot use reserved port names') ;
  206. end
  207. model = setfield(model,'obj',name.object,'class',name.class) ;
  208. model = setfield(model,'obj',name.object,'xy',coordinates) ;
  209. end
  210. function model = incorporate_anonymous_objects(model)
  211. number_of_objects = mttGetFieldLength(model,'anonymous') ;
  212. last = length(num2str(number_of_objects)) ;
  213. for i = 1:last
  214. object_number(i) = '0' ;
  215. end
  216. for i = 1:number_of_objects
  217. anonymous_object = getfield(model,'anonymous',{i}) ;
  218. current_number = num2str(i) ;
  219. width = length(current_number) ;
  220. first = last-width+1 ;
  221. object_number(first:last) = current_number ;
  222. object_name = ['mtt_obj',object_number] ;
  223. model = setfield(model,'obj',object_name,model.anonymous(i)) ;
  224. end
  225. function r = sign_cross_product(v1,v2)
  226. r = sign(v1(1)*v2(2) - v1(2)*v2(1)) ;
  227. function model = identify_causal_assignments(model)
  228. L = mttGetFieldLength(model,'line') ;
  229. if L>0
  230. N = mttGetFieldLength(model,'bond') ;
  231. for j = 1:L
  232. for i = 1:N
  233. s(i,j) = norm(model.line(j).mid - model.bond(i).xy1) ;
  234. f(i,j) = norm(model.line(j).mid - model.bond(i).xy2) ;
  235. end
  236. end
  237. [min_range_start,nearest_bond_start] = min(s) ;
  238. [min_range_finish,nearest_bond_finish] = min(f) ;
  239. equidistant = min_range_start==min_range_finish ;
  240. at_harpoon = min_range_start>min_range_finish ;
  241. for j = 1:L
  242. fulcrum = num2str(model.line(j).mid) ;
  243. mttAssert(~equidistant(j),...
  244. ['Ambiguous causal line at [',num2str(model.line(j).mid),']']) ;
  245. if at_harpoon(j)
  246. index = nearest_bond_finish(j) ;
  247. bond = model.bond(index) ;
  248. terminal = bond.xy2 ;
  249. terminal_vector = bond.v2 ;
  250. else
  251. index = nearest_bond_start(j) ;
  252. bond = model.bond(index) ;
  253. terminal = bond.xy1 ;
  254. terminal_vector = bond.v1 ;
  255. end
  256. to_lhs = norm(model.line(j).xy1 - terminal) ;
  257. to_mid = norm(model.line(j).mid - terminal) ;
  258. to_rhs = norm(model.line(j).xy2 - terminal) ;
  259. mttAssert(to_mid<norm(bond.harpoon),...
  260. ['Cannot assign causality at [',num2str(fulcrum),']']) ;
  261. causality_ok = 0 ;
  262. is_unicausal = to_mid<min(to_lhs,to_rhs) ;
  263. if is_unicausal
  264. [bond.flow,causality_ok] = mttAssign(bond.flow,at_harpoon(j)) ;
  265. [bond.effort,causality_ok] = mttAssign(bond.effort,at_harpoon(j)) ;
  266. else
  267. causal_vector = (right-left) * sign(to_mid>to_left) ;
  268. causal_assignment = sign_cross_product(terminal_vector,causal_vector) ;
  269. mttAssert(causal_assignment~=0,...
  270. ['Cannot determine causality near [',num2str(fulcrum),']']) ;
  271. if causal_assignment==bond.harpoon_side
  272. [bond.flow,causality_ok] = mttAssign(bond.flow,at_harpoon(j)) ;
  273. else
  274. [bond.effort,causality_ok] = mttAssign(bond.effort,at_harpoon(j)) ;
  275. end
  276. end
  277. mttAssert(causality_ok,...
  278. ['Ambiguous causal assignment near [',num2str(fulcrum),']']) ;
  279. bond.unicausal = mttCompare(bond.flow,bond.effort) ;
  280. model.bond(index) = bond ;
  281. end
  282. end
  283. function model = identify_object_binding(model)
  284. object_names = mttGetFieldNames(model,'obj') ;
  285. number_of_objects = length(object_names) ;
  286. number_of_bonds = mttGetFieldLength(model,'bond') ;
  287. for j = 1:number_of_bonds
  288. bond = model.bond(j) ;
  289. for i = 1:number_of_objects
  290. object = getfield(model,'obj',object_names{i}) ;
  291. origin_proximity(i) = norm(object.xy - bond.xy1) ;
  292. target_proximity(i) = norm(object.xy - bond.xy2) ;
  293. end
  294. [range,index] = min(origin_proximity) ;
  295. origin_name = object_names{index} ;
  296. bond.from.obj = origin_name ;
  297. bond.from.interface = [] ;
  298. [range,index] = min(target_proximity) ;
  299. target_name = object_names{index} ;
  300. bond.to.obj = target_name ;
  301. bond.to.interface = [] ;
  302. model = setfield(model,'bond',{j},bond) ;
  303. origin = getfield(model,'obj',origin_name) ;
  304. next = 1 + mttGetFieldLength(origin,'bond') ;
  305. origin.bond(next).number = j ;
  306. origin.bond(next).is_inbond = 0 ;
  307. model = setfield(model,'obj',origin_name,origin) ;
  308. target = getfield(model,'obj',target_name) ;
  309. next = 1 + mttGetFieldLength(target,'bond') ;
  310. target.bond(next).number = j ;
  311. target.bond(next).is_inbond = 1 ;
  312. model = setfield(model,'obj',target_name,target) ;
  313. end
  314. function model = identify_object_interfaces(model)
  315. object_names = mttGetFieldNames(model,'obj') ;
  316. number_of_objects = length(object_names) ;
  317. number_of_labels = mttGetFieldLength(model,'label') ;
  318. number_of_bonds = mttGetFieldLength(model,'bond') ;
  319. for j = 1:number_of_labels
  320. label = model.label(j) ;
  321. for i = 1:number_of_objects
  322. object_name = object_names{i} ;
  323. object = getfield(model,'obj',object_names{i}) ;
  324. proximity(i) = norm(object.xy - label.xy) ;
  325. end
  326. [range,index] = min(proximity) ;
  327. associated_object = object_names{index} ;
  328. object = getfield(model,'obj',associated_object) ;
  329. switch object.class
  330. case {'0','1'},
  331. mttAssert(~label.is_inline,...
  332. ['Inline ports not valid for "0" and "1" junctions']) ;
  333. end
  334. next = 1 + mttGetFieldLength(object,'interface') ;
  335. object = setfield(object,'interface',{next},'name',label.name) ;
  336. object = setfield(object,'interface',{next},'class',[]) ;
  337. object = setfield(object,'interface',{next},'is_inline',label.is_inline) ;
  338. object = setfield(object,'interface',{next},'xy',label.xy) ;
  339. object = setfield(object,'interface',{next},'in',[]) ;
  340. object = setfield(object,'interface',{next},'out',[]) ;
  341. object = setfield(object,'interface',{next},'map',[]) ;
  342. model = setfield(model,'obj',associated_object,object) ;
  343. end
  344. for j = 1:number_of_objects
  345. object_name = object_names{j} ;
  346. object = getfield(model,'obj',object_name) ;
  347. number_of_attached_bonds = mttGetFieldLength(object,'bond') ;
  348. number_of_interfaces = mttGetFieldLength(object,'interface') ;
  349. for k = 1:number_of_interfaces
  350. interface = object.interface(k) ;
  351. inbond_proximity = [] ; inbond_counter = [] ;
  352. outbond_proximity = [] ; outbond_counter = [] ;
  353. in_counter = 0 ;
  354. out_counter = 0 ;
  355. for i = 1:number_of_attached_bonds
  356. bond_number = object.bond(i).number ;
  357. bond = model.bond(bond_number) ;
  358. if object.bond(i).is_inbond
  359. if isempty(bond.to.interface)
  360. in_counter = in_counter + 1 ;
  361. inbond_proximity(in_counter) = norm(interface.xy - bond.xy2) ;
  362. inbond_counter(in_counter) = bond_number ;
  363. end
  364. else
  365. if isempty(bond.from.interface)
  366. out_counter = out_counter + 1 ;
  367. outbond_proximity(out_counter) = norm(interface.xy - bond.xy1) ;
  368. outbond_counter(out_counter) = bond_number ;
  369. end
  370. end
  371. end
  372. [in_range,inbond_index] = min(inbond_proximity) ;
  373. [out_range,outbond_index] = min(outbond_proximity) ;
  374. inbond = inbond_counter(inbond_index) ;
  375. outbond = outbond_counter(outbond_index) ;
  376. if interface.is_inline
  377. mttAssert(~isempty(inbond_proximity),...
  378. ['No in-bond for interface "',object_name,'[',interface.name,']"']) ;
  379. mttAssert(~isempty(outbond_proximity),...
  380. ['No out-bond for interface "',object_name,'[',interface.name,']"']) ;
  381. interface.in = inbond ;
  382. interface.out = outbond ;
  383. model = setfield(model,'bond',{outbond},'from','interface',k) ;
  384. model = setfield(model,'bond',{inbond},'to','interface',k) ;
  385. else
  386. mttAssert(~(isempty(inbond_proximity) & isempty(outbond_proximity)),...
  387. ['No bond for interface "',object_name,'[',interface.name,']"']) ;
  388. if isempty(inbond_proximity)
  389. interface.out = outbond ;
  390. model = setfield(model,'bond',{outbond},'from','interface',k) ;
  391. elseif isempty(outbond_proximity)
  392. interface.in = inbond ;
  393. model = setfield(model,'bond',{inbond},'to','interface',k) ;
  394. else
  395. mttAssert(in_range~=out_range,...
  396. ['Ambiguous interface "',object_name,'[',interface.name,']"']) ;
  397. if out_range<in_range
  398. interface.out = outbond ;
  399. model = setfield(model,'bond',{outbond},'from','interface',k) ;
  400. else
  401. interface.in = inbond ;
  402. model = setfield(model,'bond',{inbond},'to','interface',k) ;
  403. end
  404. end
  405. end
  406. object.interface(k) = interface ;
  407. end
  408. model = setfield(model,'obj',object_name,object) ;
  409. end
  410. for i = 1:number_of_objects
  411. object_name = object_names{i} ;
  412. object = getfield(model,'obj',object_name) ;
  413. number_of_interfaces = mttGetFieldLength(object,'interface') ;
  414. for k = 1:number_of_interfaces;
  415. interface = object.interface(k) ;
  416. if interface.is_inline
  417. mttAssert(~(isempty(interface.in) | isempty(interface.out)),...
  418. ['Unbound interface: ',object_name,'[',interface.name,']']) ;
  419. else
  420. mttAssert(~(isempty(interface.in) & isempty(interface.out)),...
  421. ['Unbound interface: ',object_name,'[',interface.name,']']) ;
  422. end
  423. end
  424. end
  425. objects_with_in = [] ;
  426. objects_with_out = [] ;
  427. for j = 1:number_of_bonds
  428. bond = model.bond(j) ;
  429. if isempty(bond.from.interface)
  430. object_name = bond.from.obj ;
  431. object = getfield(model,'obj',object_name) ;
  432. if ~ismember(object.class,{'0','1'})
  433. mttAssert(~ismember(object_name,objects_with_out),...
  434. ['Object "',object_name,'" has more than one implicit out-bond']) ;
  435. if isempty(objects_with_out)
  436. objects_with_out = {object_name} ;
  437. else
  438. objects_with_out = [objects_with_out,{object_name}] ;
  439. end
  440. end
  441. next = 1 + mttGetFieldLength(object,'interface') ;
  442. model = setfield(model,'obj',object_name,'interface',{next},'name','out') ;
  443. model = setfield(model,'obj',object_name,'interface',{next},'in',[]) ;
  444. model = setfield(model,'obj',object_name,'interface',{next},'out',j) ;
  445. model = setfield(model,'bond',{j},'from','interface',next) ;
  446. end
  447. if isempty(bond.to.interface)
  448. object_name = bond.to.obj ;
  449. object = getfield(model,'obj',object_name) ;
  450. if ~ismember(object.class,{'0','1'})
  451. mttAssert(~ismember(object_name,objects_with_in),...
  452. ['Object "',object_name,'" has more than one implicit in-bond']) ;
  453. if isempty(objects_with_in)
  454. objects_with_in = {object_name} ;
  455. else
  456. objects_with_in = [objects_with_in,{object_name}] ;
  457. end
  458. end
  459. next = 1 + mttGetFieldLength(object,'interface') ;
  460. model = setfield(model,'obj',object_name,'interface',{next},'name','in') ;
  461. model = setfield(model,'obj',object_name,'interface',{next},'in',j) ;
  462. model = setfield(model,'obj',object_name,'interface',{next},'out',[]) ;
  463. model = setfield(model,'bond',{j},'to','interface',next) ;
  464. end
  465. end
  466. function model = associate_external_domains(model)
  467. object_names = mttGetFieldNames(model,'obj') ;
  468. number_of_objects = length(object_names) ;
  469. for i = 1:number_of_objects
  470. object_name = object_names{i} ;
  471. object = getfield(model,'obj',object_name) ;
  472. switch object.class
  473. case {'SS','Se','Sf','De','Df'},
  474. mttAssert(mttGetFieldLength(object,'interface')==1,...
  475. ['Object "',object_name,'" must have a unique bond interface']) ;
  476. bond_number = [] ;
  477. if ~isempty(object.interface.in)
  478. bond_number = object.interface.in ;
  479. end
  480. if ~isempty(object.interface.out)
  481. bond_number = object.interface.out ;
  482. end
  483. [model,ok] = mttUpdateBondDomain(model,bond_number,object.domain,object.domain_item) ;
  484. mttAssert(ok,['Domain conflict on bond connected to object "',object_name,'"']) ;
  485. end
  486. end
  487. function model = tidy_up(model)
  488. % remove temperory data and xfig geometry from model structure
  489. object_names = mttGetFieldNames(model,'obj') ;
  490. number_of_objects = length(object_names) ;
  491. for i = 1:number_of_objects
  492. object_name = object_names{i} ;
  493. object = getfield(model,'obj',object_name) ;
  494. object = mttDeleteField(object,'bond') ;
  495. object_interfaces = getfield(object,'interface') ;
  496. object_interfaces = mttDeleteField(object_interfaces,'is_inline') ;
  497. object_interfaces = mttDeleteField(object_interfaces,'xy') ;
  498. object = setfield(object,'interface',object_interfaces) ;
  499. object = mttDeleteField(object,'xy') ;
  500. model = setfield(model,'obj',object_name,object) ;
  501. end
  502. all_bonds = getfield(model,'bond') ;
  503. all_bonds = mttDeleteField(all_bonds,'xy1') ;
  504. all_bonds = mttDeleteField(all_bonds,'xy2') ;
  505. all_bonds = mttDeleteField(all_bonds,'v1') ;
  506. all_bonds = mttDeleteField(all_bonds,'v2') ;
  507. all_bonds = mttDeleteField(all_bonds,'harpoon') ;
  508. all_bonds = mttDeleteField(all_bonds,'harpoon_side') ;
  509. model = setfield(model,'bond',all_bonds) ;
  510. model = mttDeleteField(model,'anonymous') ;
  511. model = mttDeleteField(model,'line') ;
  512. model = mttDeleteField(model,'label') ;