Loading 3d-viewer/3d_frame.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <fctsys.h> #include <kiface_i.h> #include <pgm_base.h> #include <macros.h> #include <3d_viewer.h> #include <3d_canvas.h> Loading Loading @@ -133,8 +134,6 @@ EDA_3D_FRAME::EDA_3D_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, #if wxCHECK_VERSION( 3, 0, 0 ) unsigned int ii; // Check if the canvas supports multisampling. if( EDA_3D_CANVAS::IsDisplaySupported( attrs ) ) { Loading @@ -142,7 +141,7 @@ EDA_3D_FRAME::EDA_3D_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, int maxSamples = 8; // Any higher doesn't change anything. int samplesOffset = 0; for( ii = 0; ii < sizeof( attrs ) / sizeof( attrs[0] ) - 1; ii += 2 ) for( unsigned int ii = 0; ii < DIM( attrs ); ii += 2 ) { if( attrs[ii] == WX_GL_SAMPLES ) { Loading @@ -162,7 +161,7 @@ EDA_3D_FRAME::EDA_3D_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, else { // Disable multisampling for( ii = 0; ii < sizeof( attrs ) / sizeof( attrs[0] ) - 1; ii += 2 ) for( unsigned int ii = 0; ii < DIM( attrs ); ii += 2 ) { if( attrs[ii] == WX_GL_SAMPLE_BUFFERS ) { Loading 3d-viewer/vrml_aux.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -109,7 +109,8 @@ char* GetNextTag( FILE* File, char* tag ) char *dst = &tag[1]; while( fscanf( File, "%c", dst) ) { if( (*dst == ' ') || (*dst == '[') || (*dst == '{') || (*dst == '\t') || (*dst == '\n')|| (*dst == '\r') ) if( (*dst == ' ') || (*dst == '[') || (*dst == '{') || (*dst == '\t') || (*dst == '\n')|| (*dst == '\r') ) { *dst = 0; break; Loading 3d-viewer/vrml_v2_modelparser.cpp +131 −64 Original line number Diff line number Diff line Loading @@ -109,7 +109,8 @@ void VRML2_MODEL_PARSER::Load( const wxString aFilename ) read_Transform(); } else if( strcmp( text, "DEF" ) == 0 ) } else if( strcmp( text, "DEF" ) == 0 ) { m_model = new S3D_MESH(); Loading Loading @@ -155,36 +156,73 @@ int VRML2_MODEL_PARSER::read_Transform() if( strcmp( text, "translation" ) == 0 ) { parseVertex( m_file, m_model->m_translation ); } else if( strcmp( text, "rotation" ) == 0 ) } else if( strcmp( text, "rotation" ) == 0 ) { if( fscanf( m_file, "%f %f %f %f", &m_model->m_rotation[0], &m_model->m_rotation[1], &m_model->m_rotation[2], &m_model->m_rotation[3] ) != 4 ) { // !TODO: log errors m_model->m_rotation[0] = 0.0f; m_model->m_rotation[1] = 0.0f; m_model->m_rotation[2] = 0.0f; m_model->m_rotation[3] = 0.0f; } else { fscanf( m_file, "%f %f %f %f", &m_model->m_rotation[0], &m_model->m_rotation[1], &m_model->m_rotation[2], &m_model->m_rotation[3]); m_model->m_rotation[3] = m_model->m_rotation[3] * 180.0f / 3.14f; // !TODO: use constants or functions } else if( strcmp( text, "scale" ) == 0 ) } } else if( strcmp( text, "scale" ) == 0 ) { parseVertex( m_file, m_model->m_scale ); } else if( strcmp( text, "scaleOrientation" ) == 0 ) } else if( strcmp( text, "scaleOrientation" ) == 0 ) { // this m_scaleOrientation is not implemented, but it will be parsed if( fscanf( m_file, "%f %f %f %f", &m_model->m_scaleOrientation[0], &m_model->m_scaleOrientation[1], &m_model->m_scaleOrientation[2], &m_model->m_scaleOrientation[3] ) != 4 ) { fscanf( m_file, "%f %f %f %f", &m_model->m_scaleOrientation[0], &m_model->m_scaleOrientation[1], &m_model->m_scaleOrientation[2], &m_model->m_scaleOrientation[3]); } else if( strcmp( text, "center" ) == 0 ) // !TODO: log errors m_model->m_scaleOrientation[0] = 0.0f; m_model->m_scaleOrientation[1] = 0.0f; m_model->m_scaleOrientation[2] = 0.0f; m_model->m_scaleOrientation[3] = 0.0f; } } else if( strcmp( text, "center" ) == 0 ) { parseVertex( m_file, m_model->m_center ); } else if( strcmp( text, "children" ) == 0 ) } else if( strcmp( text, "children" ) == 0 ) { // skip } else if( strcmp( text, "Switch" ) == 0 ) } else if( strcmp( text, "Switch" ) == 0 ) { // skip } else if( strcmp( text, "whichChoice" ) == 0 ) } else if( strcmp( text, "whichChoice" ) == 0 ) { int dummy; fscanf( m_file, "%d", &dummy ); } else if( strcmp( text, "choice" ) == 0 ) if( fscanf( m_file, "%d", &dummy ) != 1 ) { // !TODO: log errors } } else if( strcmp( text, "choice" ) == 0 ) { // skip } else if( strcmp( text, "Group" ) == 0 ) } else if( strcmp( text, "Group" ) == 0 ) { // skip } else if( strcmp( text, "Shape" ) == 0 ) } else if( strcmp( text, "Shape" ) == 0 ) { S3D_MESH *parent = m_model; Loading @@ -198,10 +236,12 @@ int VRML2_MODEL_PARSER::read_Transform() m_model = parent; } else if( strcmp( text, "DEF" ) == 0 ) } else if( strcmp( text, "DEF" ) == 0 ) { read_DEF(); } else } else { DBG( printf( " %s NotImplemented\n", text ) ); read_NotImplemented( m_file, '}' ); Loading Loading @@ -238,16 +278,20 @@ int VRML2_MODEL_PARSER::read_DEF() } else if( strcmp( text, "children" ) == 0 ) { // skip } else if( strcmp( text, "Switch" ) == 0 ) } else if( strcmp( text, "Switch" ) == 0 ) { // skip } else if( strcmp( text, "whichChoice" ) == 0 ) } else if( strcmp( text, "whichChoice" ) == 0 ) { // skip } else if( strcmp( text, "choice" ) == 0 ) } else if( strcmp( text, "choice" ) == 0 ) { // skip }else if( strcmp( text, "Shape" ) == 0 ) } else if( strcmp( text, "Shape" ) == 0 ) { S3D_MESH *parent = m_model; Loading Loading @@ -290,16 +334,20 @@ int VRML2_MODEL_PARSER::read_Shape() if( strcmp( text, "appearance" ) == 0 ) { //skip } else if( strcmp( text, "Appearance" ) == 0 ) } else if( strcmp( text, "Appearance" ) == 0 ) { read_Appearance(); } else if( strcmp( text, "geometry" ) == 0 ) } else if( strcmp( text, "geometry" ) == 0 ) { //skip } else if( strcmp( text, "IndexedFaceSet" ) == 0 ) } else if( strcmp( text, "IndexedFaceSet" ) == 0 ) { read_IndexedFaceSet(); } else } else { DBG( printf( " %s NotImplemented\n", text ) ); read_NotImplemented( m_file, '}' ); Loading Loading @@ -362,7 +410,8 @@ int VRML2_MODEL_PARSER::read_material() { return read_Material(); } } else if( strcmp( text, "DEF" ) == 0 ) } else if( strcmp( text, "DEF" ) == 0 ) { //DBG( printf( "DEF") ); Loading @@ -387,7 +436,8 @@ int VRML2_MODEL_PARSER::read_material() } } } } else if( strcmp( text, "USE" ) == 0 ) } else if( strcmp( text, "USE" ) == 0 ) { //DBG( printf( "USE") ); Loading Loading @@ -450,7 +500,8 @@ int VRML2_MODEL_PARSER::read_Material() { m_model->m_Materials->m_EmissiveColor.push_back( vertex ); } } else if( strcmp( text, "specularColor" ) == 0 ) } else if( strcmp( text, "specularColor" ) == 0 ) { //DBG( printf( " specularColor") ); parseVertex ( m_file, vertex); Loading @@ -459,7 +510,8 @@ int VRML2_MODEL_PARSER::read_Material() { m_model->m_Materials->m_SpecularColor.push_back( vertex ); } } else if( strcmp( text, "ambientIntensity" ) == 0 ) } else if( strcmp( text, "ambientIntensity" ) == 0 ) { float ambientIntensity; parseFloat( m_file, &ambientIntensity ); Loading @@ -468,7 +520,8 @@ int VRML2_MODEL_PARSER::read_Material() { m_model->m_Materials->m_AmbientColor.push_back( glm::vec3( ambientIntensity, ambientIntensity, ambientIntensity ) ); } } else if( strcmp( text, "transparency" ) == 0 ) } else if( strcmp( text, "transparency" ) == 0 ) { float transparency; parseFloat( m_file, &transparency ); Loading @@ -477,7 +530,8 @@ int VRML2_MODEL_PARSER::read_Material() { m_model->m_Materials->m_Transparency.push_back( transparency ); } } else if( strcmp( text, "shininess" ) == 0 ) } else if( strcmp( text, "shininess" ) == 0 ) { float shininess; parseFloat( m_file, &shininess ); Loading Loading @@ -528,7 +582,8 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet() m_normalPerVertex = true; } } } else if( strcmp( text, "colorPerVertex" ) == 0 ) } else if( strcmp( text, "colorPerVertex" ) == 0 ) { GetNextTag( m_file, text ); if( strcmp( text, "TRUE" ) ) Loading @@ -540,22 +595,28 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet() colorPerVertex = false; } } else if( strcmp( text, "Coordinate" ) == 0 ) } else if( strcmp( text, "Coordinate" ) == 0 ) { read_Coordinate(); } else if( strcmp( text, "Normal" ) == 0 ) } else if( strcmp( text, "Normal" ) == 0 ) { read_Normal(); } else if( strcmp( text, "normalIndex" ) == 0 ) } else if( strcmp( text, "normalIndex" ) == 0 ) { read_NormalIndex(); } else if( strcmp( text, "Color" ) == 0 ) } else if( strcmp( text, "Color" ) == 0 ) { read_Color(); } else if( strcmp( text, "coordIndex" ) == 0 ) } else if( strcmp( text, "coordIndex" ) == 0 ) { read_coordIndex(); } else if( strcmp( text, "colorIndex" ) == 0 ) } else if( strcmp( text, "colorIndex" ) == 0 ) { read_colorIndex(); } Loading Loading @@ -583,14 +644,17 @@ int VRML2_MODEL_PARSER::read_colorIndex() { // it only implemented color per face, so it will store as the first in the list m_model->m_MaterialIndex.push_back( first_index ); } else } else { first_index = index; } } } else } else { int index; while( fscanf( m_file, "%d,", &index ) ) { m_model->m_MaterialIndex.push_back( index ); Loading Loading @@ -622,7 +686,8 @@ int VRML2_MODEL_PARSER::read_NormalIndex() m_model->m_NormalIndex.push_back( coord_list ); //DBG( printf( " size: %lu ", coord_list.size()) ); coord_list.clear(); } else } else { coord_list.push_back( dummy ); //DBG( printf( "%d ", dummy) ); Loading Loading @@ -654,7 +719,8 @@ int VRML2_MODEL_PARSER::read_coordIndex() m_model->m_CoordIndex.push_back( coord_list ); //DBG( printf( " size: %lu ", coord_list.size()) ); coord_list.clear(); } else } else { coord_list.push_back( dummy ); //DBG( printf( "%d ", dummy) ); Loading Loading @@ -723,7 +789,8 @@ int VRML2_MODEL_PARSER::read_Normal() if(m_normalPerVertex == false ) { parseVertexList( m_file, m_model->m_PerFaceNormalsNormalized ); } else } else { parseVertexList( m_file, m_model->m_PerVertexNormalsNormalized ); Loading Loading
3d-viewer/3d_frame.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <fctsys.h> #include <kiface_i.h> #include <pgm_base.h> #include <macros.h> #include <3d_viewer.h> #include <3d_canvas.h> Loading Loading @@ -133,8 +134,6 @@ EDA_3D_FRAME::EDA_3D_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, #if wxCHECK_VERSION( 3, 0, 0 ) unsigned int ii; // Check if the canvas supports multisampling. if( EDA_3D_CANVAS::IsDisplaySupported( attrs ) ) { Loading @@ -142,7 +141,7 @@ EDA_3D_FRAME::EDA_3D_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, int maxSamples = 8; // Any higher doesn't change anything. int samplesOffset = 0; for( ii = 0; ii < sizeof( attrs ) / sizeof( attrs[0] ) - 1; ii += 2 ) for( unsigned int ii = 0; ii < DIM( attrs ); ii += 2 ) { if( attrs[ii] == WX_GL_SAMPLES ) { Loading @@ -162,7 +161,7 @@ EDA_3D_FRAME::EDA_3D_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, else { // Disable multisampling for( ii = 0; ii < sizeof( attrs ) / sizeof( attrs[0] ) - 1; ii += 2 ) for( unsigned int ii = 0; ii < DIM( attrs ); ii += 2 ) { if( attrs[ii] == WX_GL_SAMPLE_BUFFERS ) { Loading
3d-viewer/vrml_aux.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -109,7 +109,8 @@ char* GetNextTag( FILE* File, char* tag ) char *dst = &tag[1]; while( fscanf( File, "%c", dst) ) { if( (*dst == ' ') || (*dst == '[') || (*dst == '{') || (*dst == '\t') || (*dst == '\n')|| (*dst == '\r') ) if( (*dst == ' ') || (*dst == '[') || (*dst == '{') || (*dst == '\t') || (*dst == '\n')|| (*dst == '\r') ) { *dst = 0; break; Loading
3d-viewer/vrml_v2_modelparser.cpp +131 −64 Original line number Diff line number Diff line Loading @@ -109,7 +109,8 @@ void VRML2_MODEL_PARSER::Load( const wxString aFilename ) read_Transform(); } else if( strcmp( text, "DEF" ) == 0 ) } else if( strcmp( text, "DEF" ) == 0 ) { m_model = new S3D_MESH(); Loading Loading @@ -155,36 +156,73 @@ int VRML2_MODEL_PARSER::read_Transform() if( strcmp( text, "translation" ) == 0 ) { parseVertex( m_file, m_model->m_translation ); } else if( strcmp( text, "rotation" ) == 0 ) } else if( strcmp( text, "rotation" ) == 0 ) { if( fscanf( m_file, "%f %f %f %f", &m_model->m_rotation[0], &m_model->m_rotation[1], &m_model->m_rotation[2], &m_model->m_rotation[3] ) != 4 ) { // !TODO: log errors m_model->m_rotation[0] = 0.0f; m_model->m_rotation[1] = 0.0f; m_model->m_rotation[2] = 0.0f; m_model->m_rotation[3] = 0.0f; } else { fscanf( m_file, "%f %f %f %f", &m_model->m_rotation[0], &m_model->m_rotation[1], &m_model->m_rotation[2], &m_model->m_rotation[3]); m_model->m_rotation[3] = m_model->m_rotation[3] * 180.0f / 3.14f; // !TODO: use constants or functions } else if( strcmp( text, "scale" ) == 0 ) } } else if( strcmp( text, "scale" ) == 0 ) { parseVertex( m_file, m_model->m_scale ); } else if( strcmp( text, "scaleOrientation" ) == 0 ) } else if( strcmp( text, "scaleOrientation" ) == 0 ) { // this m_scaleOrientation is not implemented, but it will be parsed if( fscanf( m_file, "%f %f %f %f", &m_model->m_scaleOrientation[0], &m_model->m_scaleOrientation[1], &m_model->m_scaleOrientation[2], &m_model->m_scaleOrientation[3] ) != 4 ) { fscanf( m_file, "%f %f %f %f", &m_model->m_scaleOrientation[0], &m_model->m_scaleOrientation[1], &m_model->m_scaleOrientation[2], &m_model->m_scaleOrientation[3]); } else if( strcmp( text, "center" ) == 0 ) // !TODO: log errors m_model->m_scaleOrientation[0] = 0.0f; m_model->m_scaleOrientation[1] = 0.0f; m_model->m_scaleOrientation[2] = 0.0f; m_model->m_scaleOrientation[3] = 0.0f; } } else if( strcmp( text, "center" ) == 0 ) { parseVertex( m_file, m_model->m_center ); } else if( strcmp( text, "children" ) == 0 ) } else if( strcmp( text, "children" ) == 0 ) { // skip } else if( strcmp( text, "Switch" ) == 0 ) } else if( strcmp( text, "Switch" ) == 0 ) { // skip } else if( strcmp( text, "whichChoice" ) == 0 ) } else if( strcmp( text, "whichChoice" ) == 0 ) { int dummy; fscanf( m_file, "%d", &dummy ); } else if( strcmp( text, "choice" ) == 0 ) if( fscanf( m_file, "%d", &dummy ) != 1 ) { // !TODO: log errors } } else if( strcmp( text, "choice" ) == 0 ) { // skip } else if( strcmp( text, "Group" ) == 0 ) } else if( strcmp( text, "Group" ) == 0 ) { // skip } else if( strcmp( text, "Shape" ) == 0 ) } else if( strcmp( text, "Shape" ) == 0 ) { S3D_MESH *parent = m_model; Loading @@ -198,10 +236,12 @@ int VRML2_MODEL_PARSER::read_Transform() m_model = parent; } else if( strcmp( text, "DEF" ) == 0 ) } else if( strcmp( text, "DEF" ) == 0 ) { read_DEF(); } else } else { DBG( printf( " %s NotImplemented\n", text ) ); read_NotImplemented( m_file, '}' ); Loading Loading @@ -238,16 +278,20 @@ int VRML2_MODEL_PARSER::read_DEF() } else if( strcmp( text, "children" ) == 0 ) { // skip } else if( strcmp( text, "Switch" ) == 0 ) } else if( strcmp( text, "Switch" ) == 0 ) { // skip } else if( strcmp( text, "whichChoice" ) == 0 ) } else if( strcmp( text, "whichChoice" ) == 0 ) { // skip } else if( strcmp( text, "choice" ) == 0 ) } else if( strcmp( text, "choice" ) == 0 ) { // skip }else if( strcmp( text, "Shape" ) == 0 ) } else if( strcmp( text, "Shape" ) == 0 ) { S3D_MESH *parent = m_model; Loading Loading @@ -290,16 +334,20 @@ int VRML2_MODEL_PARSER::read_Shape() if( strcmp( text, "appearance" ) == 0 ) { //skip } else if( strcmp( text, "Appearance" ) == 0 ) } else if( strcmp( text, "Appearance" ) == 0 ) { read_Appearance(); } else if( strcmp( text, "geometry" ) == 0 ) } else if( strcmp( text, "geometry" ) == 0 ) { //skip } else if( strcmp( text, "IndexedFaceSet" ) == 0 ) } else if( strcmp( text, "IndexedFaceSet" ) == 0 ) { read_IndexedFaceSet(); } else } else { DBG( printf( " %s NotImplemented\n", text ) ); read_NotImplemented( m_file, '}' ); Loading Loading @@ -362,7 +410,8 @@ int VRML2_MODEL_PARSER::read_material() { return read_Material(); } } else if( strcmp( text, "DEF" ) == 0 ) } else if( strcmp( text, "DEF" ) == 0 ) { //DBG( printf( "DEF") ); Loading @@ -387,7 +436,8 @@ int VRML2_MODEL_PARSER::read_material() } } } } else if( strcmp( text, "USE" ) == 0 ) } else if( strcmp( text, "USE" ) == 0 ) { //DBG( printf( "USE") ); Loading Loading @@ -450,7 +500,8 @@ int VRML2_MODEL_PARSER::read_Material() { m_model->m_Materials->m_EmissiveColor.push_back( vertex ); } } else if( strcmp( text, "specularColor" ) == 0 ) } else if( strcmp( text, "specularColor" ) == 0 ) { //DBG( printf( " specularColor") ); parseVertex ( m_file, vertex); Loading @@ -459,7 +510,8 @@ int VRML2_MODEL_PARSER::read_Material() { m_model->m_Materials->m_SpecularColor.push_back( vertex ); } } else if( strcmp( text, "ambientIntensity" ) == 0 ) } else if( strcmp( text, "ambientIntensity" ) == 0 ) { float ambientIntensity; parseFloat( m_file, &ambientIntensity ); Loading @@ -468,7 +520,8 @@ int VRML2_MODEL_PARSER::read_Material() { m_model->m_Materials->m_AmbientColor.push_back( glm::vec3( ambientIntensity, ambientIntensity, ambientIntensity ) ); } } else if( strcmp( text, "transparency" ) == 0 ) } else if( strcmp( text, "transparency" ) == 0 ) { float transparency; parseFloat( m_file, &transparency ); Loading @@ -477,7 +530,8 @@ int VRML2_MODEL_PARSER::read_Material() { m_model->m_Materials->m_Transparency.push_back( transparency ); } } else if( strcmp( text, "shininess" ) == 0 ) } else if( strcmp( text, "shininess" ) == 0 ) { float shininess; parseFloat( m_file, &shininess ); Loading Loading @@ -528,7 +582,8 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet() m_normalPerVertex = true; } } } else if( strcmp( text, "colorPerVertex" ) == 0 ) } else if( strcmp( text, "colorPerVertex" ) == 0 ) { GetNextTag( m_file, text ); if( strcmp( text, "TRUE" ) ) Loading @@ -540,22 +595,28 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet() colorPerVertex = false; } } else if( strcmp( text, "Coordinate" ) == 0 ) } else if( strcmp( text, "Coordinate" ) == 0 ) { read_Coordinate(); } else if( strcmp( text, "Normal" ) == 0 ) } else if( strcmp( text, "Normal" ) == 0 ) { read_Normal(); } else if( strcmp( text, "normalIndex" ) == 0 ) } else if( strcmp( text, "normalIndex" ) == 0 ) { read_NormalIndex(); } else if( strcmp( text, "Color" ) == 0 ) } else if( strcmp( text, "Color" ) == 0 ) { read_Color(); } else if( strcmp( text, "coordIndex" ) == 0 ) } else if( strcmp( text, "coordIndex" ) == 0 ) { read_coordIndex(); } else if( strcmp( text, "colorIndex" ) == 0 ) } else if( strcmp( text, "colorIndex" ) == 0 ) { read_colorIndex(); } Loading Loading @@ -583,14 +644,17 @@ int VRML2_MODEL_PARSER::read_colorIndex() { // it only implemented color per face, so it will store as the first in the list m_model->m_MaterialIndex.push_back( first_index ); } else } else { first_index = index; } } } else } else { int index; while( fscanf( m_file, "%d,", &index ) ) { m_model->m_MaterialIndex.push_back( index ); Loading Loading @@ -622,7 +686,8 @@ int VRML2_MODEL_PARSER::read_NormalIndex() m_model->m_NormalIndex.push_back( coord_list ); //DBG( printf( " size: %lu ", coord_list.size()) ); coord_list.clear(); } else } else { coord_list.push_back( dummy ); //DBG( printf( "%d ", dummy) ); Loading Loading @@ -654,7 +719,8 @@ int VRML2_MODEL_PARSER::read_coordIndex() m_model->m_CoordIndex.push_back( coord_list ); //DBG( printf( " size: %lu ", coord_list.size()) ); coord_list.clear(); } else } else { coord_list.push_back( dummy ); //DBG( printf( "%d ", dummy) ); Loading Loading @@ -723,7 +789,8 @@ int VRML2_MODEL_PARSER::read_Normal() if(m_normalPerVertex == false ) { parseVertexList( m_file, m_model->m_PerFaceNormalsNormalized ); } else } else { parseVertexList( m_file, m_model->m_PerVertexNormalsNormalized ); Loading