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.

248 lines
6.8 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. // note: this was copied from the vrml1_separator class. the difference
  24. // between a separator and a group is that a group propagates its
  25. // current settings to its parent. While it would be possible to
  26. // implement the separator as a derived class, it is easy enough to
  27. // simply duplicate the code
  28. #include <iostream>
  29. #include <sstream>
  30. #include <wx/log.h>
  31. #include "vrml1_base.h"
  32. #include "vrml1_group.h"
  33. #include "plugins/3dapi/ifsg_all.h"
  34. WRL1GROUP::WRL1GROUP( NAMEREGISTER* aDictionary ) : WRL1NODE( aDictionary )
  35. {
  36. m_Type = WRL1_GROUP;
  37. return;
  38. }
  39. WRL1GROUP::WRL1GROUP( NAMEREGISTER* aDictionary, WRL1NODE* aParent ) :
  40. WRL1NODE( aDictionary )
  41. {
  42. m_Type = WRL1_GROUP;
  43. m_Parent = aParent;
  44. if( NULL != m_Parent )
  45. m_Parent->AddChildNode( this );
  46. return;
  47. }
  48. WRL1GROUP::~WRL1GROUP()
  49. {
  50. #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
  51. do {
  52. std::ostringstream ostr;
  53. ostr << " * [INFO] Destroying Group with " << m_Children.size();
  54. ostr << " children, " << m_Refs.size() << " references and ";
  55. ostr << m_BackPointers.size() << " backpointers";
  56. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  57. } while( 0 );
  58. #endif
  59. return;
  60. }
  61. // functions inherited from WRL1NODE
  62. bool WRL1GROUP::Read( WRLPROC& proc, WRL1BASE* aTopNode )
  63. {
  64. if( NULL == aTopNode )
  65. {
  66. #ifdef DEBUG_VRML1
  67. do {
  68. std::ostringstream ostr;
  69. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  70. ostr << " * [BUG] aTopNode is NULL";
  71. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  72. } while( 0 );
  73. #endif
  74. return false;
  75. }
  76. size_t line, column;
  77. proc.GetFilePosData( line, column );
  78. char tok = proc.Peek();
  79. if( proc.eof() )
  80. {
  81. #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
  82. do {
  83. std::ostringstream ostr;
  84. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  85. ostr << " * [INFO] bad file format; unexpected eof at line ";
  86. ostr << line << ", column " << column;
  87. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  88. } while( 0 );
  89. #endif
  90. return false;
  91. }
  92. if( '{' != tok )
  93. {
  94. #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
  95. do {
  96. std::ostringstream ostr;
  97. ostr << proc.GetError() << "\n";
  98. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  99. ostr << " * [INFO] bad file format; expecting '{' but got '" << tok;
  100. ostr << "' at line " << line << ", column " << column;
  101. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  102. } while( 0 );
  103. #endif
  104. return false;
  105. }
  106. proc.Pop();
  107. while( true )
  108. {
  109. if( proc.Peek() == '}' )
  110. {
  111. proc.Pop();
  112. break;
  113. }
  114. proc.GetFilePosData( line, column );
  115. if( !aTopNode->ReadNode( proc, this, NULL ) )
  116. {
  117. #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
  118. do {
  119. std::ostringstream ostr;
  120. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  121. ostr << " * [INFO] bad file format; unexpected eof at line ";
  122. ostr << line << ", column " << column;
  123. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  124. } while( 0 );
  125. #endif
  126. return false;
  127. }
  128. if( proc.Peek() == ',' )
  129. proc.Pop();
  130. } // while( true ) -- reading contents of Group{}
  131. return true;
  132. }
  133. SGNODE* WRL1GROUP::TranslateToSG( SGNODE* aParent, WRL1STATUS* sp )
  134. {
  135. #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
  136. do {
  137. std::ostringstream ostr;
  138. ostr << " * [INFO] Translating Group with " << m_Children.size();
  139. ostr << " children, " << m_Refs.size() << " references and ";
  140. ostr << m_BackPointers.size() << " backpointers (total ";
  141. ostr << m_Items.size() << " items)";
  142. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  143. } while( 0 );
  144. #endif
  145. if( !m_Parent )
  146. {
  147. #ifdef DEBUG
  148. do {
  149. std::ostringstream ostr;
  150. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  151. ostr << " * [BUG] Group has no parent";
  152. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  153. } while( 0 );
  154. #endif
  155. return NULL;
  156. }
  157. if( WRL1_BASE != m_Parent->GetNodeType() )
  158. {
  159. if( NULL == sp )
  160. {
  161. #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
  162. wxLogTrace( MASK_VRML, " * [INFO] bad model: no base data given\n" );
  163. #endif
  164. return NULL;
  165. }
  166. }
  167. else if( NULL == sp )
  168. {
  169. m_current.Init();
  170. sp = &m_current;
  171. }
  172. S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
  173. if( NULL != aParent && ptype != S3D::SGTYPE_TRANSFORM )
  174. {
  175. #ifdef DEBUG_VRML1
  176. do {
  177. std::ostringstream ostr;
  178. ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
  179. ostr << " * [BUG] Group does not have a Transform parent (parent ID: ";
  180. ostr << ptype << ")";
  181. wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
  182. } while( 0 );
  183. #endif
  184. return NULL;
  185. }
  186. IFSG_TRANSFORM txNode( aParent );
  187. bool hasContent = false;
  188. std::list< WRL1NODE* >::iterator sI = m_Items.begin();
  189. std::list< WRL1NODE* >::iterator eI = m_Items.end();
  190. SGNODE* node = txNode.GetRawPtr();
  191. while( sI != eI )
  192. {
  193. if( NULL != (*sI)->TranslateToSG( node, sp ) )
  194. hasContent = true;
  195. ++sI;
  196. }
  197. if( !hasContent )
  198. {
  199. txNode.Destroy();
  200. return NULL;
  201. }
  202. return node;
  203. }