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.

439 lines
10 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
  5. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /**
  25. * @file vrml_v1_modelparser.cpp
  26. */
  27. #include <fctsys.h>
  28. #include <vector>
  29. #include <macros.h>
  30. #include <kicad_string.h>
  31. #include <info3d_visu.h>
  32. #include "3d_struct.h"
  33. #include "modelparsers.h"
  34. #include "vrml_aux.h"
  35. #define BUFLINE_SIZE 32
  36. /**
  37. * Trace mask used to enable or disable the trace output of the VRML V1 parser code.
  38. * The debug output can be turned on by setting the WXTRACE environment variable to
  39. * "KI_TRACE_VRML_V1_PARSER". See the wxWidgets documentation on wxLogTrace for
  40. * more information.
  41. */
  42. static const wxChar* traceVrmlV1Parser = wxT( "KI_TRACE_VRML_V1_PARSER" );
  43. VRML1_MODEL_PARSER::VRML1_MODEL_PARSER( S3D_MODEL_PARSER* aModelParser )
  44. {
  45. m_ModelParser = aModelParser;
  46. m_Master = m_ModelParser->GetMaster();
  47. m_model.reset();
  48. m_file = NULL;
  49. m_normalPerVertex = true;
  50. colorPerVertex = true;
  51. }
  52. VRML1_MODEL_PARSER::~VRML1_MODEL_PARSER()
  53. {
  54. }
  55. bool VRML1_MODEL_PARSER::Load( const wxString& aFilename )
  56. {
  57. char text[BUFLINE_SIZE];
  58. wxLogTrace( traceVrmlV1Parser, wxT( "Loading: %s" ), GetChars( aFilename ) );
  59. m_file = wxFopen( aFilename, wxT( "rt" ) );
  60. if( m_file == NULL )
  61. return false;
  62. // Switch the locale to standard C (needed to print floating point numbers)
  63. LOCALE_IO toggle;
  64. m_ModelParser->childs.clear();
  65. while( GetNextTag( m_file, text, sizeof(text) ) )
  66. {
  67. if( ( *text == '}' ) || ( *text == ']' ) )
  68. {
  69. continue;
  70. }
  71. if( strcmp( text, "Separator" ) == 0 )
  72. {
  73. m_model.reset( new S3D_MESH() );
  74. m_ModelParser->childs.push_back( m_model );
  75. read_separator();
  76. }
  77. }
  78. fclose( m_file );
  79. return true;
  80. }
  81. int VRML1_MODEL_PARSER::read_separator()
  82. {
  83. char text[BUFLINE_SIZE];
  84. // DBG( printf( "Separator\n" ) );
  85. while( GetNextTag( m_file, text, sizeof(text) ) )
  86. {
  87. if( strcmp( text, "Material" ) == 0 )
  88. {
  89. readMaterial();
  90. }
  91. else if( strcmp( text, "Coordinate3" ) == 0 )
  92. {
  93. readCoordinate3();
  94. }
  95. else if( strcmp( text, "IndexedFaceSet" ) == 0 )
  96. {
  97. readIndexedFaceSet();
  98. }
  99. else if( strcmp( text, "Separator" ) == 0 )
  100. {
  101. S3D_MESH_PTR parent( m_model.get() );
  102. S3D_MESH_PTR new_mesh_model( new S3D_MESH() );
  103. m_model->childs.push_back( new_mesh_model );
  104. m_model.reset( new_mesh_model.get() );
  105. // recursive
  106. read_separator();
  107. m_model.reset( parent.get() );
  108. }
  109. else if( ( *text != '}' ) )
  110. {
  111. // DBG( printf( "read_NotImplemented %s\n", text ) );
  112. Read_NotImplemented( m_file, '}' );
  113. }
  114. else
  115. break;
  116. }
  117. return 0;
  118. }
  119. int VRML1_MODEL_PARSER::readMaterial()
  120. {
  121. char text[BUFLINE_SIZE];
  122. S3D_MATERIAL* material = NULL;
  123. // DBG( printf( " readMaterial\n" ) );
  124. wxString mat_name;
  125. material = new S3D_MATERIAL( m_Master, mat_name );
  126. m_Master->Insert( material );
  127. m_model->m_Materials = material;
  128. while( GetNextTag( m_file, text, sizeof(text) ) )
  129. {
  130. if( *text == ']' )
  131. {
  132. continue;
  133. }
  134. if( *text == '}' )
  135. {
  136. return 0;
  137. }
  138. if( strcmp( text, "ambientColor" ) == 0 )
  139. {
  140. readMaterial_ambientColor();
  141. }
  142. else if( strcmp( text, "diffuseColor" ) == 0 )
  143. {
  144. readMaterial_diffuseColor();
  145. }
  146. else if( strcmp( text, "emissiveColor" ) == 0 )
  147. {
  148. readMaterial_emissiveColor();
  149. }
  150. else if( strcmp( text, "specularColor" ) == 0 )
  151. {
  152. readMaterial_specularColor();
  153. }
  154. else if( strcmp( text, "shininess" ) == 0 )
  155. {
  156. readMaterial_shininess();
  157. }
  158. else if( strcmp( text, "transparency" ) == 0 )
  159. {
  160. readMaterial_transparency();
  161. }
  162. }
  163. wxLogTrace( traceVrmlV1Parser, wxT( " readMaterial failed" ) );
  164. return -1;
  165. }
  166. int VRML1_MODEL_PARSER::readCoordinate3()
  167. {
  168. char text[BUFLINE_SIZE];
  169. // DBG( printf( " readCoordinate3\n" ) );
  170. while( GetNextTag( m_file, text, sizeof( text ) ) )
  171. {
  172. if( *text == ']' )
  173. {
  174. continue;
  175. }
  176. if( *text == '}' )
  177. {
  178. return 0;
  179. }
  180. if( strcmp( text, "point" ) == 0 )
  181. {
  182. readCoordinate3_point();
  183. }
  184. }
  185. wxLogTrace( traceVrmlV1Parser, wxT( " readCoordinate3 failed" ) );
  186. return -1;
  187. }
  188. int VRML1_MODEL_PARSER::readIndexedFaceSet()
  189. {
  190. char text[BUFLINE_SIZE];
  191. // DBG( printf( " readIndexedFaceSet\n" ) );
  192. while( GetNextTag( m_file, text, sizeof(text) ) )
  193. {
  194. if( *text == ']' )
  195. {
  196. continue;
  197. }
  198. if( *text == '}' )
  199. {
  200. return 0;
  201. }
  202. if( strcmp( text, "coordIndex" ) == 0 )
  203. {
  204. readIndexedFaceSet_coordIndex();
  205. }
  206. else if( strcmp( text, "materialIndex" ) == 0 )
  207. {
  208. readIndexedFaceSet_materialIndex();
  209. }
  210. }
  211. wxLogTrace( traceVrmlV1Parser, wxT( " readIndexedFaceSet failed" ) );
  212. return -1;
  213. }
  214. int VRML1_MODEL_PARSER::readMaterial_ambientColor()
  215. {
  216. // DBG( printf( " readMaterial_ambientColor\n" ) );
  217. return ParseVertexList( m_file, m_model->m_Materials->m_AmbientColor );
  218. }
  219. int VRML1_MODEL_PARSER::readMaterial_diffuseColor()
  220. {
  221. // DBG( printf( " readMaterial_diffuseColor\n" ) );
  222. return ParseVertexList( m_file, m_model->m_Materials->m_DiffuseColor );
  223. }
  224. int VRML1_MODEL_PARSER::readMaterial_emissiveColor()
  225. {
  226. // DBG( printf( " readMaterial_emissiveColor\n" ) );
  227. int ret = ParseVertexList( m_file, m_model->m_Materials->m_EmissiveColor );
  228. if( m_Master->m_use_modelfile_emissiveColor == false )
  229. {
  230. m_model->m_Materials->m_EmissiveColor.clear();
  231. }
  232. return ret;
  233. }
  234. int VRML1_MODEL_PARSER::readMaterial_specularColor()
  235. {
  236. // DBG( printf( " readMaterial_specularColor\n" ) );
  237. int ret = ParseVertexList( m_file, m_model->m_Materials->m_SpecularColor );
  238. if( m_Master->m_use_modelfile_specularColor == false )
  239. {
  240. m_model->m_Materials->m_SpecularColor.clear();
  241. }
  242. return ret;
  243. }
  244. int VRML1_MODEL_PARSER::readMaterial_shininess()
  245. {
  246. // DBG( printf( " readMaterial_shininess\n" ) );
  247. m_model->m_Materials->m_Shininess.clear();
  248. float shininess_value;
  249. while( fscanf( m_file, "%f,", &shininess_value ) )
  250. {
  251. // VRML value is normalized and openGL expects a value 0 - 128
  252. shininess_value = shininess_value * 128.0f;
  253. m_model->m_Materials->m_Shininess.push_back( shininess_value );
  254. }
  255. if( m_Master->m_use_modelfile_shininess == false )
  256. {
  257. m_model->m_Materials->m_Shininess.clear();
  258. }
  259. // DBG( printf( " m_Shininess.size: %ld\n", m_model->m_Materials->m_Shininess.size() ) );
  260. return 0;
  261. }
  262. int VRML1_MODEL_PARSER::readMaterial_transparency()
  263. {
  264. // DBG( printf( " readMaterial_transparency\n" ) );
  265. m_model->m_Materials->m_Transparency.clear();
  266. float tmp;
  267. while( fscanf( m_file, "%f,", &tmp ) )
  268. {
  269. m_model->m_Materials->m_Transparency.push_back( tmp );
  270. }
  271. if( m_Master->m_use_modelfile_transparency == false )
  272. {
  273. m_model->m_Materials->m_Transparency.clear();
  274. }
  275. // DBG( printf( " m_Transparency.size: %ld\n", m_model->m_Materials->m_Transparency.size() ) );
  276. return 0;
  277. }
  278. int VRML1_MODEL_PARSER::readCoordinate3_point()
  279. {
  280. // DBG( printf( " readCoordinate3_point\n" ) );
  281. if( ParseVertexList( m_file, m_model->m_Point ) == 0 )
  282. {
  283. return 0;
  284. }
  285. wxLogTrace( traceVrmlV1Parser, wxT( " readCoordinate3_point failed" ) );
  286. return -1;
  287. }
  288. int VRML1_MODEL_PARSER::readIndexedFaceSet_coordIndex()
  289. {
  290. // DBG( printf( " readIndexedFaceSet_coordIndex\n" ) );
  291. m_model->m_CoordIndex.clear();
  292. glm::ivec3 coord;
  293. int dummy; // should be -1
  294. while( fscanf( m_file, "%d,%d,%d,%d,", &coord[0], &coord[1], &coord[2], &dummy ) )
  295. {
  296. std::vector<int> coord_list;
  297. coord_list.resize( 3 );
  298. coord_list[0] = coord[0];
  299. coord_list[1] = coord[1];
  300. coord_list[2] = coord[2];
  301. if( (coord[0] == coord[1])
  302. || (coord[0] == coord[2])
  303. || (coord[2] == coord[1]) )
  304. {
  305. wxLogTrace( traceVrmlV1Parser, wxT( " invalid coordIndex at index %zu (%d, %d, %d, %d)" ),
  306. m_model->m_CoordIndex.size() + 1, coord[0], coord[1], coord[2], dummy );
  307. }
  308. if( dummy != -1 )
  309. {
  310. wxLogTrace( traceVrmlV1Parser, wxT( " Error at index %zu, -1 Expected, got %d" ),
  311. m_model->m_CoordIndex.size() + 1, dummy );
  312. }
  313. m_model->m_CoordIndex.push_back( coord_list );
  314. }
  315. // DBG( printf( " m_CoordIndex.size: %ld\n", m_model->m_CoordIndex.size() ) );
  316. return 0;
  317. }
  318. int VRML1_MODEL_PARSER::readIndexedFaceSet_materialIndex()
  319. {
  320. // DBG( printf( " readIndexedFaceSet_materialIndex\n" ) );
  321. m_model->m_MaterialIndexPerFace.clear();
  322. int index;
  323. while( fscanf( m_file, "%d,", &index ) )
  324. {
  325. m_model->m_MaterialIndexPerFace.push_back( index );
  326. }
  327. // DBG( printf( " m_MaterialIndexPerFace.size: %ld\n", m_model->m_MaterialIndexPerFace.size() ) );
  328. return 0;
  329. }