FileVRMLParser.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. //
  2. // The unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. (*
  5. VRML file format parser.
  6. *)
  7. unit FileVRMLParser;
  8. interface
  9. {$I GLScene.inc}
  10. uses
  11. System.Classes,
  12. System.SysUtils,
  13. GLVectorGeometry,
  14. GLVectorTypes,
  15. GLVectorLists,
  16. GLUtils;
  17. type
  18. TVRMLNode = class
  19. private
  20. FNodes: TList;
  21. FParent: TVRMLNode;
  22. FName, FDefName: String;
  23. function GetNode(index: Integer): TVRMLNode;
  24. public
  25. constructor Create; virtual;
  26. constructor CreateOwned(AParent: TVRMLNode);
  27. destructor Destroy; override;
  28. function Count: Integer;
  29. procedure Clear;
  30. procedure Add(node: TVRMLNode);
  31. procedure Remove(node: TVRMLNode);
  32. procedure Delete(index: Integer);
  33. property Nodes[index: Integer]: TVRMLNode read GetNode; default;
  34. property Parent: TVRMLNode read FParent;
  35. property Name: String read FName write FName;
  36. property DefName: String read FDefName write FDefName;
  37. end;
  38. TVRMLSingleArray = class(TVRMLNode)
  39. private
  40. FValues: TSingleList;
  41. public
  42. constructor Create; override;
  43. destructor Destroy; override;
  44. property Values: TSingleList read FValues;
  45. end;
  46. TVRMLIntegerArray = class(TVRMLNode)
  47. private
  48. FValues: TIntegerList;
  49. public
  50. constructor Create; override;
  51. destructor Destroy; override;
  52. property Values: TIntegerList read FValues;
  53. end;
  54. TVRMLMaterial = class(TVRMLNode)
  55. private
  56. FDiffuseColor, FAmbientColor, FSpecularColor, FEmissiveColor: TVector3f;
  57. FTransparency, FShininess: Single;
  58. FHasDiffuse, FHasAmbient, FHasSpecular, FHasEmissive, FHasTransparency,
  59. FHasShininess: Boolean;
  60. public
  61. constructor Create; override;
  62. property DiffuseColor: TVector3f read FDiffuseColor write FDiffuseColor;
  63. property AmbientColor: TVector3f read FAmbientColor write FAmbientColor;
  64. property SpecularColor: TVector3f read FSpecularColor write FSpecularColor;
  65. property EmissiveColor: TVector3f read FEmissiveColor write FEmissiveColor;
  66. property Transparency: Single read FTransparency write FTransparency;
  67. property Shininess: Single read FShininess write FShininess;
  68. property HasDiffuse: Boolean read FHasDiffuse write FHasDiffuse;
  69. property HasAmbient: Boolean read FHasAmbient write FHasAmbient;
  70. property HasSpecular: Boolean read FHasSpecular write FHasSpecular;
  71. property HasEmissive: Boolean read FHasEmissive write FHasEmissive;
  72. property HasTransparency: Boolean read FHasTransparency
  73. write FHasTransparency;
  74. property HasShininess: Boolean read FHasShininess write FHasShininess;
  75. end;
  76. TVRMLUse = class(TVRMLNode)
  77. private
  78. FValue: String;
  79. public
  80. property Value: String read FValue write FValue;
  81. end;
  82. TVRMLShapeHints = class(TVRMLNode)
  83. private
  84. FCreaseAngle: Single;
  85. public
  86. property CreaseAngle: Single read FCreaseAngle write FCreaseAngle;
  87. end;
  88. TVRMLTransform = class(TVRMLNode)
  89. private
  90. FCenter: TVector3f;
  91. FRotation: TVector4f;
  92. FScaleFactor: TVector3f;
  93. public
  94. constructor Create; override;
  95. property Center: TVector3f read FCenter write FCenter;
  96. property Rotation: TVector4f read FRotation write FRotation;
  97. property ScaleFactor: TVector3f read FScaleFactor write FScaleFactor;
  98. end;
  99. TVRMLParser = class
  100. private
  101. FCursor: Integer;
  102. FTokens: TStringList;
  103. FRootNode: TVRMLNode;
  104. FCurrentNode: TVRMLNode;
  105. FAllowUnknownNodes: Boolean;
  106. FDefines: TList;
  107. protected
  108. function ReadToken: String;
  109. function ReadSingle: Single;
  110. function ReadVector3f: TVector3f;
  111. function ReadVector4f: TVector4f;
  112. procedure ReadUnknownArray(DefName: String = '');
  113. procedure ReadUnknownHeirachy(DefName: String = '');
  114. procedure ReadUnknown(unknown_token: String; DefName: String = '');
  115. procedure ReadPointArray(DefName: String = '');
  116. procedure ReadCoordIndexArray(DefName: String = '');
  117. procedure ReadNormalIndexArray(DefName: String = '');
  118. procedure ReadTextureCoordIndexArray(DefName: String = '');
  119. procedure ReadCoordinate3(DefName: String = '');
  120. procedure ReadNormal(DefName: String = '');
  121. procedure ReadTextureCoordinate2(DefName: String = '');
  122. procedure ReadMaterial(DefName: String = '');
  123. procedure ReadIndexedFaceSet(DefName: String = '');
  124. procedure ReadTransform(DefName: String = '');
  125. procedure ReadShapeHints(DefName: String = '');
  126. procedure ReadSeparator(DefName: String = '');
  127. procedure ReadGroup(DefName: String = '');
  128. procedure ReadDef;
  129. procedure ReadUse;
  130. public
  131. constructor Create;
  132. destructor Destroy; override;
  133. procedure Parse(Text: String);
  134. property RootNode: TVRMLNode read FRootNode;
  135. property AllowUnknownNodes: Boolean read FAllowUnknownNodes
  136. write FAllowUnknownNodes;
  137. end;
  138. // ---------------------------------------------------------------------------
  139. implementation
  140. // ---------------------------------------------------------------------------
  141. function CreateVRMLTokenList(Text: String): TStringList;
  142. const
  143. cSymbols: array [0 .. 3] of char = ('{', '}', '[', ']');
  144. var
  145. i, j, p: Integer;
  146. str, token: String;
  147. begin
  148. Result := TStringList.Create;
  149. Result.Text := Text;
  150. for i := 0 to Result.Count - 1 do
  151. begin
  152. p := Pos('#', Result[i]);
  153. if p > 0 then
  154. Result[i] := Copy(Result[i], 1, p - 1);
  155. end;
  156. Result.CommaText := Result.Text;
  157. for j := 0 to Length(cSymbols) - 1 do
  158. begin
  159. i := 0;
  160. repeat
  161. token := Result[i];
  162. p := Pos(cSymbols[j], token);
  163. if (p > 0) and (token <> cSymbols[j]) then
  164. begin
  165. str := Copy(token, p + 1, Length(token) - p);
  166. if (p = 1) then
  167. begin
  168. Result.Delete(i);
  169. Result.Insert(i, trim(str));
  170. Result.Insert(i, cSymbols[j]);
  171. end
  172. else
  173. begin
  174. Result.Delete(i);
  175. if Length(str) > 0 then
  176. Result.Insert(i, trim(str));
  177. Result.Insert(i, cSymbols[j]);
  178. Result.Insert(i, trim(Copy(token, 1, p - 1)));
  179. end;
  180. end;
  181. Inc(i);
  182. until i >= Result.Count - 1;
  183. end;
  184. end;
  185. // ---------------
  186. // --------------- TVRMLNode ---------------
  187. // ---------------
  188. constructor TVRMLNode.Create;
  189. begin
  190. FNodes := TList.Create;
  191. end;
  192. constructor TVRMLNode.CreateOwned(AParent: TVRMLNode);
  193. begin
  194. Create;
  195. if Assigned(AParent) then
  196. AParent.Add(Self);
  197. end;
  198. destructor TVRMLNode.Destroy;
  199. begin
  200. Clear;
  201. FNodes.Free;
  202. inherited;
  203. end;
  204. function TVRMLNode.GetNode(index: Integer): TVRMLNode;
  205. begin
  206. Result := TVRMLNode(FNodes[index]);
  207. end;
  208. function TVRMLNode.Count: Integer;
  209. begin
  210. Result := FNodes.Count;
  211. end;
  212. procedure TVRMLNode.Clear;
  213. begin
  214. while FNodes.Count > 0 do
  215. Delete(0);
  216. end;
  217. procedure TVRMLNode.Add(node: TVRMLNode);
  218. begin
  219. if not Assigned(node) then
  220. exit;
  221. if Assigned(node.Parent) then
  222. node.Parent.FNodes.Remove(node);
  223. FNodes.Add(node);
  224. node.FParent := Self;
  225. end;
  226. procedure TVRMLNode.Remove(node: TVRMLNode);
  227. begin
  228. if not Assigned(node) then
  229. exit;
  230. FNodes.Remove(node);
  231. node.Free;
  232. end;
  233. procedure TVRMLNode.Delete(index: Integer);
  234. begin
  235. if (index < 0) or (index >= Count) then
  236. exit;
  237. Nodes[index].Free;
  238. FNodes.Delete(index);
  239. end;
  240. // ---------------
  241. // --------------- TVRMLSingleArray ---------------
  242. // ---------------
  243. constructor TVRMLSingleArray.Create;
  244. begin
  245. inherited;
  246. FValues := TSingleList.Create;
  247. end;
  248. destructor TVRMLSingleArray.Destroy;
  249. begin
  250. FValues.Free;
  251. inherited;
  252. end;
  253. // ---------------
  254. // --------------- TVRMLIntegerArray ---------------
  255. // ---------------
  256. constructor TVRMLIntegerArray.Create;
  257. begin
  258. inherited;
  259. FValues := TIntegerList.Create;
  260. end;
  261. destructor TVRMLIntegerArray.Destroy;
  262. begin
  263. FValues.Free;
  264. inherited;
  265. end;
  266. // ---------------
  267. // --------------- TVRMLMaterial ---------------
  268. // ---------------
  269. constructor TVRMLMaterial.Create;
  270. begin
  271. inherited;
  272. // Default shininess value
  273. FHasDiffuse := False;
  274. FHasAmbient := False;
  275. FHasSpecular := False;
  276. FHasEmissive := False;
  277. FHasTransparency := False;
  278. FHasShininess := False;
  279. end;
  280. // ---------------
  281. // --------------- TVRMLTransform ---------------
  282. // ---------------
  283. constructor TVRMLTransform.Create;
  284. begin
  285. inherited;
  286. FScaleFactor.X := 1;
  287. FScaleFactor.Y := 1;
  288. FScaleFactor.Z := 1;
  289. end;
  290. // ---------------
  291. // --------------- TVRMLParser ---------------
  292. // ---------------
  293. constructor TVRMLParser.Create;
  294. begin
  295. FDefines := TList.Create;
  296. FRootNode := TVRMLNode.Create;
  297. FRootNode.Name := 'Root';
  298. FAllowUnknownNodes := False;
  299. end;
  300. destructor TVRMLParser.Destroy;
  301. begin
  302. FDefines.Free;
  303. FRootNode.Free;
  304. inherited;
  305. end;
  306. function TVRMLParser.ReadToken: String;
  307. begin
  308. if FCursor < FTokens.Count then
  309. begin
  310. Result := LowerCase(FTokens[FCursor]);
  311. Inc(FCursor);
  312. end
  313. else
  314. Result := '';
  315. end;
  316. procedure TVRMLParser.ReadUnknownArray(DefName: String);
  317. var
  318. token: String;
  319. begin
  320. if AllowUnknownNodes then
  321. begin
  322. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  323. FCurrentNode.Name := 'Unknown array';
  324. end;
  325. repeat
  326. token := ReadToken;
  327. if token = '' then
  328. exit;
  329. until token = ']';
  330. if AllowUnknownNodes then
  331. FCurrentNode := FCurrentNode.Parent;
  332. end;
  333. procedure TVRMLParser.ReadUnknownHeirachy(DefName: String);
  334. var
  335. token: String;
  336. begin
  337. if AllowUnknownNodes then
  338. begin
  339. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  340. FCurrentNode.Name := 'Unknown hierarchy';
  341. end;
  342. repeat
  343. token := ReadToken;
  344. if token = '' then
  345. exit
  346. else
  347. ReadUnknown(token);
  348. until token = '}';
  349. if AllowUnknownNodes then
  350. FCurrentNode := FCurrentNode.Parent;
  351. end;
  352. procedure TVRMLParser.ReadUnknown(unknown_token: String; DefName: String);
  353. begin
  354. if unknown_token = '{' then
  355. ReadUnknownHeirachy
  356. else if unknown_token = '[' then
  357. ReadUnknownArray
  358. else if (unknown_token <> '}') and (unknown_token <> ']') and AllowUnknownNodes
  359. then
  360. begin
  361. TVRMLNode.CreateOwned(FCurrentNode).Name := 'UNKNOWN[' +
  362. unknown_token + ']';
  363. end;
  364. end;
  365. function TVRMLParser.ReadSingle: Single;
  366. begin
  367. Result := GLUtils.StrToFloatDef(ReadToken, 0);
  368. end;
  369. function TVRMLParser.ReadVector3f: TVector3f;
  370. begin
  371. Result.X := ReadSingle;
  372. Result.Y := ReadSingle;
  373. Result.Z := ReadSingle;
  374. end;
  375. function TVRMLParser.ReadVector4f: TVector4f;
  376. begin
  377. Result.X := ReadSingle;
  378. Result.Y := ReadSingle;
  379. Result.Z := ReadSingle;
  380. Result.W := ReadSingle;
  381. end;
  382. procedure TVRMLParser.ReadPointArray(DefName: String);
  383. var
  384. token: String;
  385. begin
  386. FCurrentNode := TVRMLSingleArray.CreateOwned(FCurrentNode);
  387. FCurrentNode.Name := 'PointArray';
  388. repeat
  389. token := ReadToken;
  390. if token = '' then
  391. exit;
  392. until token = '[';
  393. repeat
  394. token := ReadToken;
  395. if token = '' then
  396. exit
  397. else if token <> ']' then
  398. TVRMLSingleArray(FCurrentNode)
  399. .Values.Add(GLUtils.StrToFloatDef(token, 0));
  400. until token = ']';
  401. FCurrentNode := FCurrentNode.Parent;
  402. end;
  403. procedure TVRMLParser.ReadCoordIndexArray(DefName: String = '');
  404. var
  405. token: String;
  406. begin
  407. FCurrentNode := TVRMLIntegerArray.CreateOwned(FCurrentNode);
  408. FCurrentNode.Name := 'CoordIndexArray';
  409. FCurrentNode.DefName := DefName;
  410. repeat
  411. token := ReadToken;
  412. if token = '' then
  413. exit;
  414. until token = '[';
  415. repeat
  416. token := ReadToken;
  417. if token = '' then
  418. exit
  419. else if token <> ']' then
  420. TVRMLIntegerArray(FCurrentNode).Values.Add(StrToInt(token));
  421. until token = ']';
  422. FCurrentNode := FCurrentNode.Parent;
  423. end;
  424. procedure TVRMLParser.ReadNormalIndexArray(DefName: String = '');
  425. var
  426. token: String;
  427. begin
  428. FCurrentNode := TVRMLIntegerArray.CreateOwned(FCurrentNode);
  429. FCurrentNode.Name := 'NormalIndexArray';
  430. FCurrentNode.DefName := DefName;
  431. repeat
  432. token := ReadToken;
  433. if token = '' then
  434. exit;
  435. until token = '[';
  436. repeat
  437. token := ReadToken;
  438. if token = '' then
  439. exit
  440. else if token <> ']' then
  441. TVRMLIntegerArray(FCurrentNode).Values.Add(StrToInt(token));
  442. until token = ']';
  443. FCurrentNode := FCurrentNode.Parent;
  444. end;
  445. procedure TVRMLParser.ReadTextureCoordIndexArray(DefName: String = '');
  446. var
  447. token: String;
  448. begin
  449. FCurrentNode := TVRMLIntegerArray.CreateOwned(FCurrentNode);
  450. FCurrentNode.Name := 'TextureCoordIndexArray';
  451. FCurrentNode.DefName := DefName;
  452. repeat
  453. token := ReadToken;
  454. if token = '' then
  455. exit;
  456. until token = '[';
  457. repeat
  458. token := ReadToken;
  459. if token = '' then
  460. exit
  461. else if token <> ']' then
  462. TVRMLIntegerArray(FCurrentNode).Values.Add(StrToInt(token));
  463. until token = ']';
  464. FCurrentNode := FCurrentNode.Parent;
  465. end;
  466. procedure TVRMLParser.ReadMaterial(DefName: String);
  467. var
  468. token: String;
  469. begin
  470. FCurrentNode := TVRMLMaterial.CreateOwned(FCurrentNode);
  471. FCurrentNode.Name := 'Material';
  472. FCurrentNode.DefName := DefName;
  473. repeat
  474. token := ReadToken;
  475. if token = '' then
  476. exit;
  477. until token = '{';
  478. with TVRMLMaterial(FCurrentNode) do
  479. begin
  480. repeat
  481. token := ReadToken;
  482. if token = '' then
  483. exit
  484. else if token = 'diffusecolor' then
  485. begin
  486. DiffuseColor := ReadVector3f;
  487. HasDiffuse := True;
  488. end
  489. else if token = 'ambientcolor' then
  490. begin
  491. AmbientColor := ReadVector3f;
  492. HasAmbient := True;
  493. end
  494. else if token = 'specularcolor' then
  495. begin
  496. SpecularColor := ReadVector3f;
  497. HasSpecular := True;
  498. end
  499. else if token = 'emissivecolor' then
  500. begin
  501. EmissiveColor := ReadVector3f;
  502. HasEmissive := True;
  503. end
  504. else if token = 'transparency' then
  505. begin
  506. Transparency := ReadSingle;
  507. HasTransparency := True;
  508. end
  509. else if token = 'shininess' then
  510. begin
  511. Shininess := ReadSingle;
  512. HasShininess := True;
  513. end
  514. else if token <> '}' then
  515. ReadUnknown(token);
  516. until token = '}';
  517. end;
  518. FCurrentNode := FCurrentNode.Parent;
  519. end;
  520. procedure TVRMLParser.ReadCoordinate3(DefName: String = '');
  521. var
  522. token: String;
  523. begin
  524. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  525. FCurrentNode.Name := 'Coordinate3';
  526. FCurrentNode.DefName := DefName;
  527. repeat
  528. token := ReadToken;
  529. if token = '' then
  530. exit;
  531. until token = '{';
  532. repeat
  533. token := ReadToken;
  534. if token = '' then
  535. exit
  536. else if token = 'point' then
  537. ReadPointArray
  538. else if token <> '}' then
  539. ReadUnknown(token);
  540. until token = '}';
  541. FCurrentNode := FCurrentNode.Parent;
  542. end;
  543. procedure TVRMLParser.ReadNormal(DefName: String = '');
  544. var
  545. token: String;
  546. begin
  547. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  548. FCurrentNode.Name := 'Normal';
  549. FCurrentNode.DefName := DefName;
  550. repeat
  551. token := ReadToken;
  552. if token = '' then
  553. exit;
  554. until token = '{';
  555. repeat
  556. token := ReadToken;
  557. if token = '' then
  558. exit
  559. else if token = 'vector' then
  560. ReadPointArray
  561. else if token <> '}' then
  562. ReadUnknown(token);
  563. until token = '}';
  564. FCurrentNode := FCurrentNode.Parent;
  565. end;
  566. procedure TVRMLParser.ReadTextureCoordinate2(DefName: String = '');
  567. var
  568. token: String;
  569. begin
  570. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  571. FCurrentNode.Name := 'TextureCoordinate2';
  572. FCurrentNode.DefName := DefName;
  573. repeat
  574. token := ReadToken;
  575. if token = '' then
  576. exit;
  577. until token = '{';
  578. repeat
  579. token := ReadToken;
  580. if token = '' then
  581. exit
  582. else if token = 'point' then
  583. ReadPointArray
  584. else if token <> '}' then
  585. ReadUnknown(token);
  586. until token = '}';
  587. FCurrentNode := FCurrentNode.Parent;
  588. end;
  589. procedure TVRMLParser.ReadIndexedFaceSet(DefName: String = '');
  590. var
  591. token: String;
  592. begin
  593. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  594. FCurrentNode.Name := 'IndexedFaceSet';
  595. FCurrentNode.DefName := DefName;
  596. repeat
  597. token := ReadToken;
  598. if token = '' then
  599. exit;
  600. until token = '{';
  601. repeat
  602. token := ReadToken;
  603. if token = '' then
  604. exit
  605. else if token = 'coordindex' then
  606. ReadCoordIndexArray
  607. else if token = 'normalindex' then
  608. ReadNormalIndexArray
  609. else if token = 'texturecoordindex' then
  610. ReadTextureCoordIndexArray
  611. else if token <> '}' then
  612. ReadUnknown(token);
  613. until token = '}';
  614. FCurrentNode := FCurrentNode.Parent;
  615. end;
  616. procedure TVRMLParser.ReadTransform(DefName: String);
  617. var
  618. token: String;
  619. begin
  620. FCurrentNode := TVRMLTransform.CreateOwned(FCurrentNode);
  621. FCurrentNode.Name := 'Transform';
  622. FCurrentNode.DefName := DefName;
  623. repeat
  624. token := ReadToken;
  625. if token = '' then
  626. exit;
  627. until token = '{';
  628. with TVRMLTransform(FCurrentNode) do
  629. begin
  630. repeat
  631. token := ReadToken;
  632. if token = '' then
  633. exit
  634. else if token = 'rotation' then
  635. Rotation := ReadVector4f
  636. else if token = 'center' then
  637. Center := ReadVector3f
  638. else if token = 'scalefactor' then
  639. ScaleFactor := ReadVector3f
  640. else if token <> '}' then
  641. ReadUnknown(token);
  642. until token = '}';
  643. end;
  644. FCurrentNode := FCurrentNode.Parent;
  645. end;
  646. procedure TVRMLParser.ReadShapeHints(DefName: String = '');
  647. var
  648. token: String;
  649. begin
  650. FCurrentNode := TVRMLShapeHints.CreateOwned(FCurrentNode);
  651. FCurrentNode.Name := 'ShapeHints';
  652. FCurrentNode.DefName := DefName;
  653. repeat
  654. token := ReadToken;
  655. if token = '' then
  656. exit;
  657. until token = '{';
  658. repeat
  659. token := ReadToken;
  660. if token = '' then
  661. exit
  662. else if token = 'creaseangle' then
  663. TVRMLShapeHints(FCurrentNode).CreaseAngle := ReadSingle
  664. else if token <> '}' then
  665. ReadUnknown(token);
  666. until token = '}';
  667. FCurrentNode := FCurrentNode.Parent;
  668. end;
  669. procedure TVRMLParser.ReadSeparator(DefName: String = '');
  670. var
  671. token: String;
  672. begin
  673. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  674. FCurrentNode.Name := 'Separator';
  675. FCurrentNode.DefName := DefName;
  676. repeat
  677. token := ReadToken;
  678. if token = '' then
  679. exit;
  680. until token = '{';
  681. repeat
  682. token := ReadToken;
  683. if token = '' then
  684. exit
  685. else if token = 'def' then
  686. ReadDef
  687. else if (token = 'group') or (token = 'switch') then
  688. ReadGroup
  689. else if token = 'separator' then
  690. ReadSeparator
  691. else if token = 'use' then
  692. ReadUse
  693. else if token = 'shapehints' then
  694. ReadShapeHints
  695. else if token = 'transform' then
  696. ReadTransform
  697. else if token = 'material' then
  698. ReadMaterial
  699. else if token = 'coordinate3' then
  700. ReadCoordinate3
  701. else if token = 'normal' then
  702. ReadNormal
  703. else if token = 'texturecoordinate2' then
  704. ReadTextureCoordinate2
  705. else if token = 'indexedfaceset' then
  706. ReadIndexedFaceSet
  707. else if token <> '}' then
  708. ReadUnknown(token);
  709. until token = '}';
  710. FCurrentNode := FCurrentNode.Parent;
  711. end;
  712. procedure TVRMLParser.ReadGroup(DefName: String = '');
  713. var
  714. token: String;
  715. begin
  716. FCurrentNode := TVRMLNode.CreateOwned(FCurrentNode);
  717. FCurrentNode.Name := 'Group';
  718. FCurrentNode.DefName := DefName;
  719. repeat
  720. token := ReadToken;
  721. if token = '' then
  722. exit;
  723. until token = '{';
  724. repeat
  725. token := ReadToken;
  726. if token = '' then
  727. exit
  728. else if token = 'def' then
  729. ReadDef
  730. else if (token = 'group') or (token = 'switch') then
  731. ReadGroup
  732. else if token = 'separator' then
  733. ReadSeparator
  734. else if token = 'use' then
  735. ReadUse
  736. else if token = 'shapehints' then
  737. ReadShapeHints
  738. else if token = 'transform' then
  739. ReadTransform
  740. else if token = 'material' then
  741. ReadMaterial
  742. else if token = 'coordinate3' then
  743. ReadCoordinate3
  744. else if token = 'indexedfaceset' then
  745. ReadIndexedFaceSet
  746. else if token <> '}' then
  747. ReadUnknown(token);
  748. until token = '}';
  749. FCurrentNode := FCurrentNode.Parent;
  750. end;
  751. procedure TVRMLParser.ReadDef;
  752. var
  753. DefName, token: String;
  754. begin
  755. DefName := ReadToken;
  756. token := ReadToken;
  757. if (token = 'group') or (token = 'switch') then
  758. ReadGroup(DefName)
  759. else if token = 'separator' then
  760. ReadSeparator(DefName)
  761. else if token = 'transform' then
  762. ReadTransform(DefName)
  763. else if token = 'material' then
  764. ReadMaterial(DefName)
  765. else if token = 'coordinate3' then
  766. ReadCoordinate3(DefName)
  767. else if token = 'indexedfaceset' then
  768. ReadIndexedFaceSet(DefName)
  769. else
  770. ReadUnknown(token);
  771. end;
  772. procedure TVRMLParser.ReadUse;
  773. begin
  774. with TVRMLUse.CreateOwned(FCurrentNode) do
  775. begin
  776. name := 'Use';
  777. Value := ReadToken;
  778. end;
  779. end;
  780. procedure TVRMLParser.Parse(Text: String);
  781. var
  782. token: String;
  783. begin
  784. FTokens := CreateVRMLTokenList(Text);
  785. FCursor := 0;
  786. FCurrentNode := FRootNode;
  787. try
  788. repeat
  789. token := ReadToken;
  790. if token = 'def' then
  791. ReadDef
  792. else if (token = 'group') or (token = 'switch') then
  793. ReadGroup
  794. else if token = 'separator' then
  795. ReadSeparator
  796. else if token = 'use' then
  797. ReadUse
  798. else if token = 'shapehints' then
  799. ReadShapeHints
  800. else if token = 'transform' then
  801. ReadTransform
  802. else if token = 'material' then
  803. ReadMaterial
  804. else if token = 'coordinate3' then
  805. ReadCoordinate3
  806. else if token = 'indexedfaceset' then
  807. ReadIndexedFaceSet
  808. else
  809. ReadUnknown(token);
  810. until FCursor >= FTokens.Count;
  811. finally
  812. FTokens.Free;
  813. end;
  814. end;
  815. end.