Skip to content

Commit 85c1294

Browse files
Merge pull request #122 from sketchfab/bug/updates-to-blender4
Updates plugin to Blender 4, and minor fixes
2 parents 5a0769c + ea511b4 commit 85c1294

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+56
-4692
lines changed

.gitignore

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
addons/.idea/
2-
addons/io_scene_gltf2/.idea/
3-
addons/io_sketchfab_plugin/io/*
4-
releases/*
1+
.idea/
2+
releases/*
3+
__pycache__/
4+
**.pyc
5+
sketchfab/.cache

.gitmodules

Lines changed: 0 additions & 4 deletions
This file was deleted.

.project

Lines changed: 0 additions & 17 deletions
This file was deleted.

.pydevproject

Lines changed: 0 additions & 8 deletions
This file was deleted.

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ After installing the addon, two optional settings are available:
2424

2525
<p align="center"><img style="max-width:100%" src="https://user-images.githubusercontent.com/52042414/158475442-3e6c90c3-983d-4d91-8f58-f8c3d20216dc.jpg"></p>
2626

27-
**Note to Blender 2.79 OSX/Linux users:** The addon uses an embedded version of the SSL library. Do not hesitate to [report an issue](#report-an-issue) if you encounter any issue related to SSL.
28-
2927
<br>
3028

3129
## Login
3230

33-
After installation, the addon is available in the 3D view in the tab 'Sketchfab' in the Properties panel (shortcut **N**) for Blender 2.80 and after, and in the Tools panel (shortcut **T**) for Blender 2.79.
31+
After installation, the addon is available in the 3D view in the tab 'Sketchfab' in the Properties panel (shortcut **N**) for Blender 2.80+.
3432

3533
Login (mandatory to import or export models) can be achieved through using the email and password associated to your Sketchfab account, or by using your API token, available in the settings of your [Sketchfab account](https://sketchfab.com/settings/password):
3634

@@ -113,7 +111,7 @@ There is no "quick fix" for those kinds of behaviours, which are actively being
113111

114112
Here is a list of known issues on import, as well as some possible fixes.
115113

116-
Please note that the materials are being converted from Sketchfab to Cycles in Blender 2.79, and Eevee in Blender 2.80. If a material looks wrong, using the **Node editor** could therefore help you fixing possible issues.
114+
Please note that the materials are being converted from Sketchfab to Eevee in Blender 2.80+. If a material looks wrong, using the **Node editor** could therefore help you fixing possible issues.
117115

118116
#### Mesh not parented to armature
119117

Lines changed: 46 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -34,50 +34,13 @@
3434
IntProperty,
3535
PointerProperty)
3636

37-
from .io import *
38-
from .io.imp.gltf2_io_gltf import *
39-
from .blender.imp.gltf2_blender_gltf import *
40-
from .blender.blender_version import Version
41-
42-
43-
# Blender 2.79 has been shipped with openssl version 0.9.8 which uses a TLS protocol
44-
# that is now blocked for security reasons on websites (github.com for example)
45-
# In order to allow communication with github.com and other websites, the code will intend
46-
# to use the updated openssl version distributed with the addon.
47-
# Note: Blender 2.8 will have a more recent openssl version. This fix is only for 2.79 and olders
48-
if bpy.app.version < (2, 80, 0) and not bpy.app.build_platform == b'Windows':
49-
try:
50-
sslib_path = None
51-
if bpy.app.build_platform == b'Darwin':
52-
sslib_path = os.path.join(os.path.dirname(__file__), 'dependencies/_ssl.cpython-35m-darwin.so')
53-
elif bpy.app.build_platform == b'Linux':
54-
sslib_path = os.path.join(os.path.dirname(__file__), '/io_sketchfab_plugin/_ssl.cpython-35m-x86_64-linux-gnu.so')
55-
56-
import importlib.util
57-
spec = importlib.util.spec_from_file_location("_ssl", sslib_path)
58-
new_ssl = importlib.util.module_from_spec(spec)
59-
spec.loader.exec_module(new_ssl)
60-
61-
62-
from importlib import reload
63-
import ssl
64-
reload(ssl)
65-
from requests.packages.urllib3.util import ssl_
66-
reload(ssl_)
67-
print('SSL python module has been successfully overriden by Sketchfab addon')
68-
print('It might fix other addons having the same refused TLS protocol issue')
69-
except Exception as e:
70-
print(e)
71-
print("Failed to override SSL lib. The plugin will not be able to check for updates")
72-
73-
7437
bl_info = {
7538
'name': 'Sketchfab Plugin',
7639
'description': 'Browse and download free Sketchfab downloadable models',
7740
'author': 'Sketchfab',
7841
'license': 'APACHE2',
7942
'deps': '',
80-
'version': (1, 5, 0),
43+
'version': (1, 6, 0),
8144
"blender": (2, 80, 0),
8245
'location': 'View3D > Tools > Sketchfab',
8346
'warning': '',
@@ -105,8 +68,8 @@ class Config:
10568
SKETCHFAB_REPORT_URL = 'https://help.sketchfab.com/hc/en-us/requests/new?type=exporters&subject=Blender+Plugin'
10669

10770
SKETCHFAB_URL = 'https://sketchfab.com'
108-
DUMMY_CLIENTID = 'hGC7unF4BHyEB0s7Orz5E1mBd3LluEG0ILBiZvF9'
109-
SKETCHFAB_OAUTH = SKETCHFAB_URL + '/oauth2/token/?grant_type=password&client_id=' + DUMMY_CLIENTID
71+
CLIENTID = 'hGC7unF4BHyEB0s7Orz5E1mBd3LluEG0ILBiZvF9'
72+
SKETCHFAB_OAUTH = SKETCHFAB_URL + '/oauth2/token/'
11073
SKETCHFAB_API = 'https://api.sketchfab.com'
11174
SKETCHFAB_SEARCH = SKETCHFAB_API + '/v3/search'
11275
SKETCHFAB_MODEL = SKETCHFAB_API + '/v3/models'
@@ -244,12 +207,6 @@ def get_thumbnail_url(thumbnails_json):
244207
return min_thumbnail
245208
return best_thumbnail
246209

247-
def make_model_name(gltf_data):
248-
if 'title' in gltf_data.asset.extras:
249-
return gltf_data.asset.extras['title']
250-
251-
return 'GLTFModel'
252-
253210
def setup_plugin():
254211
if not os.path.exists(Config.SKETCHFAB_THUMB_DIR):
255212
os.makedirs(Config.SKETCHFAB_THUMB_DIR)
@@ -432,6 +389,7 @@ def __init__(self):
432389
self.next_results_url = None
433390
self.prev_results_url = None
434391
self.user_orgs = []
392+
self.user_has_orgs = False
435393
self.active_org = None
436394
self.use_org_profile = False
437395

@@ -473,6 +431,7 @@ def logout(self):
473431
#pprops.search_domain = "DEFAULT"
474432

475433
self.user_orgs = []
434+
self.user_has_orgs = False
476435
self.active_org = None
477436
self.use_org_profile = False
478437
props.use_org_profile = False
@@ -495,7 +454,7 @@ def parse_user_info(self, r, *args, **kargs):
495454
self.username = user_data['username']
496455
self.display_name = user_data['displayName']
497456
self.plan_type = user_data['account']
498-
requests.get(Config.SKETCHFAB_ME + "/orgs", headers=self.headers, hooks={'response': self.parse_orgs_info})
457+
requests.get(Config.SKETCHFAB_ME + "/orgs", headers=self.headers, hooks={'response': self.on_user_orgs_check})
499458
else:
500459
print('\nInvalid access or API token\nYou can get your API token here:\nhttps://sketchfab.com/settings/password\n')
501460
set_login_status('ERROR', 'Failed to authenticate')
@@ -504,6 +463,14 @@ def parse_user_info(self, r, *args, **kargs):
504463
self.api_token = ''
505464
self.headers = {}
506465

466+
def request_user_orgs(self):
467+
if not self.active_org:
468+
requests.get(Config.SKETCHFAB_ME + "/orgs", headers=self.headers, hooks={'response': self.parse_orgs_info})
469+
pass
470+
471+
def on_user_orgs_check(self, r, *args, **kargs):
472+
self.user_has_orgs = bool((r.status_code == 200) and len(r.json().get("results", [])))
473+
507474
def parse_orgs_info(self, r, *args, **kargs):
508475
"""
509476
Get and store information about user's orgs, and its orgs projects
@@ -564,6 +531,7 @@ def parse_projects_info(r, *args, **kargs):
564531
# Set the first org as active
565532
if len(self.user_orgs):
566533
self.active_org = self.user_orgs[0]
534+
self.user_has_orgs = True
567535

568536
# Iterate on all orgs (not just the 24 first)
569537
if orgs_data["next"] is not None:
@@ -716,9 +684,11 @@ def handle_download(self, r, *args, **kwargs):
716684
skfb_model.download_url = gltf['url']
717685
skfb_model.time_url_requested = time.time()
718686
skfb_model.url_expires = gltf['expires']
719-
self.get_archive(gltf['url'])
687+
self.get_archive(gltf['url'], skfb_model.title)
688+
else:
689+
ShowMessage("ERROR", "Cannot retrieve information for this model", "")
720690

721-
def get_archive(self, url):
691+
def get_archive(self, url, title):
722692
if url is None:
723693
print('Url is None')
724694
return
@@ -755,7 +725,7 @@ def get_archive(self, url):
755725
gltf_path, gltf_zip = unzip_archive(archive_path)
756726
if gltf_path:
757727
try:
758-
import_model(gltf_path, uid)
728+
import_model(gltf_path, uid, title)
759729
except Exception as e:
760730
import traceback
761731
print(traceback.format_exc())
@@ -826,6 +796,8 @@ def update_tr(self, context):
826796

827797
def get_user_orgs(self, context):
828798
api = get_sketchfab_props().skfb_api
799+
if not api.user_has_orgs:
800+
api.request_user_orgs()
829801
return [(org["uid"], org["displayName"], "") for org in api.user_orgs]
830802

831803
def get_org_projects(self, context):
@@ -837,7 +809,7 @@ def get_available_search_domains(self, context):
837809

838810
search_domains = [domain for domain in Config.SKETCHFAB_SEARCH_DOMAIN]
839811

840-
if len(api.user_orgs) and api.use_org_profile:
812+
if api.user_has_orgs and api.use_org_profile:
841813
search_domains = [
842814
("ACTIVE_ORG", "Active Organization", api.active_org["displayName"], 0)
843815
]
@@ -856,6 +828,12 @@ def refresh_orgs(self, context):
856828
api = props.skfb_api
857829

858830
api.use_org_profile = pprops.use_org_profile
831+
832+
if api.user_has_orgs and not api.active_org :
833+
bpy.context.window.cursor_set("WAIT")
834+
api.request_user_orgs()
835+
bpy.context.window.cursor_set("DEFAULT")
836+
859837
orgs = [org for org in api.user_orgs if org["uid"] == pprops.active_org]
860838
api.active_org = orgs[0] if len(orgs) else None
861839

@@ -875,7 +853,7 @@ def refresh_orgs(self, context):
875853

876854
def get_sorting_options(self, context):
877855
api = get_sketchfab_props().skfb_api
878-
if len(api.user_orgs) and api.use_org_profile:
856+
if api.user_has_orgs and api.use_org_profile:
879857
return (
880858
('RELEVANCE', "Relevance", ""),
881859
('RECENT', "Recent", "")
@@ -1183,8 +1161,8 @@ def async_func(*args, **kwargs):
11831161
return async_func
11841162

11851163

1186-
def import_model(gltf_path, uid):
1187-
bpy.ops.wm.import_modal('INVOKE_DEFAULT', gltf_path=gltf_path, uid=uid)
1164+
def import_model(gltf_path, uid, title):
1165+
bpy.ops.wm.import_modal('INVOKE_DEFAULT', gltf_path=gltf_path, uid=uid, title=title)
11881166

11891167

11901168
def build_search_request(query, pbr, animated, staffpick, face_count, category, sort_by):
@@ -1378,8 +1356,13 @@ def invoke(self, context, event):
13781356
context.window_manager.modal_handler_add(self)
13791357
login_props = get_sketchfab_login_props()
13801358
if(login_props.use_mail):
1381-
url = '{}&username={}&password={}'.format(Config.SKETCHFAB_OAUTH, urllib.parse.quote_plus(login_props.email), urllib.parse.quote_plus(login_props.password))
1382-
requests.post(url, hooks={'response': self.handle_mail_login})
1359+
data = {
1360+
'grant_type': 'password',
1361+
'client_id': Config.CLIENTID,
1362+
'username': login_props.email,
1363+
'password': login_props.password,
1364+
}
1365+
requests.post(Config.SKETCHFAB_OAUTH, data=data, hooks={'response': self.handle_mail_login})
13831366
else:
13841367
self.handle_token_login(login_props.api_token)
13851368
except Exception as e:
@@ -1397,33 +1380,28 @@ class ImportModalOperator(bpy.types.Operator):
13971380

13981381
gltf_path : StringProperty()
13991382
uid : StringProperty()
1383+
title: StringProperty()
14001384

14011385
def execute(self, context):
14021386
print('IMPORT')
14031387
return {'FINISHED'}
14041388

14051389
def modal(self, context, event):
14061390
if bpy.context.scene.render.engine not in ["CYCLES", "BLENDER_EEVEE"]:
1407-
bpy.context.scene.render.engine = Version.ENGINE
1408-
gltf_importer = glTFImporter(self.gltf_path)
1409-
gltf_importer.read()
1410-
1391+
bpy.context.scene.render.engine = "BLENDER_EEVEE"
14111392
try:
14121393
old_objects = [o.name for o in bpy.data.objects] # Get the current objects inorder to find the new node hierarchy
1413-
BlenderGlTF.create(gltf_importer)
1394+
bpy.ops.import_scene.gltf(filepath=self.gltf_path)
14141395
set_import_status('')
14151396
Utils.clean_downloaded_model_dir(self.uid)
1416-
root_name = Utils.make_model_name(gltf_importer.data)
1417-
Utils.clean_node_hierarchy([o for o in bpy.data.objects if o.name not in old_objects], root_name)
1397+
Utils.clean_node_hierarchy([o for o in bpy.data.objects if o.name not in old_objects], self.title)
14181398
return {'FINISHED'}
14191399
except Exception:
14201400
import traceback
14211401
print(traceback.format_exc())
14221402
set_import_status('')
14231403
return {'FINISHED'}
14241404

1425-
return {'RUNNING_MODAL'}
1426-
14271405
def invoke(self, context, event):
14281406
context.window_manager.modal_handler_add(self)
14291407
set_import_status('Importing...')
@@ -1524,7 +1502,7 @@ def draw(self, context):
15241502

15251503
self.layout.enabled = get_plugin_enabled() and api.is_user_logged()
15261504

1527-
if not api.user_orgs:
1505+
if not api.user_has_orgs:
15281506
self.layout.label(text="You are not part of an organization", icon='INFO')
15291507
self.layout.operator("wm.url_open", text='Learn about Sketchfab for Teams').url = "https://sketchfab.com/features/teams"
15301508
else:
@@ -2134,7 +2112,7 @@ def upload(filepath, filename):
21342112
else:
21352113

21362114
# Org or not
2137-
if len(api.user_orgs) and api.use_org_profile:
2115+
if api.user_has_orgs and api.use_org_profile:
21382116
uploadUrl = "%s/%s/models" % (Config.SKETCHFAB_ORGS, api.active_org["uid"])
21392117
_data["orgProject"] = props.active_project
21402118
else:
@@ -2395,7 +2373,7 @@ def check_plugin_version(request, *args, **kwargs):
23952373

23962374
def register():
23972375
sketchfab_icon = bpy.utils.previews.new()
2398-
icons_dir = os.path.join(os.path.dirname(__file__), "resources")
2376+
icons_dir = os.path.dirname(__file__)
23992377
sketchfab_icon.load("skfb", os.path.join(icons_dir, "logo.png"), 'IMAGE')
24002378
sketchfab_icon.load("0", os.path.join(icons_dir, "placeholder.png"), 'IMAGE')
24012379

addons/io_sketchfab_plugin/.gitignore

Lines changed: 0 additions & 10 deletions
This file was deleted.

addons/io_sketchfab_plugin/blender/README.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)