-
Notifications
You must be signed in to change notification settings - Fork 8
/
importscad.py
125 lines (94 loc) · 3.79 KB
/
importscad.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# -*- coding: utf-8 -*-
import os
import subprocess
import bpy
from bpy.props import StringProperty, BoolProperty, FloatProperty, IntProperty, PointerProperty, CollectionProperty
from bpy.types import Operator, AddonPreferences
from bpy_extras.io_utils import ImportHelper
bl_info = {
"name": "OpenSCAD importer",
"description": "Imports OpenSCAD (.scad) files.",
"author": "Maqq",
"version": (1, 3),
"blender": (2, 80, 0),
"location": "File > Import",
"warning": "", # used for warning icon and text in addons panel
"category": "Import-Export"
}
# Temporary stl file
TEMPNAME = "tempexport.stl"
def read_openscad(context, filepath, scale, parameters):
""" Exports stl using OpenSCAD and imports it. """
from io_mesh_stl import stl_utils
from io_mesh_stl import blender_utils
from mathutils import Matrix
user_preferences = bpy.context.preferences
addon_prefs = user_preferences.addons[__name__].preferences
openscad_path = addon_prefs.filepath
tempfile_path = os.path.join(os.path.dirname(filepath), TEMPNAME)
# Export stl from OpenSCAD
command = [openscad_path, "-o", tempfile_path, filepath]
print("Executing command:", command)
use_shell = False if os.name == 'posix' else True
result = subprocess.run(command, capture_output=True, shell=use_shell, text=True)
print(result.stdout)
print(result.stderr)
if os.path.exists(tempfile_path):
if bpy.ops.object.mode_set.poll():
bpy.ops.object.mode_set(mode='OBJECT')
if bpy.ops.object.select_all.poll():
bpy.ops.object.select_all(action='DESELECT')
obj_name = os.path.basename(filepath).split('.')[0]
bpy.ops.import_mesh.stl(filepath=tempfile_path, global_scale=scale)
os.remove(tempfile_path)
# Rename the imported stl objects
for imported_obj in bpy.context.selected_objects:
imported_obj.name = obj_name
imported_obj.data.name = obj_name
else:
print("Temporary export file not found:", tempfile_path)
return {'FINISHED'}
class OpenSCADImporterPreferences(AddonPreferences):
""" Addon preferences. """
bl_idname = __name__
filepath : StringProperty(
name="Path to OpenSCAD executable",
subtype='FILE_PATH',
)
def draw(self, context):
self.layout.prop(self, "filepath")
class OpenSCADImporter(Operator, ImportHelper):
""" Import OpenSCAD files. """
bl_idname = "import_mesh.scad"
bl_label = "Import OpenSCAD"
# ImportHelper mixin class uses this
filename_ext = ".scad"
filter_glob : StringProperty(
default="*.scad",
options={'HIDDEN'},
)
scale : FloatProperty(name='Scale', default=1.0)
# Parameters for the scad file
p1 : StringProperty(name='P1 name')
p1v : StringProperty(name='P1 value')
p2 : StringProperty(name='P2 name')
p2v : StringProperty(name='P2 value')
p3 : StringProperty(name='P3 name')
p3v : StringProperty(name='P3 value')
p4 : StringProperty(name='P4 name')
p4v : StringProperty(name='P4 value')
def __init__(self):
super(OpenSCADImporter, self).__init__()
def execute(self, context):
return read_openscad(context, self.filepath, self.scale, {self.p1:self.p1v, self.p2:self.p2v, self.p3:self.p3v, self.p4:self.p4v})
def menu_func_import(self, context):
self.layout.operator(OpenSCADImporter.bl_idname, text="OpenSCAD (.scad)")
def register():
bpy.utils.register_class(OpenSCADImporter)
bpy.utils.register_class(OpenSCADImporterPreferences)
bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
def unregister():
bpy.utils.unregister_class(OpenSCADImporter)
bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
if __name__ == "__main__":
pass