Update for 2.8
TODO: - Ray-cast for thickness doesn't have access to an evaluated mesh. - Exporters such as PLY need updating too.
This commit is contained in:
parent
0ac377d853
commit
351dbd03d4
|
@ -21,7 +21,7 @@
|
|||
bl_info = {
|
||||
"name": "3D Print Toolbox",
|
||||
"author": "Campbell Barton",
|
||||
"blender": (2, 79, 0),
|
||||
"blender": (2, 80, 0),
|
||||
"location": "3D View > Toolbox",
|
||||
"description": "Utilities for 3D printing",
|
||||
"wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
|
||||
|
@ -186,7 +186,7 @@ classes = (
|
|||
|
||||
Print3D_Scene_Props,
|
||||
Print3D_Preferences,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
|
|
|
@ -53,11 +53,12 @@ def image_copy_guess(filepath, objects):
|
|||
|
||||
def write_mesh(context, info, report_cb):
|
||||
scene = context.scene
|
||||
layer = context.view_layer
|
||||
unit = scene.unit_settings
|
||||
print_3d = scene.print_3d
|
||||
|
||||
obj_base = scene.object_bases.active
|
||||
obj = obj_base.object
|
||||
# obj_base = layer.object_bases.active
|
||||
obj = layer.objects.active
|
||||
|
||||
export_format = print_3d.export_format
|
||||
global_scale = unit.scale_length if (unit.system != 'NONE' and print_3d.use_apply_scale) else 1.0
|
||||
|
@ -73,13 +74,16 @@ def write_mesh(context, info, report_cb):
|
|||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
from . import mesh_helpers
|
||||
obj_base_tmp = mesh_helpers.object_merge(context, context_override["selected_objects"])
|
||||
context_override["active_object"] = obj_base_tmp.object
|
||||
context_override["selected_bases"] = [obj_base_tmp]
|
||||
context_override["selected_objects"] = [obj_base_tmp.object]
|
||||
obj_tmp = mesh_helpers.object_merge(context, context_override["selected_objects"])
|
||||
context_override["active_object"] = obj_tmp
|
||||
# context_override["selected_bases"] = [obj_base_tmp]
|
||||
context_override["selected_objects"] = [obj_tmp]
|
||||
else:
|
||||
# XXX28
|
||||
'''
|
||||
if obj_base not in context_override["selected_bases"]:
|
||||
context_override["selected_bases"].append(obj_base)
|
||||
'''
|
||||
if obj not in context_override["selected_objects"]:
|
||||
context_override["selected_objects"].append(obj)
|
||||
|
||||
|
|
|
@ -157,19 +157,31 @@ def bmesh_check_thick_object(obj, thickness):
|
|||
# Create a real mesh (lame!)
|
||||
context = bpy.context
|
||||
scene = context.scene
|
||||
layer = context.view_layer
|
||||
layer_collection = context.layer_collection
|
||||
if layer_collection is None:
|
||||
scene_collection = scene.master_collection.collections.new("")
|
||||
layer_collection = layer.collections.link(scene_collection)
|
||||
else:
|
||||
scene_collection = layer_collection.collection
|
||||
|
||||
me_tmp = bpy.data.meshes.new(name="~temp~")
|
||||
bm.to_mesh(me_tmp)
|
||||
# bm.free() # delay free
|
||||
obj_tmp = bpy.data.objects.new(name=me_tmp.name, object_data=me_tmp)
|
||||
base = scene.objects.link(obj_tmp)
|
||||
# base = scene.objects.link(obj_tmp)
|
||||
scene_collection.objects.link(obj_tmp)
|
||||
|
||||
# Add new object to local view layer
|
||||
# XXX28
|
||||
'''
|
||||
v3d = None
|
||||
if context.space_data and context.space_data.type == 'VIEW_3D':
|
||||
v3d = context.space_data
|
||||
|
||||
if v3d and v3d.local_view:
|
||||
base.layers_from_view(context.space_data)
|
||||
'''
|
||||
|
||||
scene.update()
|
||||
ray_cast = obj_tmp.ray_cast
|
||||
|
@ -190,7 +202,7 @@ def bmesh_check_thick_object(obj, thickness):
|
|||
p_b = p - no_end
|
||||
p_dir = p_b - p_a
|
||||
|
||||
ok, co, no, index = ray_cast(p_a, p_dir, p_dir.length)
|
||||
ok, co, no, index = ray_cast(p_a, p_dir, distance=p_dir.length)
|
||||
|
||||
if ok:
|
||||
# Add the face we hit
|
||||
|
@ -203,7 +215,7 @@ def bmesh_check_thick_object(obj, thickness):
|
|||
# finished with bm
|
||||
bm.free()
|
||||
|
||||
scene.objects.unlink(obj_tmp)
|
||||
scene_collection.objects.unlink(obj_tmp)
|
||||
bpy.data.objects.remove(obj_tmp)
|
||||
bpy.data.meshes.remove(me_tmp)
|
||||
|
||||
|
@ -228,17 +240,24 @@ def object_merge(context, objects):
|
|||
seq.remove(seq[i])
|
||||
|
||||
scene = context.scene
|
||||
layer = context.view_layer
|
||||
layer_collection = context.layer_collection
|
||||
if layer_collection is None:
|
||||
scene_collection = scene.master_collection.collections.new("")
|
||||
layer_collection = layer.collections.link(scene_collection)
|
||||
else:
|
||||
scene_collection = layer_collection.collection
|
||||
|
||||
# deselect all
|
||||
for obj in scene.objects:
|
||||
obj.select = False
|
||||
obj.select_set('DESELECT')
|
||||
|
||||
# add empty object
|
||||
mesh_base = bpy.data.meshes.new(name="~tmp~")
|
||||
obj_base = bpy.data.objects.new(name="~tmp~", object_data=mesh_base)
|
||||
base_base = scene.objects.link(obj_base)
|
||||
scene.objects.active = obj_base
|
||||
obj_base.select = True
|
||||
scene_collection.objects.link(obj_base)
|
||||
layer.objects.active = obj_base
|
||||
obj_base.select_set('SELECT')
|
||||
|
||||
# loop over all meshes
|
||||
for obj in objects:
|
||||
|
@ -246,29 +265,30 @@ def object_merge(context, objects):
|
|||
continue
|
||||
|
||||
# convert each to a mesh
|
||||
mesh_new = obj.to_mesh(scene=scene,
|
||||
apply_modifiers=True,
|
||||
settings='PREVIEW',
|
||||
calc_tessface=False)
|
||||
mesh_new = obj.to_mesh(
|
||||
depsgraph=context.depsgraph,
|
||||
apply_modifiers=True,
|
||||
calc_tessface=False,
|
||||
)
|
||||
|
||||
# remove non-active uvs/vcols
|
||||
cd_remove_all_but_active(mesh_new.vertex_colors)
|
||||
cd_remove_all_but_active(mesh_new.uv_textures)
|
||||
cd_remove_all_but_active(mesh_new.uv_layers)
|
||||
|
||||
# join into base mesh
|
||||
obj_new = bpy.data.objects.new(name="~tmp-new~", object_data=mesh_new)
|
||||
base_new = scene.objects.link(obj_new)
|
||||
base_new = scene_collection.objects.link(obj_new)
|
||||
obj_new.matrix_world = obj.matrix_world
|
||||
|
||||
fake_context = context.copy()
|
||||
fake_context["active_object"] = obj_base
|
||||
fake_context["selected_editable_bases"] = [base_base, base_new]
|
||||
fake_context["selected_editable_objects"] = [obj_base, obj_new]
|
||||
|
||||
bpy.ops.object.join(fake_context)
|
||||
del base_new, obj_new
|
||||
|
||||
# remove object and its mesh, join does this
|
||||
# scene.objects.unlink(obj_new)
|
||||
# scene_collection.objects.unlink(obj_new)
|
||||
# bpy.data.objects.remove(obj_new)
|
||||
|
||||
bpy.data.meshes.remove(mesh_new)
|
||||
|
@ -276,7 +296,8 @@ def object_merge(context, objects):
|
|||
scene.update()
|
||||
|
||||
# return new object
|
||||
return base_base
|
||||
return obj_base
|
||||
|
||||
|
||||
|
||||
def face_is_distorted(ele, angle_distort):
|
||||
|
|
|
@ -731,11 +731,11 @@ class MESH_OT_Print3D_Scale_To_Bounds(Operator):
|
|||
return max(((max(v[i] for v in vecs) - min(v[i] for v in vecs)), i) for i in range(3))
|
||||
|
||||
if context.mode == 'EDIT_MESH':
|
||||
length, axis = calc_length([Vector(v) * obj.matrix_world
|
||||
length, axis = calc_length([Vector(v) @ obj.matrix_world
|
||||
for obj in [context.edit_object]
|
||||
for v in obj.bound_box])
|
||||
else:
|
||||
length, axis = calc_length([Vector(v) * obj.matrix_world
|
||||
length, axis = calc_length([Vector(v) @ obj.matrix_world
|
||||
for obj in context.selected_editable_objects
|
||||
if obj.type == 'MESH' for v in obj.bound_box])
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ from . import report
|
|||
class Print3D_ToolBar:
|
||||
bl_label = "Print3D"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_region_type = 'UI'
|
||||
|
||||
_type_to_icon = {
|
||||
bmesh.types.BMVert: 'VERTEXSEL',
|
||||
|
@ -49,7 +49,7 @@ class Print3D_ToolBar:
|
|||
if info:
|
||||
obj = context.edit_object
|
||||
|
||||
layout.label("Output:")
|
||||
layout.label(text="Output:")
|
||||
box = layout.box()
|
||||
col = box.column(align=False)
|
||||
# box.alert = True
|
||||
|
@ -61,7 +61,7 @@ class Print3D_ToolBar:
|
|||
icon=Print3D_ToolBar._type_to_icon[bm_type]).index = i
|
||||
layout.operator("mesh.select_non_manifold", text='Non Manifold Extended')
|
||||
else:
|
||||
col.label(text)
|
||||
col.label(text=text)
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -73,13 +73,13 @@ class Print3D_ToolBar:
|
|||
# TODO, presets
|
||||
|
||||
row = layout.row()
|
||||
row.label("Statistics:")
|
||||
row.label(text="Statistics:")
|
||||
rowsub = layout.row(align=True)
|
||||
rowsub.operator("mesh.print3d_info_volume", text="Volume")
|
||||
rowsub.operator("mesh.print3d_info_area", text="Area")
|
||||
|
||||
row = layout.row()
|
||||
row.label("Checks:")
|
||||
row.label(text="Checks:")
|
||||
col = layout.column(align=True)
|
||||
col.operator("mesh.print3d_check_solid", text="Solid")
|
||||
col.operator("mesh.print3d_check_intersect", text="Intersections")
|
||||
|
@ -102,7 +102,7 @@ class Print3D_ToolBar:
|
|||
col.operator("mesh.print3d_check_all", text="Check All")
|
||||
|
||||
row = layout.row()
|
||||
row.label("Cleanup:")
|
||||
row.label(text="Cleanup:")
|
||||
col = layout.column(align=True)
|
||||
col.operator("mesh.print3d_clean_isolated", text="Isolated")
|
||||
rowsub = col.row(align=True)
|
||||
|
@ -114,14 +114,14 @@ class Print3D_ToolBar:
|
|||
# col.operator("mesh.print3d_clean_thin", text="Wall Thickness")
|
||||
|
||||
row = layout.row()
|
||||
row.label("Scale To:")
|
||||
row.label(text="Scale To:")
|
||||
rowsub = layout.row(align=True)
|
||||
rowsub.operator("mesh.print3d_scale_to_volume", text="Volume")
|
||||
rowsub.operator("mesh.print3d_scale_to_bounds", text="Bounds")
|
||||
|
||||
col = layout.column()
|
||||
rowsub = col.row(align=True)
|
||||
rowsub.label("Export Path:")
|
||||
rowsub.label(text="Export Path:")
|
||||
rowsub.prop(print_3d, "use_apply_scale", text="", icon='MAN_SCALE')
|
||||
rowsub.prop(print_3d, "use_export_texture", text="", icon='FILE_IMAGE')
|
||||
rowsub = col.row()
|
||||
|
|
Loading…
Reference in New Issue