You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1235 lines
29 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <iostream>
  24. #include <sstream>
  25. #include <utility>
  26. #include <wx/string.h>
  27. #include <wx/filename.h>
  28. #include <wx/log.h>
  29. #include "vrml2_base.h"
  30. #include "vrml2_transform.h"
  31. #include "vrml2_shape.h"
  32. #include "vrml2_appearance.h"
  33. #include "vrml2_material.h"
  34. #include "vrml2_faceset.h"
  35. #include "vrml2_lineset.h"
  36. #include "vrml2_pointset.h"
  37. #include "vrml2_coords.h"
  38. #include "vrml2_norms.h"
  39. #include "vrml2_color.h"
  40. #include "vrml2_box.h"
  41. #include "vrml2_switch.h"
  42. #include "vrml2_inline.h"
  43. #include "plugins/3dapi/ifsg_all.h"
  44. SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline );
  45. WRL2BASE::WRL2BASE() : WRL2NODE()
  46. {
  47. m_useInline = false;
  48. m_Type = WRL2_BASE;
  49. return;
  50. }
  51. WRL2BASE::~WRL2BASE()
  52. {
  53. std::map< std::string, SGNODE* >::iterator iS = m_inlineModels.begin();
  54. std::map< std::string, SGNODE* >::iterator eS = m_inlineModels.end();
  55. while( iS != eS )
  56. {
  57. SGNODE* np = iS->second;
  58. // destroy any orphaned Inline{} node data
  59. if( np && NULL == S3D::GetSGNodeParent( np ) )
  60. S3D::DestroyNode( np );
  61. ++iS;
  62. }
  63. m_inlineModels.clear();
  64. return;
  65. }
  66. // functions inherited from WRL2NODE
  67. bool WRL2BASE::SetParent( WRL2NODE* aParent, bool /* doUnlink */ )
  68. {
  69. #ifdef DEBUG_VRML2
  70. do {
  71. std::ostringstream ostr;
  72. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  73. ostr << " * [BUG] attempting to set parent on WRL2BASE node";
  74. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  75. } while( 0 );
  76. #endif
  77. return false;
  78. }
  79. void WRL2BASE::SetEnableInline( bool enable )
  80. {
  81. m_useInline = enable;
  82. return;
  83. }
  84. bool WRL2BASE::GetEnableInline( void )
  85. {
  86. return m_useInline;
  87. }
  88. SGNODE* WRL2BASE::GetInlineData( const std::string& aName )
  89. {
  90. if( aName.empty() )
  91. return NULL;
  92. std::map< std::string, SGNODE* >::iterator dp = m_inlineModels.find( aName );
  93. if( dp != m_inlineModels.end() )
  94. return dp->second;
  95. wxString tname;
  96. if( aName.find( "file://", 0, 7 ) == 0 )
  97. {
  98. if( aName.length() <= 7 )
  99. return NULL;
  100. tname = wxString::FromUTF8Unchecked( aName.substr( 7 ).c_str() );
  101. }
  102. else
  103. {
  104. tname = wxString::FromUTF8Unchecked( aName.c_str() );
  105. }
  106. wxFileName fn;
  107. fn.Assign( tname );
  108. if( !fn.Normalize() )
  109. {
  110. m_inlineModels.insert( std::pair< std::string, SGNODE* >( aName, NULL ) );
  111. return NULL;
  112. }
  113. SCENEGRAPH* sp = LoadVRML( fn.GetFullPath(), false );
  114. if( NULL == sp )
  115. {
  116. m_inlineModels.insert( std::pair< std::string, SGNODE* >( aName, NULL ) );
  117. return NULL;
  118. }
  119. m_inlineModels.insert( std::pair< std::string, SGNODE* >( aName, (SGNODE*)sp ) );
  120. return (SGNODE*)sp;
  121. }
  122. std::string WRL2BASE::GetName( void )
  123. {
  124. #ifdef DEBUG_VRML2
  125. do {
  126. std::ostringstream ostr;
  127. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  128. ostr << " * [BUG] attempting to extract name from virtual base node";
  129. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  130. } while( 0 );
  131. #endif
  132. return std::string( "" );
  133. }
  134. bool WRL2BASE::SetName( const std::string& aName )
  135. {
  136. #ifdef DEBUG_VRML2
  137. do {
  138. std::ostringstream ostr;
  139. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  140. ostr << " * [BUG] attempting to set name on virtual base node";
  141. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  142. } while( 0 );
  143. #endif
  144. return false;
  145. }
  146. bool WRL2BASE::Read( WRLPROC& proc )
  147. {
  148. if( proc.GetVRMLType() != VRML_V2 )
  149. {
  150. #ifdef DEBUG_VRML2
  151. do {
  152. std::ostringstream ostr;
  153. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  154. ostr << " * [BUG] no open file or file is not a VRML2 file";
  155. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  156. } while( 0 );
  157. #endif
  158. return false;
  159. }
  160. WRL2NODE* node = NULL;
  161. while( ReadNode( proc, this, &node ) && !proc.eof() );
  162. if( proc.eof() )
  163. return true;
  164. return false;
  165. }
  166. bool WRL2BASE::isDangling( void )
  167. {
  168. // the base node is never dangling
  169. return false;
  170. }
  171. bool WRL2BASE::implementUse( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  172. {
  173. if( NULL != aNode )
  174. *aNode = NULL;
  175. if( !aParent )
  176. {
  177. #ifdef DEBUG_VRML2
  178. do {
  179. std::ostringstream ostr;
  180. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  181. ostr << " * [BUG] invoked with NULL parent";
  182. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  183. } while( 0 );
  184. #endif
  185. return false;
  186. }
  187. std::string glob;
  188. if( !proc.ReadName( glob ) )
  189. {
  190. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  191. do {
  192. std::ostringstream ostr;
  193. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  194. ostr << proc.GetError();
  195. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  196. } while( 0 );
  197. #endif
  198. return false;
  199. }
  200. WRL2NODE* ref = aParent->FindNode( glob, NULL );
  201. // return 'true' - the file may be defective but it may still be somewhat OK
  202. if( NULL == ref )
  203. {
  204. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  205. do {
  206. std::ostringstream ostr;
  207. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  208. ostr << " * [INFO] node '" << glob << "' not found";
  209. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  210. } while( 0 );
  211. #endif
  212. return true;
  213. }
  214. if( !aParent->AddRefNode( ref ) )
  215. {
  216. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  217. do {
  218. std::ostringstream ostr;
  219. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  220. ostr << " * [INFO] failed to add node '" << glob << "' (";
  221. ostr << ref->GetNodeTypeName( ref->GetNodeType() ) << ") to parent of type ";
  222. ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
  223. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  224. } while( 0 );
  225. #endif
  226. return false;
  227. }
  228. if( NULL != aNode )
  229. *aNode = ref;
  230. return true;
  231. }
  232. bool WRL2BASE::implementDef( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  233. {
  234. if( NULL != aNode )
  235. *aNode = NULL;
  236. if( NULL == aParent )
  237. {
  238. #ifdef DEBUG_VRML2
  239. do {
  240. std::ostringstream ostr;
  241. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  242. ostr << " * [BUG] invalid parent pointer (NULL)";
  243. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  244. } while( 0 );
  245. #endif
  246. return false;
  247. }
  248. std::string glob;
  249. WRL2NODE* lnode = NULL;
  250. if( !proc.ReadName( glob ) )
  251. {
  252. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  253. do {
  254. std::ostringstream ostr;
  255. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  256. ostr << proc.GetError();
  257. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  258. } while( 0 );
  259. #endif
  260. return false;
  261. }
  262. size_t line, column;
  263. proc.GetFilePosData( line, column );
  264. if( ReadNode( proc, aParent, &lnode ) )
  265. {
  266. if( NULL != aNode )
  267. *aNode = lnode;
  268. if( lnode && !lnode->SetName( glob ) )
  269. {
  270. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  271. do {
  272. std::ostringstream ostr;
  273. size_t line, column;
  274. proc.GetFilePosData( line, column );
  275. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  276. ostr << " * [INFO] bad formatting (invalid name) at line";
  277. ostr << line << ", column " << column;
  278. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  279. } while( 0 );
  280. #endif
  281. return false;
  282. }
  283. return true;
  284. }
  285. return false;
  286. }
  287. bool WRL2BASE::ReadNode( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  288. {
  289. // This function reads a node and stores a pointer to it in aNode.
  290. // A value 'true' is returned if a node is successfully read or,
  291. // if the node is not supported, successfully discarded. Callers
  292. // must always check the value of aNode when the function returns
  293. // 'true' since it will be NULL if the node type is not supported.
  294. if( NULL != aNode )
  295. *aNode = NULL;
  296. if( NULL == aParent )
  297. {
  298. #ifdef DEBUG_VRML2
  299. do {
  300. std::ostringstream ostr;
  301. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  302. ostr << " * [BUG] invalid parent pointer (NULL)";
  303. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  304. } while( 0 );
  305. #endif
  306. return false;
  307. }
  308. std::string glob;
  309. WRL2NODES ntype;
  310. if( !proc.ReadName( glob ) )
  311. {
  312. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  313. if( !proc.eof() )
  314. {
  315. std::ostringstream ostr;
  316. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  317. ostr << proc.GetError();
  318. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  319. }
  320. #endif
  321. return false;
  322. }
  323. // Process node name:
  324. // the names encountered at this point should be one of the
  325. // built-in node names or one of:
  326. // DEF, USE
  327. // PROTO, EXTERNPROTO
  328. // ROUTE
  329. // any PROTO or EXTERNPROTO defined name
  330. // since we do not support PROTO or EXTERNPROTO, any unmatched names are
  331. // assumed to be defined via PROTO/EXTERNPROTO and deleted according to
  332. // a typical pattern.
  333. if( !glob.compare( "USE" ) )
  334. {
  335. if( !implementUse( proc, aParent, aNode ) )
  336. {
  337. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  338. do {
  339. std::ostringstream ostr;
  340. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  341. ostr << proc.GetError();
  342. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  343. } while( 0 );
  344. #endif
  345. return false;
  346. }
  347. return true;
  348. }
  349. if( !glob.compare( "DEF" ) )
  350. {
  351. if( !implementDef( proc, aParent, aNode ) )
  352. {
  353. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  354. do {
  355. std::ostringstream ostr;
  356. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  357. ostr << proc.GetError();
  358. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  359. } while( 0 );
  360. #endif
  361. return false;
  362. }
  363. return true;
  364. }
  365. if( !glob.compare( "PROTO" ) )
  366. {
  367. if( !proc.ReadName( glob ) || !proc.DiscardList() )
  368. {
  369. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  370. do {
  371. std::ostringstream ostr;
  372. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  373. ostr << proc.GetError();
  374. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  375. } while( 0 );
  376. #endif
  377. return false;
  378. }
  379. return true;
  380. }
  381. if( !glob.compare( "EXTERNPROTO" ) )
  382. {
  383. if( !proc.ReadName( glob ) || !proc.ReadName( glob ) || !proc.DiscardList() )
  384. {
  385. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  386. do {
  387. std::ostringstream ostr;
  388. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  389. ostr << proc.GetError();
  390. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  391. } while( 0 );
  392. #endif
  393. return false;
  394. }
  395. return true;
  396. }
  397. if( !glob.compare( "ROUTE" ) )
  398. {
  399. if( !proc.ReadGlob( glob ) || !proc.ReadGlob( glob ) || !proc.ReadGlob( glob ) )
  400. {
  401. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  402. do {
  403. std::ostringstream ostr;
  404. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  405. ostr << proc.GetError();
  406. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  407. } while( 0 );
  408. #endif
  409. return false;
  410. }
  411. return true;
  412. }
  413. ntype = getNodeTypeID( glob );
  414. size_t line = 0;
  415. size_t column = 0;
  416. proc.GetFilePosData( line, column );
  417. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
  418. do {
  419. std::ostringstream ostr;
  420. ostr << " * [INFO] Processing node '" << glob << "' ID: " << ntype;
  421. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  422. } while( 0 );
  423. #endif
  424. switch( ntype )
  425. {
  426. //
  427. // items to be implemented:
  428. //
  429. case WRL2_APPEARANCE:
  430. if( !readAppearance( proc, aParent, aNode ) )
  431. return false;
  432. break;
  433. case WRL2_BOX:
  434. if( !readBox( proc, aParent, aNode ) )
  435. return false;
  436. break;
  437. case WRL2_COLOR:
  438. if( !readColor( proc, aParent, aNode ) )
  439. return false;
  440. break;
  441. case WRL2_CONE:
  442. // XXX - IMPLEMENT
  443. if( !proc.DiscardNode() )
  444. {
  445. #ifdef DEBUG_VRML2
  446. do {
  447. std::ostringstream ostr;
  448. ostr << " * [INFO] FAIL: discard " << glob << " node at l";
  449. ostr << line << ", c" << column;
  450. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  451. } while( 0 );
  452. #endif
  453. return false;
  454. }
  455. #ifdef DEBUG_VRML2
  456. else
  457. {
  458. do {
  459. std::ostringstream ostr;
  460. ostr << " * [INFO] OK: discard " << glob << " node at l";
  461. ostr << line << ", c" << column;
  462. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  463. } while( 0 );
  464. }
  465. #endif
  466. break;
  467. case WRL2_COORDINATE:
  468. if( !readCoords( proc, aParent, aNode ) )
  469. return false;
  470. break;
  471. case WRL2_CYLINDER:
  472. // XXX - IMPLEMENT
  473. if( !proc.DiscardNode() )
  474. {
  475. #ifdef DEBUG_VRML2
  476. do {
  477. std::ostringstream ostr;
  478. ostr << " * [INFO] FAIL: discard " << glob << " node at l";
  479. ostr << line << ", c" << column;
  480. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  481. } while( 0 );
  482. #endif
  483. return false;
  484. }
  485. #ifdef DEBUG_VRML2
  486. else
  487. {
  488. std::ostringstream ostr;
  489. ostr << " * [INFO] OK: discard " << glob << " node at l";
  490. ostr << line << ", c" << column;
  491. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  492. }
  493. #endif
  494. break;
  495. case WRL2_ELEVATIONGRID:
  496. // XXX - IMPLEMENT
  497. if( !proc.DiscardNode() )
  498. {
  499. #ifdef DEBUG_VRML2
  500. do {
  501. std::ostringstream ostr;
  502. ostr << " * [INFO] FAIL: discard " << glob << " node at l";
  503. ostr << line << ", c" << column;
  504. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  505. } while( 0 );
  506. #endif
  507. return false;
  508. }
  509. #ifdef DEBUG_VRML2
  510. else
  511. {
  512. do {
  513. std::ostringstream ostr;
  514. ostr << " * [INFO] OK: discard " << glob << " node at l";
  515. ostr << line << ", c" << column;
  516. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  517. } while( 0 );
  518. }
  519. #endif
  520. break;
  521. case WRL2_EXTRUSION:
  522. // XXX - IMPLEMENT
  523. if( !proc.DiscardNode() )
  524. {
  525. #ifdef DEBUG_VRML2
  526. do {
  527. std::ostringstream ostr;
  528. ostr << " * [INFO] FAIL: discard " << glob << " node at l";
  529. ostr << line << ", c" << column;
  530. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  531. } while( 0 );
  532. #endif
  533. return false;
  534. }
  535. #ifdef DEBUG_VRML2
  536. else
  537. {
  538. std::ostringstream ostr;
  539. ostr << " * [INFO] OK: discard " << glob << " node at l";
  540. ostr << line << ", c" << column;
  541. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  542. }
  543. #endif
  544. break;
  545. case WRL2_INDEXEDFACESET:
  546. if( !readFaceSet( proc, aParent, aNode ) )
  547. return false;
  548. break;
  549. case WRL2_INDEXEDLINESET:
  550. if( !readLineSet( proc, aParent, aNode ) )
  551. return false;
  552. break;
  553. case WRL2_POINTSET:
  554. if( !readPointSet( proc, aParent, aNode ) )
  555. return false;
  556. break;
  557. case WRL2_MATERIAL:
  558. if( !readMaterial( proc, aParent, aNode ) )
  559. return false;
  560. break;
  561. case WRL2_NORMAL:
  562. if( !readNorms( proc, aParent, aNode ) )
  563. return false;
  564. break;
  565. case WRL2_SHAPE:
  566. if( !readShape( proc, aParent, aNode ) )
  567. return false;
  568. break;
  569. case WRL2_SPHERE:
  570. // XXX - IMPLEMENT
  571. if( !proc.DiscardNode() )
  572. {
  573. #ifdef DEBUG_VRML2
  574. do {
  575. std::ostringstream ostr;
  576. ostr << " * [INFO] FAIL: discard " << glob << " node at l";
  577. ostr << line << ", c" << column;
  578. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  579. } while( 0 );
  580. #endif
  581. return false;
  582. }
  583. #ifdef DEBUG_VRML2
  584. else
  585. {
  586. std::ostringstream ostr;
  587. ostr << " * [INFO] OK: discard " << glob << " node at l";
  588. ostr << line << ", c" << column;
  589. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  590. }
  591. #endif
  592. break;
  593. case WRL2_SWITCH:
  594. if( !readSwitch( proc, aParent, aNode ) )
  595. return false;
  596. break;
  597. case WRL2_TRANSFORM:
  598. case WRL2_GROUP:
  599. if( !readTransform( proc, aParent, aNode ) )
  600. return false;
  601. break;
  602. case WRL2_INLINE:
  603. if( !readInline( proc, aParent, aNode ) )
  604. return false;
  605. break;
  606. //
  607. // items not implemented or for optional future implementation:
  608. //
  609. case WRL2_ANCHOR:
  610. case WRL2_AUDIOCLIP:
  611. case WRL2_BACKGROUND:
  612. case WRL2_BILLBOARD:
  613. case WRL2_COLLISION:
  614. case WRL2_COLORINTERPOLATOR:
  615. case WRL2_COORDINATEINTERPOLATOR:
  616. case WRL2_CYLINDERSENSOR:
  617. case WRL2_DIRECTIONALLIGHT:
  618. case WRL2_FOG:
  619. case WRL2_FONTSTYLE:
  620. case WRL2_IMAGETEXTURE:
  621. case WRL2_LOD:
  622. case WRL2_MOVIETEXTURE:
  623. case WRL2_NAVIGATIONINFO:
  624. case WRL2_NORMALINTERPOLATOR:
  625. case WRL2_ORIENTATIONINTERPOLATOR:
  626. case WRL2_PIXELTEXTURE:
  627. case WRL2_PLANESENSOR:
  628. case WRL2_POINTLIGHT:
  629. case WRL2_POSITIONINTERPOLATOR:
  630. case WRL2_PROXIMITYSENSOR:
  631. case WRL2_SCALARINTERPOLATOR:
  632. case WRL2_SCRIPT:
  633. case WRL2_SOUND:
  634. case WRL2_SPHERESENSOR:
  635. case WRL2_SPOTLIGHT:
  636. case WRL2_TEXT:
  637. case WRL2_TEXTURECOORDINATE:
  638. case WRL2_TEXTURETRANSFORM:
  639. case WRL2_TIMESENSOR:
  640. case WRL2_TOUCHSENSOR:
  641. case WRL2_VIEWPOINT:
  642. case WRL2_VISIBILITYSENSOR:
  643. case WRL2_WORLDINFO:
  644. case WRL2_INVALID:
  645. default:
  646. proc.GetFilePosData( line, column );
  647. if( !proc.DiscardNode() )
  648. {
  649. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  650. do {
  651. std::ostringstream ostr;
  652. ostr << proc.GetError() << "\n";
  653. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  654. ostr << " * [INFO] could not discard node at line " << line;
  655. ostr << ", column " << column;
  656. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  657. } while( 0 );
  658. #endif
  659. return false;
  660. }
  661. #ifdef DEBUG_VRML2
  662. else
  663. {
  664. std::ostringstream ostr;
  665. ostr << " * [INFO] OK: discard unsupported " << glob << " node at l";
  666. ostr << line << ", c" << column;
  667. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  668. }
  669. #endif
  670. break;
  671. }
  672. return true;
  673. }
  674. bool WRL2BASE::Read( WRLPROC& proc, WRL2BASE* aTopNode )
  675. {
  676. // this function makes no sense in the base node
  677. #ifdef DEBUG_VRML2
  678. do {
  679. std::ostringstream ostr;
  680. ostr << proc.GetError() << "\n";
  681. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  682. ostr << " * [BUG] this method must never be invoked on a WRL2BASE object";
  683. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  684. } while( 0 );
  685. #endif
  686. return false;
  687. }
  688. bool WRL2BASE::readTransform( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  689. {
  690. if( NULL != aNode )
  691. *aNode = NULL;
  692. WRL2TRANSFORM* np = new WRL2TRANSFORM( aParent );
  693. if( !np->Read( proc, this ) )
  694. {
  695. delete np;
  696. return false;
  697. }
  698. if( NULL != aNode )
  699. *aNode = (WRL2NODE*) np;
  700. return true;
  701. }
  702. bool WRL2BASE::readShape( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  703. {
  704. if( NULL != aNode )
  705. *aNode = NULL;
  706. WRL2SHAPE* np = new WRL2SHAPE( aParent );
  707. if( !np->Read( proc, this ) )
  708. {
  709. delete np;
  710. return false;
  711. }
  712. if( NULL != aNode )
  713. *aNode = (WRL2NODE*) np;
  714. return true;
  715. }
  716. bool WRL2BASE::readAppearance( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  717. {
  718. if( NULL != aNode )
  719. *aNode = NULL;
  720. WRL2APPEARANCE* np = new WRL2APPEARANCE( aParent );
  721. if( !np->Read( proc, this ) )
  722. {
  723. delete np;
  724. return false;
  725. }
  726. if( NULL != aNode )
  727. *aNode = (WRL2NODE*) np;
  728. return true;
  729. }
  730. bool WRL2BASE::readMaterial( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  731. {
  732. if( NULL != aNode )
  733. *aNode = NULL;
  734. WRL2MATERIAL* np = new WRL2MATERIAL( aParent );
  735. if( !np->Read( proc, this ) )
  736. {
  737. delete np;
  738. return false;
  739. }
  740. if( NULL != aNode )
  741. *aNode = (WRL2NODE*) np;
  742. return true;
  743. }
  744. bool WRL2BASE::readFaceSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  745. {
  746. if( NULL != aNode )
  747. *aNode = NULL;
  748. WRL2FACESET* np = new WRL2FACESET( aParent );
  749. if( !np->Read( proc, this ) )
  750. {
  751. delete np;
  752. return false;
  753. }
  754. if( NULL != aNode )
  755. *aNode = (WRL2NODE*) np;
  756. return true;
  757. }
  758. bool WRL2BASE::readLineSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  759. {
  760. if( NULL != aNode )
  761. *aNode = NULL;
  762. WRL2LINESET* np = new WRL2LINESET( aParent );
  763. if( !np->Read( proc, this ) )
  764. {
  765. delete np;
  766. return false;
  767. }
  768. if( NULL != aNode )
  769. *aNode = (WRL2NODE*) np;
  770. return true;
  771. }
  772. bool WRL2BASE::readPointSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  773. {
  774. if( NULL != aNode )
  775. *aNode = NULL;
  776. WRL2POINTSET* np = new WRL2POINTSET( aParent );
  777. if( !np->Read( proc, this ) )
  778. {
  779. delete np;
  780. return false;
  781. }
  782. if( NULL != aNode )
  783. *aNode = (WRL2NODE*) np;
  784. return true;
  785. }
  786. bool WRL2BASE::readCoords( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  787. {
  788. if( NULL != aNode )
  789. *aNode = NULL;
  790. WRL2COORDS* np = new WRL2COORDS( aParent );
  791. if( !np->Read( proc, this ) )
  792. {
  793. delete np;
  794. return false;
  795. }
  796. if( NULL != aNode )
  797. *aNode = (WRL2NODE*) np;
  798. return true;
  799. }
  800. bool WRL2BASE::readNorms( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  801. {
  802. if( NULL != aNode )
  803. *aNode = NULL;
  804. WRL2NORMS* np = new WRL2NORMS( aParent );
  805. if( !np->Read( proc, this ) )
  806. {
  807. delete np;
  808. return false;
  809. }
  810. if( NULL != aNode )
  811. *aNode = (WRL2NODE*) np;
  812. return true;
  813. }
  814. bool WRL2BASE::readColor( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  815. {
  816. if( NULL != aNode )
  817. *aNode = NULL;
  818. WRL2COLOR* np = new WRL2COLOR( aParent );
  819. if( !np->Read( proc, this ) )
  820. {
  821. delete np;
  822. return false;
  823. }
  824. if( NULL != aNode )
  825. *aNode = (WRL2NODE*) np;
  826. return true;
  827. }
  828. bool WRL2BASE::readBox( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  829. {
  830. if( NULL != aNode )
  831. *aNode = NULL;
  832. WRL2BOX* np = new WRL2BOX( aParent );
  833. if( !np->Read( proc, this ) )
  834. {
  835. delete np;
  836. return false;
  837. }
  838. if( NULL != aNode )
  839. *aNode = (WRL2NODE*) np;
  840. return true;
  841. }
  842. bool WRL2BASE::readSwitch( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  843. {
  844. if( NULL != aNode )
  845. *aNode = NULL;
  846. WRL2SWITCH* np = new WRL2SWITCH( aParent );
  847. if( !np->Read( proc, this ) )
  848. {
  849. delete np;
  850. return false;
  851. }
  852. if( NULL != aNode )
  853. *aNode = (WRL2NODE*) np;
  854. return true;
  855. }
  856. bool WRL2BASE::readInline( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
  857. {
  858. if( NULL != aNode )
  859. *aNode = NULL;
  860. if( !m_useInline )
  861. {
  862. size_t line = 0;
  863. size_t column = 0;
  864. proc.GetFilePosData( line, column );
  865. if( !proc.DiscardNode() )
  866. {
  867. #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
  868. do {
  869. std::ostringstream ostr;
  870. ostr << proc.GetError() << "\n";
  871. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  872. ostr << " * [INFO] could not discard Inline node at line " << line;
  873. ostr << ", column " << column;
  874. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  875. } while( 0 );
  876. #endif
  877. return false;
  878. }
  879. return true;
  880. }
  881. WRL2INLINE* np = new WRL2INLINE( aParent );
  882. if( !np->Read( proc, this ) )
  883. {
  884. delete np;
  885. return false;
  886. }
  887. if( NULL != aNode )
  888. *aNode = (WRL2NODE*) np;
  889. return true;
  890. }
  891. SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent )
  892. {
  893. if( m_Children.empty() )
  894. return NULL;
  895. S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
  896. if( NULL != aParent && ptype != S3D::SGTYPE_SHAPE )
  897. {
  898. #ifdef DEBUG_VRML2
  899. do {
  900. std::ostringstream ostr;
  901. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  902. ostr << " * [BUG] WRL2BASE does not have a Transform parent (parent ID: ";
  903. ostr << ptype << ")";
  904. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  905. } while( 0 );
  906. #endif
  907. return NULL;
  908. }
  909. if( m_sgNode )
  910. {
  911. if( NULL != aParent )
  912. {
  913. if( NULL == S3D::GetSGNodeParent( m_sgNode )
  914. && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
  915. {
  916. return NULL;
  917. }
  918. else if( aParent != S3D::GetSGNodeParent( m_sgNode )
  919. && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
  920. {
  921. return NULL;
  922. }
  923. }
  924. return m_sgNode;
  925. }
  926. IFSG_TRANSFORM topNode( aParent );
  927. std::list< WRL2NODE* >::iterator sC = m_Children.begin();
  928. std::list< WRL2NODE* >::iterator eC = m_Children.end();
  929. WRL2NODES type;
  930. // Include only Shape and Transform nodes in the top node
  931. bool test = false; // set to true if there are any subnodes for display
  932. while( sC != eC )
  933. {
  934. type = (*sC)->GetNodeType();
  935. switch( type )
  936. {
  937. case WRL2_SHAPE:
  938. // wrap the shape in a transform
  939. do
  940. {
  941. IFSG_TRANSFORM wrapper( topNode.GetRawPtr() );
  942. SGNODE* pshape = (*sC)->TranslateToSG( wrapper.GetRawPtr() );
  943. if( NULL != pshape )
  944. test = true;
  945. else
  946. wrapper.Destroy();
  947. } while( 0 );
  948. break;
  949. case WRL2_TRANSFORM:
  950. case WRL2_SWITCH:
  951. case WRL2_INLINE:
  952. if( NULL != (*sC)->TranslateToSG( topNode.GetRawPtr() ) )
  953. test = true;
  954. break;
  955. default:
  956. break;
  957. }
  958. ++ sC;
  959. }
  960. if( false == test )
  961. {
  962. topNode.Destroy();
  963. return NULL;
  964. }
  965. m_sgNode = topNode.GetRawPtr();
  966. return m_sgNode;
  967. }