Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--add_mesh_BoltFactory/Boltfactory.py99
-rw-r--r--add_mesh_BoltFactory/createMesh.py522
-rw-r--r--add_mesh_extra_objects/Wallfactory.py10
-rw-r--r--add_mesh_extra_objects/__init__.py3
-rw-r--r--add_mesh_extra_objects/add_mesh_beam_builder.py27
-rw-r--r--add_mesh_extra_objects/add_mesh_gears.py18
-rw-r--r--add_mesh_extra_objects/add_mesh_gemstones.py18
-rw-r--r--add_mesh_extra_objects/add_mesh_honeycomb.py10
-rw-r--r--add_mesh_extra_objects/add_mesh_pipe_joint.py50
-rw-r--r--add_mesh_extra_objects/add_mesh_pyramid.py9
-rw-r--r--add_mesh_extra_objects/add_mesh_rocks/rockgen.py39
-rw-r--r--add_mesh_extra_objects/add_mesh_round_brilliant.py9
-rw-r--r--add_mesh_extra_objects/add_mesh_round_cube.py10
-rw-r--r--add_mesh_extra_objects/add_mesh_star.py10
-rw-r--r--add_mesh_extra_objects/add_mesh_supertoroid.py10
-rw-r--r--add_mesh_extra_objects/add_mesh_teapot.py37
-rw-r--r--add_mesh_extra_objects/add_mesh_torusknot.py10
-rw-r--r--add_mesh_extra_objects/add_mesh_twisted_torus.py9
-rw-r--r--ant_landscape/ant_functions.py49
-rw-r--r--ant_landscape/ant_noise.py10
-rw-r--r--archipack/archipack_manipulator.py5
-rw-r--r--io_scene_fbx/__init__.py20
-rwxr-xr-xio_scene_gltf2/__init__.py19
-rw-r--r--io_scene_obj/__init__.py198
-rw-r--r--node_wrangler.py337
-rw-r--r--object_fracture_cell/__init__.py316
-rw-r--r--oscurart_tools/render/material_overrides.py14
-rw-r--r--presets/operator/mesh.bolt_add/default.py8
-rw-r--r--presets/operator/mesh.bolt_add/m10.py8
-rw-r--r--presets/operator/mesh.bolt_add/m12.py8
-rw-r--r--presets/operator/mesh.bolt_add/m3.py8
-rw-r--r--presets/operator/mesh.bolt_add/m4.py8
-rw-r--r--presets/operator/mesh.bolt_add/m5.py8
-rw-r--r--presets/operator/mesh.bolt_add/m6.py8
-rw-r--r--presets/operator/mesh.bolt_add/m8.py8
-rw-r--r--presets/pov/light/01_(4800K)_Direct_Sun.py (renamed from presets/pov/light/01_(5400K)_Direct_Sun.py)0
-rw-r--r--rigify/rigs/chain_rigs.py6
-rw-r--r--rigify/rigs/spines/spine_rigs.py4
-rw-r--r--rigify/rigs/spines/super_head.py48
-rw-r--r--space_view3d_pie_menus/pie_proportional_menu.py2
-rw-r--r--ui_translate/__init__.py2
-rw-r--r--ui_translate/update_svn.py121
-rw-r--r--viewport_vr_preview.py28
43 files changed, 1660 insertions, 483 deletions
diff --git a/add_mesh_BoltFactory/Boltfactory.py b/add_mesh_BoltFactory/Boltfactory.py
index b3d3b108..acfe5886 100644
--- a/add_mesh_BoltFactory/Boltfactory.py
+++ b/add_mesh_BoltFactory/Boltfactory.py
@@ -60,6 +60,7 @@ class add_mesh_bolt(Operator, AddObjectHelper):
)
# Head Types
Model_Type_List = [('bf_Head_Hex', 'HEX', 'Hex Head'),
+ ('bf_Head_12Pnt', '12 POINT', '12 Point Head'),
('bf_Head_Cap', 'CAP', 'Cap Head'),
('bf_Head_Dome', 'DOME', 'Dome Head'),
('bf_Head_Pan', 'PAN', 'Pan Head'),
@@ -73,6 +74,7 @@ class add_mesh_bolt(Operator, AddObjectHelper):
# Bit Types
Bit_Type_List = [('bf_Bit_None', 'NONE', 'No Bit Type'),
('bf_Bit_Allen', 'ALLEN', 'Allen Bit Type'),
+ ('bf_Bit_Torx', 'TORX', 'Torx Bit Type'),
('bf_Bit_Philips', 'PHILLIPS', 'Phillips Bit Type')]
bf_Bit_Type: EnumProperty(
attr='bf_Bit_Type',
@@ -82,7 +84,8 @@ class add_mesh_bolt(Operator, AddObjectHelper):
)
# Nut Types
Nut_Type_List = [('bf_Nut_Hex', 'HEX', 'Hex Nut'),
- ('bf_Nut_Lock', 'LOCK', 'Lock Nut')]
+ ('bf_Nut_Lock', 'LOCK', 'Lock Nut'),
+ ('bf_Nut_12Pnt', '12 POINT', '12 Point Nut')]
bf_Nut_Type: EnumProperty(
attr='bf_Nut_Type',
name='Nut Type',
@@ -129,6 +132,30 @@ class add_mesh_bolt(Operator, AddObjectHelper):
description='Flat Distance of the Allen Bit',
unit='LENGTH',
)
+ # Torx Size Types
+ Torx_Size_Type_List = [('bf_Torx_T10', 'T10', 'T10'),
+ ('bf_Torx_T20', 'T20', 'T20'),
+ ('bf_Torx_T25', 'T25', 'T25'),
+ ('bf_Torx_T30', 'T30', 'T30'),
+ ('bf_Torx_T40', 'T40', 'T40'),
+ ('bf_Torx_T50', 'T50', 'T50'),
+ ('bf_Torx_T55', 'T55', 'T55'),
+ ]
+
+ bf_Torx_Size_Type: EnumProperty(
+ attr='bf_Torx_Size_Type',
+ name='Torx Size',
+ description='Size of the Torx Bit',
+ items=Torx_Size_Type_List, default='bf_Torx_T20'
+ )
+ bf_Torx_Bit_Depth: FloatProperty(
+ attr='bf_Torx_Bit_Depth',
+ name='Bit Depth', default=1.5,
+ min=0, soft_min=0,
+ max=MAX_INPUT_NUMBER,
+ description='Depth of the Torx Bit',
+ unit='LENGTH',
+ )
bf_Hex_Head_Height: FloatProperty(
attr='bf_Hex_Head_Height',
name='Head Height', default=2,
@@ -144,6 +171,29 @@ class add_mesh_bolt(Operator, AddObjectHelper):
description='Flat Distance of the Hex Head',
unit='LENGTH',
)
+ bf_12_Point_Head_Height: FloatProperty(
+ attr='bf_12_Point_Head_Height',
+ name='Head Height', default=3.0,
+ min=0, soft_min=0, max=MAX_INPUT_NUMBER,
+ description='Height of the 12 Point Head',
+ unit='LENGTH',
+ )
+ bf_12_Point_Head_Flat_Distance: FloatProperty(
+ attr='bf_12_Point_Head_Flat_Distance',
+ name='Flat Dist', default=3.0,
+ min=0.001, soft_min=0, #limit to 0.001 to avoid calculation error
+ max=MAX_INPUT_NUMBER,
+ description='Flat Distance of the 12 Point Head',
+ unit='LENGTH',
+ )
+ bf_12_Point_Head_Flange_Dia: FloatProperty(
+ attr='bf_12_Point_Head_Flange_Dia',
+ name='12 Point Head Flange Dia', default=5.5,
+ min=0, soft_min=0,
+ max=MAX_INPUT_NUMBER,
+ description='Flange diameter of the 12 point Head',
+ unit='LENGTH',
+ )
bf_CounterSink_Head_Dia: FloatProperty(
attr='bf_CounterSink_Head_Dia',
name='Head Dia', default=6.300000190734863,
@@ -265,7 +315,31 @@ class add_mesh_bolt(Operator, AddObjectHelper):
description='Flat distance of the Hex Nut',
unit='LENGTH',
)
-
+ bf_12_Point_Nut_Height: FloatProperty(
+ attr='bf_12_Point_Nut_Height',
+ name='12 Point Nut Height', default=2.4000000953674316,
+ min=0, soft_min=0,
+ max=MAX_INPUT_NUMBER,
+ description='Height of the 12 Point Nut',
+ unit='LENGTH',
+ )
+
+ bf_12_Point_Nut_Flat_Distance: FloatProperty(
+ attr='bf_12_Point_Nut_Flat_Distance',
+ name='12 Point Nut Flat Dist', default=3.0,
+ min=0.001, soft_min=0, #limit to 0.001 to avoid calculation error
+ max=MAX_INPUT_NUMBER,
+ description='Flat distance of the 12 point Nut',
+ unit='LENGTH',
+ )
+ bf_12_Point_Nut_Flange_Dia: FloatProperty(
+ attr='bf_12_Point_Nut_Flange_Dia',
+ name='12 Point Nut Flange Dia', default=5.5,
+ min=0, soft_min=0,
+ max=MAX_INPUT_NUMBER,
+ description='Flange diameter of the 12 point Nut',
+ unit='LENGTH',
+ )
def draw(self, context):
layout = self.layout
col = layout.column()
@@ -282,6 +356,9 @@ class add_mesh_bolt(Operator, AddObjectHelper):
elif self.bf_Bit_Type == 'bf_Bit_Allen':
col.prop(self, 'bf_Allen_Bit_Depth')
col.prop(self, 'bf_Allen_Bit_Flat_Distance')
+ elif self.bf_Bit_Type == 'bf_Bit_Torx':
+ col.prop(self, 'bf_Torx_Bit_Depth')
+ col.prop(self, 'bf_Torx_Size_Type')
elif self.bf_Bit_Type == 'bf_Bit_Philips':
col.prop(self, 'bf_Phillips_Bit_Depth')
col.prop(self, 'bf_Philips_Bit_Dia')
@@ -292,6 +369,10 @@ class add_mesh_bolt(Operator, AddObjectHelper):
if self.bf_Head_Type == 'bf_Head_Hex':
col.prop(self, 'bf_Hex_Head_Height')
col.prop(self, 'bf_Hex_Head_Flat_Distance')
+ elif self.bf_Head_Type == 'bf_Head_12Pnt':
+ col.prop(self, 'bf_12_Point_Head_Height')
+ col.prop(self, 'bf_12_Point_Head_Flat_Distance')
+ col.prop(self, 'bf_12_Point_Head_Flange_Dia')
elif self.bf_Head_Type == 'bf_Head_Cap':
col.prop(self, 'bf_Cap_Head_Height')
col.prop(self, 'bf_Cap_Head_Dia')
@@ -311,8 +392,16 @@ class add_mesh_bolt(Operator, AddObjectHelper):
# Nut
if self.bf_Model_Type == 'bf_Model_Nut':
col.prop(self, 'bf_Nut_Type')
- col.prop(self, 'bf_Hex_Nut_Height')
- col.prop(self, 'bf_Hex_Nut_Flat_Distance')
+ if self.bf_Nut_Type == "bf_Nut_12Pnt":
+ col.prop(self, 'bf_12_Point_Nut_Height')
+ col.prop(self, 'bf_12_Point_Nut_Flat_Distance')
+ col.prop(self, 'bf_12_Point_Nut_Flange_Dia')
+ else:
+ col.prop(self, 'bf_Hex_Nut_Height')
+ col.prop(self, 'bf_Hex_Nut_Flat_Distance')
+
+
+
# Thread
col.label(text='Thread')
if self.bf_Model_Type == 'bf_Model_Bolt':
@@ -434,6 +523,8 @@ def BoltParameters():
"bf_Phillips_Bit_Depth",
"bf_Allen_Bit_Depth",
"bf_Allen_Bit_Flat_Distance",
+ "bf_Torx_Bit_Depth",
+ "bf_Torx_Size_Type",
"bf_Hex_Head_Height",
"bf_Hex_Head_Flat_Distance",
"bf_CounterSink_Head_Dia",
diff --git a/add_mesh_BoltFactory/createMesh.py b/add_mesh_BoltFactory/createMesh.py
index ccdd4372..96284012 100644
--- a/add_mesh_BoltFactory/createMesh.py
+++ b/add_mesh_BoltFactory/createMesh.py
@@ -20,10 +20,11 @@ import bpy
from mathutils import (
Matrix,
Vector,
+ geometry,
)
from math import (
sin, cos,
- tan, radians,
+ tan, radians,atan,degrees
)
from random import triangular
from bpy_extras.object_utils import AddObjectHelper, object_data_add
@@ -66,7 +67,7 @@ def unpack_face_list(list_of_tuples):
"""
Remove Doubles takes a list on Verts and a list of Faces and
removes the doubles, much like Blender does in edit mode.
-It doesn’t have the range function but it will round the corrdinates
+It doesn't have the range function but it will round the corrdinates
and remove verts that are very close together. The function
is useful because you can perform a "Remove Doubles" with out
having to enter Edit Mode. Having to enter edit mode has the
@@ -285,6 +286,29 @@ def Fill_Ring_Face(OFFSET, NUM, FACE_DOWN=0):
Face[2] = TempFace[2]
return Ret
+# Returns a list of faces that makes up a fill pattern around the last vert
+def Fill_Fan_Face(OFFSET, NUM, FACE_DOWN=0):
+ Ret = []
+ Face = [NUM-1,0,1]
+ TempFace = [0, 0, 0]
+ A = 0
+ #B = 1 unsed
+ C = 2
+ if NUM < 3:
+ return None
+ for _i in range(NUM - 2):
+ TempFace[0] = Face[A]
+ TempFace[1] = Face[C]
+ TempFace[2] = Face[C]+1
+ if FACE_DOWN:
+ Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
+ else:
+ Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
+
+ Face[0] = TempFace[0]
+ Face[1] = TempFace[1]
+ Face[2] = TempFace[2]
+ return Ret
# ####################################################################
# Create Allen Bit
@@ -378,7 +402,175 @@ def Create_Allen_Bit(FLAT_DISTANCE, HEIGHT):
faces.extend(M_Faces)
return verts, faces, OUTTER_RADIUS * 2.0
+# ####################################################################
+# Create Torx Bit
+# ####################################################################
+
+def Torx_Bit_Size_To_Point_Distance(Bit_Size):
+ if Bit_Size == 'bf_Torx_T10':
+ return 2.83
+ elif Bit_Size == 'bf_Torx_T20':
+ return 3.94
+ elif Bit_Size == 'bf_Torx_T25':
+ return 4.52
+ elif Bit_Size == 'bf_Torx_T30':
+ return 5.61
+ elif Bit_Size == 'bf_Torx_T40':
+ return 6.75
+ elif Bit_Size == 'bf_Torx_T50':
+ return 8.94
+ elif Bit_Size == 'bf_Torx_T55':
+ return 8.94
+ else:
+ return 2.83 #default to M3
+
+def Torx_Fill(OFFSET, FLIP=0):
+ faces = []
+ Lookup = [[0,10,11],
+ [0,11, 12],
+ [0,12,1],
+
+ [1, 12, 13],
+ [1, 13, 14],
+ [1, 14, 15],
+ [1, 15, 2],
+
+ [2, 15, 16],
+ [2, 16, 17],
+ [2, 17, 18],
+ [2, 18, 19],
+ [2, 19, 3],
+
+ [3, 19, 20],
+ [3, 20, 21],
+ [3, 21, 22],
+ [3, 22, 23],
+ [3, 23, 24],
+ [3, 24, 25],
+ [3, 25, 4],
+
+
+ [4, 25, 26],
+ [4, 26, 27],
+ [4, 27, 28],
+ [4, 28, 29],
+ [4, 29, 30],
+ [4, 30, 31],
+ [4, 31, 5],
+
+ [5, 31, 32],
+ [5, 32, 33],
+ [5, 33, 34],
+ [5, 34, 35],
+ [5, 35, 36],
+ [5, 36, 6],
+
+ [6, 36, 37],
+ [6, 37, 38],
+ [6, 38, 39],
+ [6, 39, 7],
+
+ [7, 39, 40],
+ [7, 40, 41],
+ [7, 41, 42],
+ [7, 42, 43],
+ [7, 43, 8],
+
+ [8, 43, 44],
+ [8, 44, 45],
+ [8, 45, 46],
+ [8, 46, 47],
+ [8, 47, 48],
+ [8, 48, 49],
+ [8, 49, 50],
+ [8, 50, 51],
+ [8, 51, 52],
+ [8, 52, 9],
+ ]
+ for i in Lookup:
+ if FLIP:
+ faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
+ else:
+ faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
+
+ return faces
+
+
+
+def Create_Torx_Bit(Point_Distance, HEIGHT):
+ verts = []
+ faces = []
+
+ POINT_RADIUS = Point_Distance * 0.5
+ OUTTER_RADIUS = POINT_RADIUS * 1.05
+
+ POINT_1_Y = POINT_RADIUS * 0.816592592592593
+ POINT_2_X = POINT_RADIUS * 0.511111111111111
+ POINT_2_Y = POINT_RADIUS * 0.885274074074074
+ POINT_3_X = POINT_RADIUS * 0.7072
+ POINT_3_Y = POINT_RADIUS * 0.408296296296296
+ POINT_4_X = POINT_RADIUS * 1.02222222222222
+ SMALL_RADIUS = POINT_RADIUS * 0.183407407407407
+ BIG_RADIUS = POINT_RADIUS * 0.333333333333333
+# Values for T40 # POINT_1_Y = 2.756
+# POINT_2_X = 1.725
+# POINT_2_Y = 2.9878
+# POINT_3_X = 2.3868
+# POINT_3_Y = 1.378
+# POINT_4_X = 3.45
+#
+# SMALL_RADIUS = 0.619
+# BIG_RADIUS = 1.125
+
+ def Do_Curve(Curve_Height):
+ for i in range(0, 90, 10):
+ x = sin(radians(i)) * SMALL_RADIUS
+ y = cos(radians(i)) * SMALL_RADIUS
+ verts.append([x, POINT_1_Y + y, Curve_Height])
+
+ for i in range(260, 150, -10):
+ x = sin(radians(i)) * BIG_RADIUS
+ y = cos(radians(i)) * BIG_RADIUS
+ verts.append([POINT_2_X + x, POINT_2_Y + y, Curve_Height])
+
+ for i in range(340, 150 + 360, 10):
+ x = sin(radians(i%360)) * SMALL_RADIUS
+ y = cos(radians(i%360)) * SMALL_RADIUS
+ verts.append([POINT_3_X + x, POINT_3_Y + y, Curve_Height])
+
+ for i in range(320, 260, -10):
+ x = sin(radians(i)) * BIG_RADIUS
+ y = cos(radians(i)) * BIG_RADIUS
+ verts.append([POINT_4_X + x, y, Curve_Height])
+
+ FaceStart_Outside = len(verts)
+
+ for i in range(0, 100, 10):
+ x = sin(radians(i)) * OUTTER_RADIUS
+ y = cos(radians(i)) * OUTTER_RADIUS
+ verts.append([x, y, 0])
+ FaceStart_Top_Curve= len(verts)
+ Do_Curve(0)
+ faces.extend(Torx_Fill(FaceStart_Outside, 0))
+
+ FaceStart_Bottom_Curve= len(verts)
+ Do_Curve(0 - HEIGHT)
+
+ faces.extend(Build_Face_List_Quads(FaceStart_Top_Curve,42 ,1 , True))
+
+ verts.append([0,0,0 - HEIGHT]) # add center point for fill Fan
+ faces.extend(Fill_Fan_Face(FaceStart_Bottom_Curve, 44))
+
+ M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'x')
+ verts.extend(M_Verts)
+ faces.extend(M_Faces)
+
+ M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'y')
+ verts.extend(M_Verts)
+ faces.extend(M_Faces)
+
+ return verts, faces, OUTTER_RADIUS * 2.0
# ####################################################################
# Create Phillips Bit
@@ -881,6 +1073,280 @@ def Create_Hex_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT):
return Spin_Verts, Spin_Faces, 0 - (-HEIGHT)
+
+def Create_12_Point(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA):
+ FLANGE_HEIGHT = (1.89/8.0)*HEIGHT
+ FLAT_HEIGHT = (4.18/8.0)*HEIGHT
+# FLANGE_DIA = (13.27/8.0)*FLAT
+
+ FLANGE_RADIUS = FLANGE_DIA * 0.5
+ FLANGE_TAPPER_HEIGHT = HEIGHT - FLANGE_HEIGHT - FLAT_HEIGHT
+
+# HOLE_DIA = 0.0
+
+ verts = []
+ faces = []
+ HOLE_RADIUS = HOLE_DIA / 2
+ Half_Flat = FLAT / 2
+ TopBevelRadius = Half_Flat - (Half_Flat * (0.05 / 8))
+# Undercut_Height = (Half_Flat * (0.05 / 8))
+# Shank_Bevel = (Half_Flat * (0.05 / 8))
+# Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel
+ # Undercut_Height = 5
+ SHANK_RADIUS = SHANK_DIA / 2
+ Row = 0
+
+ verts.append([0.0, 0.0, 0.0])
+
+# print("HOLE_RADIUS" + str(HOLE_RADIUS))
+# print("TopBevelRadius" + str(TopBevelRadius))
+
+ FaceStart = len(verts)
+
+ # inner hole
+ x = sin(radians(0)) * HOLE_RADIUS
+ y = cos(radians(0)) * HOLE_RADIUS
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(5)) * HOLE_RADIUS
+ y = cos(radians(5)) * HOLE_RADIUS
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(10)) * HOLE_RADIUS
+ y = cos(radians(10)) * HOLE_RADIUS
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(15)) * HOLE_RADIUS
+ y = cos(radians(15)) * HOLE_RADIUS
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(20)) * HOLE_RADIUS
+ y = cos(radians(20)) * HOLE_RADIUS
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(25)) * HOLE_RADIUS
+ y = cos(radians(25)) * HOLE_RADIUS
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(30)) * HOLE_RADIUS
+ y = cos(radians(30)) * HOLE_RADIUS
+ verts.append([x, y, 0.0])
+
+ Row += 1
+
+
+
+ # bevel
+ x = sin(radians(0)) * TopBevelRadius
+ y = cos(radians(0)) * TopBevelRadius
+ vec1 = Vector([x, y, 0.0])
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(5)) * TopBevelRadius
+ y = cos(radians(5)) * TopBevelRadius
+ vec2 = Vector([x, y, 0.0])
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(10)) * TopBevelRadius
+ y = cos(radians(10)) * TopBevelRadius
+ vec3 = Vector([x, y, 0.0])
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(15)) * TopBevelRadius
+ y = cos(radians(15)) * TopBevelRadius
+ vec4 = Vector([x, y, 0.0])
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(20)) * TopBevelRadius
+ y = cos(radians(20)) * TopBevelRadius
+ vec5 = Vector([x, y, 0.0])
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(25)) * TopBevelRadius
+ y = cos(radians(25)) * TopBevelRadius
+ vec6 = Vector([x, y, 0.0])
+ verts.append([x, y, 0.0])
+
+ x = sin(radians(30)) * TopBevelRadius
+ y = cos(radians(30)) * TopBevelRadius
+ vec7 = Vector([x, y, 0.0])
+ verts.append([x, y, 0.0])
+
+ Row += 1
+
+
+ #45Deg bevel on the top
+
+ #First we work out how far up the Y axis the vert is
+ v_origin = Vector([0.0,0.0,0.0]) # center of the model
+ v_15Deg_Point = Vector([tan(radians(15)) * Half_Flat,Half_Flat,0.0]) #Is a know point to work back from
+
+ x = tan(radians(0)) * Half_Flat
+ Point_Distance =(tan(radians(30)) * v_15Deg_Point.x)+Half_Flat
+ dvec = vec1 - Vector([x, Point_Distance, 0.0])
+ verts.append([x, Point_Distance, -dvec.length])
+ v_0_Deg_Top_Point = Vector([x, Point_Distance, -dvec.length])
+
+ v_0_Deg_Point = Vector([x, Point_Distance,0.0])
+
+ v_5Deg_Line = Vector([tan(radians(5)) * Half_Flat, Half_Flat, 0.0])
+ v_5Deg_Line.length *= 2 # extende out the line on a 5 deg angle
+
+ #We cross 2 lines. One from the origin to the 0 Deg point
+ #and the second is from the orign extended out past the first line
+ # This gives the cross point of the
+ v_Cross = geometry.intersect_line_line_2d(v_0_Deg_Point,v_15Deg_Point,v_origin,v_5Deg_Line)
+ dvec = vec2 - Vector([v_Cross.x,v_Cross.y,0.0])
+ verts.append([v_Cross.x,v_Cross.y,-dvec.length])
+ v_5_Deg_Top_Point = Vector([v_Cross.x,v_Cross.y,-dvec.length])
+
+ v_10Deg_Line = Vector([tan(radians(10)) * Half_Flat, Half_Flat, 0.0])
+ v_10Deg_Line.length *= 2 # extende out the line
+
+ v_Cross = geometry.intersect_line_line_2d(v_0_Deg_Point,v_15Deg_Point,v_origin,v_10Deg_Line)
+ dvec = vec3 - Vector([v_Cross.x,v_Cross.y,0.0])
+ verts.append([v_Cross.x,v_Cross.y,-dvec.length])
+ v_10_Deg_Top_Point = Vector([v_Cross.x,v_Cross.y,-dvec.length])
+
+ #The remain points are stright forward because y is all the same y height (Half_Flat)
+ x = tan(radians(15)) * Half_Flat
+ dvec = vec4 - Vector([x, Half_Flat, 0.0])
+ Lowest_Point = -dvec.length
+ verts.append([x, Half_Flat, -dvec.length])
+ v_15_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
+
+ x = tan(radians(20)) * Half_Flat
+ dvec = vec5 - Vector([x, Half_Flat, 0.0])
+ Lowest_Point = -dvec.length
+ verts.append([x, Half_Flat, -dvec.length])
+ v_20_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
+
+ x = tan(radians(25)) * Half_Flat
+ dvec = vec6 - Vector([x, Half_Flat, 0.0])
+ Lowest_Point = -dvec.length
+ verts.append([x, Half_Flat, -dvec.length])
+ v_25_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
+
+ x = tan(radians(30)) * Half_Flat
+ dvec = vec7 - Vector([x, Half_Flat, 0.0])
+ Lowest_Point = -dvec.length
+ verts.append([x, Half_Flat, -dvec.length])
+ v_30_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
+ Row += 1
+
+
+ #Down Bits
+# print ("Point_Distance")
+# print (Point_Distance)
+
+
+
+ Flange_Adjacent = FLANGE_RADIUS - Point_Distance
+ if (Flange_Adjacent == 0.0):
+ Flange_Adjacent = 0.000001
+ Flange_Opposite = FLANGE_TAPPER_HEIGHT
+
+# print ("Flange_Opposite")
+# print (Flange_Opposite)
+# print ("Flange_Adjacent")
+# print (Flange_Adjacent)
+
+ FLANGE_ANGLE_RAD = atan(Flange_Opposite/Flange_Adjacent )
+# FLANGE_ANGLE_RAD = radians(45)
+# print("FLANGE_ANGLE_RAD")
+# print (degrees (FLANGE_ANGLE_RAD))
+
+
+ v_Extended_Flange_Edge = Vector([0.0,0.0,-HEIGHT + FLANGE_HEIGHT + (tan(FLANGE_ANGLE_RAD)* FLANGE_RADIUS) ])
+# print("v_Extended_Flange_Edge")
+# print (v_Extended_Flange_Edge)
+
+ #0deg
+ v_Flange_Edge = Vector([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
+ v_Cross = geometry.intersect_line_line(v_0_Deg_Top_Point,Vector([v_0_Deg_Top_Point.x,v_0_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
+ verts.append(v_Cross[0])
+
+ #5deg
+ v_Flange_Edge = Vector([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
+ v_Cross = geometry.intersect_line_line(v_5_Deg_Top_Point,Vector([v_5_Deg_Top_Point.x,v_5_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
+ verts.append(v_Cross[0])
+
+ #10deg
+ v_Flange_Edge = Vector([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
+ v_Cross = geometry.intersect_line_line(v_10_Deg_Top_Point,Vector([v_10_Deg_Top_Point.x,v_10_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
+ verts.append(v_Cross[0])
+
+ #15deg
+ v_Flange_Edge = Vector([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
+ v_Cross = geometry.intersect_line_line(v_15_Deg_Top_Point,Vector([v_15_Deg_Top_Point.x,v_15_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
+ verts.append(v_Cross[0])
+
+
+ #20deg
+ v_Flange_Edge = Vector([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
+ v_Cross = geometry.intersect_line_line(v_20_Deg_Top_Point,Vector([v_20_Deg_Top_Point.x,v_20_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
+ verts.append(v_Cross[0])
+
+ #25deg
+ v_Flange_Edge = Vector([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
+ v_Cross = geometry.intersect_line_line(v_25_Deg_Top_Point,Vector([v_25_Deg_Top_Point.x,v_25_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
+ verts.append(v_Cross[0])
+
+
+ #30deg
+ v_Flange_Edge = Vector([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
+ v_Cross = geometry.intersect_line_line(v_30_Deg_Top_Point,Vector([v_30_Deg_Top_Point.x,v_30_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
+ verts.append(v_Cross[0])
+
+ Row += 1
+
+
+
+ verts.append([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
+ verts.append([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
+ verts.append([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
+ verts.append([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
+ verts.append([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
+ verts.append([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
+ verts.append([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
+
+ Row += 1
+
+ verts.append([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT])
+ verts.append([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT])
+ verts.append([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT])
+ verts.append([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT])
+ verts.append([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT])
+ verts.append([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT])
+ verts.append([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT])
+
+ Row += 1
+
+
+ verts.append([sin(radians(0)) * SHANK_RADIUS,cos(radians(0)) * SHANK_RADIUS,-HEIGHT])
+ verts.append([sin(radians(0)) * SHANK_RADIUS,cos(radians(0)) * SHANK_RADIUS,-HEIGHT])
+ verts.append([sin(radians(10)) * SHANK_RADIUS,cos(radians(10)) * SHANK_RADIUS,-HEIGHT])
+ verts.append([sin(radians(10)) * SHANK_RADIUS,cos(radians(10)) * SHANK_RADIUS,-HEIGHT])
+ verts.append([sin(radians(20)) * SHANK_RADIUS,cos(radians(20)) * SHANK_RADIUS,-HEIGHT])
+ verts.append([sin(radians(20)) * SHANK_RADIUS,cos(radians(20)) * SHANK_RADIUS,-HEIGHT])
+ verts.append([sin(radians(30)) * SHANK_RADIUS,cos(radians(30)) * SHANK_RADIUS,-HEIGHT])
+
+ Row += 1
+
+
+ faces.extend(Build_Face_List_Quads(FaceStart, 6, Row - 1))
+
+ Spin_Verts, Spin_Faces = SpinDup(verts, faces, 360,12, 'z')
+
+ return Spin_Verts, Spin_Faces, 0 - (-HEIGHT)
+
+
+def Create_12_Point_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA):
+ #TODO add under head radius
+ return Create_12_Point(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA)
+
+
+
# ####################################################################
# Create External Thread
# ####################################################################
@@ -1569,6 +2035,11 @@ def add_Nylon_Part(OUTSIDE_RADIUS, Z_LOCATION, DIV_COUNT):
return sVerts, faces, 0 - Lowest_Z_Vert
+def add_12_Point_Nut(FLAT, HOLE_DIA, HEIGHT,FLANGE_DIA):
+ return Create_12_Point(FLAT, HOLE_DIA,HOLE_DIA, HEIGHT,FLANGE_DIA)
+
+
+
# ####################################################################
# Create Internal Thread
# ####################################################################
@@ -1815,12 +2286,18 @@ def Nut_Mesh(props, context):
Head_Verts = []
Head_Faces = []
- New_Nut_Height = 5
Face_Start = len(verts)
+
+
+ if props.bf_Nut_Type == 'bf_Nut_12Pnt':
+ Nut_Height = props.bf_12_Point_Nut_Height
+ else:
+ Nut_Height = props.bf_Hex_Nut_Height
+
Thread_Verts, Thread_Faces, New_Nut_Height = Create_Internal_Thread(
props.bf_Minor_Dia, props.bf_Major_Dia,
- props.bf_Pitch, props.bf_Hex_Nut_Height,
+ props.bf_Pitch, Nut_Height,
props.bf_Crest_Percent, props.bf_Root_Percent,
1, props.bf_Div_Count
)
@@ -1828,7 +2305,16 @@ def Nut_Mesh(props, context):
faces.extend(Copy_Faces(Thread_Faces, Face_Start))
Face_Start = len(verts)
- Head_Verts, Head_Faces, Lock_Nut_Rad = add_Hex_Nut(
+
+ if props.bf_Nut_Type == 'bf_Nut_12Pnt':
+ Head_Verts, Head_Faces, Lock_Nut_Rad = add_12_Point_Nut(
+ props.bf_12_Point_Nut_Flat_Distance,
+ props.bf_Major_Dia, New_Nut_Height,
+ #Limit the size of the Flange to avoid calculation error
+ max(props.bf_12_Point_Nut_Flange_Dia,props.bf_12_Point_Nut_Flat_Distance)
+ )
+ else:
+ Head_Verts, Head_Faces, Lock_Nut_Rad = add_Hex_Nut(
props.bf_Hex_Nut_Flat_Distance,
props.bf_Major_Dia, New_Nut_Height
)
@@ -1892,6 +2378,13 @@ def Bolt_Mesh(props, context):
props.bf_Allen_Bit_Depth
)
+ if props.bf_Bit_Type == 'bf_Bit_Torx':
+ Bit_Verts, Bit_Faces, Bit_Dia = Create_Torx_Bit(
+ Torx_Bit_Size_To_Point_Distance(props.bf_Torx_Size_Type),
+ props.bf_Torx_Bit_Depth
+ )
+
+
if props.bf_Bit_Type == 'bf_Bit_Philips':
Bit_Verts, Bit_Faces, Bit_Dia = Create_Phillips_Bit(
props.bf_Philips_Bit_Dia,
@@ -1904,6 +2397,14 @@ def Bolt_Mesh(props, context):
props.bf_Hex_Head_Flat_Distance, Bit_Dia,
props.bf_Shank_Dia, props.bf_Hex_Head_Height
)
+
+ elif props.bf_Head_Type == 'bf_Head_12Pnt':
+ Head_Verts, Head_Faces, Head_Height = Create_12_Point_Head(
+ props.bf_12_Point_Head_Flat_Distance, Bit_Dia,
+ props.bf_Shank_Dia, props.bf_12_Point_Head_Height,
+ #Limit the size of the Flange to avoid calculation error
+ max(props.bf_12_Point_Head_Flange_Dia,props.bf_12_Point_Head_Flat_Distance)
+ )
elif props.bf_Head_Type == 'bf_Head_Cap':
Head_Verts, Head_Faces, Head_Height = Create_Cap_Head(
Bit_Dia, props.bf_Cap_Head_Dia,
@@ -1933,14 +2434,7 @@ def Bolt_Mesh(props, context):
props.bf_CounterSink_Head_Dia * (0.09 / 6.31),
props.bf_Div_Count
)
- """
- Head_Verts, Head_Faces, Head_Height = Create_CounterSink_Head(
- Bit_Dia, props.bf_CounterSink_Head_Dia,
- props.bf_Shank_Dia,
- props.bf_CounterSink_Head_Dia,
- props.bf_CounterSink_Head_Dia * (1.0 / 19.0)
- )
- """
+
Face_Start = len(verts)
verts.extend(Move_Verts_Up_Z(Bit_Verts, Head_Height))
faces.extend(Copy_Faces(Bit_Faces, Face_Start))
@@ -1958,7 +2452,7 @@ def Bolt_Mesh(props, context):
props.bf_Root_Percent, props.bf_Div_Count
)
- verts.extend(Move_Verts_Up_Z(Thread_Verts, 00))
+ verts.extend(Move_Verts_Up_Z(Thread_Verts, 0))
faces.extend(Copy_Faces(Thread_Faces, Face_Start))
return Move_Verts_Up_Z(verts, Thread_Height), faces
diff --git a/add_mesh_extra_objects/Wallfactory.py b/add_mesh_extra_objects/Wallfactory.py
index a4e87574..ede91fc3 100644
--- a/add_mesh_extra_objects/Wallfactory.py
+++ b/add_mesh_extra_objects/Wallfactory.py
@@ -665,6 +665,10 @@ class add_mesh_wallb(Operator, object_utils.AddObjectHelper):
if not self.ConstructTog:
return {'FINISHED'}
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
# enter the settings for the wall dimensions (area)
# start can't be zero - min/max don't matter [if max less than end] but zero don't workie.
# start can't exceed end.
@@ -917,6 +921,12 @@ class add_mesh_wallb(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def WallParameters():
diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py
index 4f00c450..14bde07d 100644
--- a/add_mesh_extra_objects/__init__.py
+++ b/add_mesh_extra_objects/__init__.py
@@ -249,6 +249,9 @@ def Extras_contex_menu(self, context):
obj = context.object
layout = self.layout
+ if obj == None:
+ return
+
if 'Gear' in obj.data.keys():
props = layout.operator("mesh.primitive_gear", text="Change Gear")
props.change = True
diff --git a/add_mesh_extra_objects/add_mesh_beam_builder.py b/add_mesh_extra_objects/add_mesh_beam_builder.py
index ceda4ffc..38944c58 100644
--- a/add_mesh_extra_objects/add_mesh_beam_builder.py
+++ b/add_mesh_extra_objects/add_mesh_beam_builder.py
@@ -730,11 +730,6 @@ class addBeam(Operator, object_utils.AddObjectHelper):
default=0,
description="Angle beam edges"
)
- Cursor: BoolProperty(
- name="Use 3D Cursor",
- default=False,
- description="Draw the beam where the 3D Cursor is"
- )
def draw(self, context):
layout = self.layout
@@ -742,7 +737,6 @@ class addBeam(Operator, object_utils.AddObjectHelper):
box = layout.box()
split = box.split(factor=0.85, align=True)
split.prop(self, "Type", text="")
- split.prop(self, "Cursor", text="")
box.prop(self, "beamZ")
box.prop(self, "beamX")
@@ -760,6 +754,10 @@ class addBeam(Operator, object_utils.AddObjectHelper):
box.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
@@ -781,21 +779,11 @@ class addBeam(Operator, object_utils.AddObjectHelper):
bpy.ops.transform.rotate(value=1.570796, constraint_axis=[False, True, False])
bpy.ops.object.transform_apply(location=False, rotation=True, scale=False)
- if self.Cursor:
- if beamObj.select_get() is True:
- # we also have to check if we're considered to be in 3D View (view3d)
- if bpy.ops.view3d.snap_selected_to_cursor.poll():
- bpy.ops.view3d.snap_selected_to_cursor()
- else:
- self.Cursor = False
-
obj.data["Beam"] = True
obj.data["change"] = False
for prm in BeamParameters():
obj.data[prm] = getattr(self, prm)
- return {'FINISHED'}
-
if bpy.context.mode == "EDIT_MESH":
active_object = context.active_object
name_active_object = active_object.name
@@ -808,6 +796,12 @@ class addBeam(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def BeamParameters():
@@ -818,6 +812,5 @@ def BeamParameters():
"beamY",
"beamW",
"edgeA",
- "Cursor",
]
return BeamParameters
diff --git a/add_mesh_extra_objects/add_mesh_gears.py b/add_mesh_extra_objects/add_mesh_gears.py
index 44128330..9170952a 100644
--- a/add_mesh_extra_objects/add_mesh_gears.py
+++ b/add_mesh_extra_objects/add_mesh_gears.py
@@ -683,6 +683,9 @@ class AddGear(Operator, object_utils.AddObjectHelper):
return context.scene is not None
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
@@ -738,6 +741,12 @@ class AddGear(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def invoke(self, context, event):
@@ -894,6 +903,9 @@ class AddWormGear(Operator, object_utils.AddObjectHelper):
box.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
@@ -950,6 +962,12 @@ class AddWormGear(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def WormGearParameters():
diff --git a/add_mesh_extra_objects/add_mesh_gemstones.py b/add_mesh_extra_objects/add_mesh_gemstones.py
index 5829794b..c47e4131 100644
--- a/add_mesh_extra_objects/add_mesh_gemstones.py
+++ b/add_mesh_extra_objects/add_mesh_gemstones.py
@@ -278,6 +278,9 @@ class AddDiamond(Operator, object_utils.AddObjectHelper):
box.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
@@ -333,6 +336,12 @@ class AddDiamond(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def DiamondParameters():
@@ -417,6 +426,9 @@ class AddGem(Operator, object_utils.AddObjectHelper):
box.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
@@ -472,6 +484,12 @@ class AddGem(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def GemParameters():
diff --git a/add_mesh_extra_objects/add_mesh_honeycomb.py b/add_mesh_extra_objects/add_mesh_honeycomb.py
index ef7d34db..73dea1d6 100644
--- a/add_mesh_extra_objects/add_mesh_honeycomb.py
+++ b/add_mesh_extra_objects/add_mesh_honeycomb.py
@@ -272,6 +272,10 @@ class add_mesh_honeycomb(bpy.types.Operator, object_utils.AddObjectHelper):
return context.scene is not None
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
('HoneyComb' in context.active_object.data.keys()) and (self.change == True):
@@ -314,6 +318,12 @@ class add_mesh_honeycomb(bpy.types.Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def HoneyCombParameters():
diff --git a/add_mesh_extra_objects/add_mesh_pipe_joint.py b/add_mesh_extra_objects/add_mesh_pipe_joint.py
index 00902ad5..65876136 100644
--- a/add_mesh_extra_objects/add_mesh_pipe_joint.py
+++ b/add_mesh_extra_objects/add_mesh_pipe_joint.py
@@ -169,6 +169,10 @@ class AddElbowJoint(Operator, object_utils.AddObjectHelper):
box.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
radius = self.radius
div = self.div
@@ -259,6 +263,12 @@ class AddElbowJoint(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
@@ -360,6 +370,10 @@ class AddTeeJoint(Operator, object_utils.AddObjectHelper):
box.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
radius = self.radius
div = self.div
@@ -514,6 +528,12 @@ class AddTeeJoint(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def WyeJointParameters():
@@ -622,6 +642,10 @@ class AddWyeJoint(Operator, object_utils.AddObjectHelper):
box.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
radius = self.radius
div = self.div
@@ -786,6 +810,12 @@ class AddWyeJoint(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
@@ -911,6 +941,10 @@ class AddCrossJoint(Operator, object_utils.AddObjectHelper):
box.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
radius = self.radius
div = self.div
@@ -1122,6 +1156,12 @@ class AddCrossJoint(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
@@ -1198,6 +1238,10 @@ class AddNJoint(Operator, object_utils.AddObjectHelper):
box.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
radius = self.radius
div = self.div
number = self.number
@@ -1353,4 +1397,10 @@ class AddNJoint(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
diff --git a/add_mesh_extra_objects/add_mesh_pyramid.py b/add_mesh_extra_objects/add_mesh_pyramid.py
index cfc086ff..c70988b7 100644
--- a/add_mesh_extra_objects/add_mesh_pyramid.py
+++ b/add_mesh_extra_objects/add_mesh_pyramid.py
@@ -162,6 +162,9 @@ class AddPyramid(bpy.types.Operator, object_utils.AddObjectHelper):
col.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
@@ -195,6 +198,12 @@ class AddPyramid(bpy.types.Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def PyramidParameters():
diff --git a/add_mesh_extra_objects/add_mesh_rocks/rockgen.py b/add_mesh_extra_objects/add_mesh_rocks/rockgen.py
index 26f15d97..7279d904 100644
--- a/add_mesh_extra_objects/add_mesh_rocks/rockgen.py
+++ b/add_mesh_extra_objects/add_mesh_rocks/rockgen.py
@@ -174,6 +174,9 @@ def createMeshObject(context, verts, edges, faces, name):
# Update mesh geometry after adding stuff.
mesh.update()
+ if bpy.context.mode == "EDIT_MESH":
+ bpy.ops.object.mode_set(mode='OBJECT')
+
return object_utils.object_data_add(context, mesh, operator=None)
@@ -749,7 +752,7 @@ def generateRocks(context, scaleX, skewX, scaleY, skewY, scaleZ, skewZ,
scale_fac, detail, display_detail, deform, rough,
smooth_fac, smooth_it,
numOfRocks=1, userSeed=1.0,
- scaleDisplace=False, randomSeed=True):
+ scaleDisplace=False, randomSeed=True, use_enter_edit_mode=False):
global LASTROCK
sigmaX = 0
sigmaY = 0
@@ -823,6 +826,8 @@ def generateRocks(context, scaleX, skewX, scaleY, skewY, scaleZ, skewZ,
else:
muZ = scaleZ
+ rocks = []
+
for i in range(numOfRocks):
# todo: enable different random values for each (x,y,z) corrdinate for
# each vertex. This will add additional randomness to the shape of the
@@ -928,13 +933,20 @@ def generateRocks(context, scaleX, skewX, scaleY, skewY, scaleZ, skewZ,
bpy.ops.mesh.normals_make_consistent()
bpy.ops.object.editmode_toggle()
+ if use_enter_edit_mode:
+ for m in rock.modifiers:
+ m.show_in_editmode = True
+ m.show_on_cage = True
+
# Store the last value of i:
shift = i
+ rocks.append(rock)
+
# Add the shift to LASTROCK:
LASTROCK += shift + 1
- return
+ return rocks
# Much of the code below is more-or-less imitation of other addons and as such
@@ -1087,12 +1099,10 @@ class OBJECT_OT_add_mesh_rock(bpy.types.Operator):
box.prop(self, 'user_seed')
box.prop(self, 'preset_values')
- @classmethod
- def poll(cls, context):
- return context.mode == 'OBJECT'
- # return (context.object is not None and context.object.mode == 'OBJECT')
-
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
# The following "if" block loads preset values:
if self.lastPreset != int(self.preset_values):
@@ -1120,7 +1130,7 @@ class OBJECT_OT_add_mesh_rock(bpy.types.Operator):
# *** Eliminated "deform_Var" and "rough_Var" so the script is not
# as complex to use. May add in again as advanced features. ***
if self.use_generate:
- generateRocks(context,
+ rocks = generateRocks(context,
self.scale_X,
self.skew_X,
self.scale_Y,
@@ -1137,10 +1147,19 @@ class OBJECT_OT_add_mesh_rock(bpy.types.Operator):
self.num_of_rocks,
self.user_seed,
self.use_scale_dis,
- self.use_random_seed)
+ self.use_random_seed,
+ use_enter_edit_mode)
- return {'FINISHED'}
+ for rock in rocks:
+ rock.select_set(True)
+
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
+ return {'FINISHED'}
# Register:
def menu_func_rocks(self, context):
diff --git a/add_mesh_extra_objects/add_mesh_round_brilliant.py b/add_mesh_extra_objects/add_mesh_round_brilliant.py
index cd796a53..49232151 100644
--- a/add_mesh_extra_objects/add_mesh_round_brilliant.py
+++ b/add_mesh_extra_objects/add_mesh_round_brilliant.py
@@ -422,6 +422,9 @@ class MESH_OT_primitive_brilliant_add(Operator, object_utils.AddObjectHelper):
# call mesh/object generator function with user inputs
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
@@ -466,6 +469,12 @@ class MESH_OT_primitive_brilliant_add(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def BrilliantParameters():
diff --git a/add_mesh_extra_objects/add_mesh_round_cube.py b/add_mesh_extra_objects/add_mesh_round_cube.py
index 3be67b5b..3c261908 100644
--- a/add_mesh_extra_objects/add_mesh_round_cube.py
+++ b/add_mesh_extra_objects/add_mesh_round_cube.py
@@ -388,6 +388,10 @@ class AddRoundCube(Operator, object_utils.AddObjectHelper):
)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
if self.arc_div <= 0 and self.lin_div <= 0:
self.report({'ERROR'},
"Either Arc Divisions or Linear Divisions must be greater than zero")
@@ -441,6 +445,12 @@ class AddRoundCube(Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def check(self, context):
diff --git a/add_mesh_extra_objects/add_mesh_star.py b/add_mesh_extra_objects/add_mesh_star.py
index 105648e3..30573864 100644
--- a/add_mesh_extra_objects/add_mesh_star.py
+++ b/add_mesh_extra_objects/add_mesh_star.py
@@ -202,6 +202,10 @@ class AddStar(bpy.types.Operator, object_utils.AddObjectHelper):
col.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
('Star' in context.active_object.data.keys()) and (self.change == True):
@@ -256,6 +260,12 @@ class AddStar(bpy.types.Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def StarParameters():
diff --git a/add_mesh_extra_objects/add_mesh_supertoroid.py b/add_mesh_extra_objects/add_mesh_supertoroid.py
index 6aec60b5..af63ca2a 100644
--- a/add_mesh_extra_objects/add_mesh_supertoroid.py
+++ b/add_mesh_extra_objects/add_mesh_supertoroid.py
@@ -199,6 +199,10 @@ class add_supertoroid(bpy.types.Operator, object_utils.AddObjectHelper):
col.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
props = self.properties
# check how the radii properties must be used
@@ -274,6 +278,12 @@ class add_supertoroid(bpy.types.Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def SuperToroidParameters():
diff --git a/add_mesh_extra_objects/add_mesh_teapot.py b/add_mesh_extra_objects/add_mesh_teapot.py
index c583bb7a..e4ddbecb 100644
--- a/add_mesh_extra_objects/add_mesh_teapot.py
+++ b/add_mesh_extra_objects/add_mesh_teapot.py
@@ -9,9 +9,10 @@ import mathutils
import io
import operator
import functools
+from bpy_extras import object_utils
-class AddTeapot(bpy.types.Operator):
+class AddTeapot(bpy.types.Operator, object_utils.AddObjectHelper):
bl_idname = "mesh.primitive_teapot_add"
bl_label = "Add Teapot"
bl_description = "Construct a teapot or teaspoon mesh"
@@ -31,16 +32,42 @@ class AddTeapot(bpy.types.Operator):
default='1',
)
+ def draw(self, context):
+ layout = self.layout
+
+ box = layout.box()
+ box.prop(self, 'resolution')
+
+ box = layout.box()
+ box.prop(self, 'objecttype')
+
+ # generic transform props
+ box = layout.box()
+ box.prop(self, 'align', expand=True)
+ box.prop(self, 'location', expand=True)
+ box.prop(self, 'rotation', expand=True)
+
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
cmode = bpy.context.mode
verts, faces = make_teapot(self.objecttype,
self.resolution)
# Actually create the mesh object from this geometry data.
- obj = create_mesh_object(context, verts, [], faces, "Teapot")
+ obj = create_mesh_object(self, context, verts, [], faces, "Teapot")
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.remove_doubles()
if cmode != "EDIT_MESH":
bpy.ops.object.mode_set(mode=cmode)
+
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
@@ -56,7 +83,7 @@ def create_mesh_face_hack(faces):
faces[:] = faces_copy
-def create_mesh_object(context, verts, edges, faces, name):
+def create_mesh_object(self, context, verts, edges, faces, name):
create_mesh_face_hack(faces)
@@ -66,8 +93,8 @@ def create_mesh_object(context, verts, edges, faces, name):
mesh.from_pydata(verts, edges, faces)
# Update mesh geometry after adding stuff.
mesh.update()
- from bpy_extras import object_utils
- return object_utils.object_data_add(context, mesh, operator=None)
+
+ return object_utils.object_data_add(context, mesh, operator=self)
# ==========================
diff --git a/add_mesh_extra_objects/add_mesh_torusknot.py b/add_mesh_extra_objects/add_mesh_torusknot.py
index 73a0b80f..ac666289 100644
--- a/add_mesh_extra_objects/add_mesh_torusknot.py
+++ b/add_mesh_extra_objects/add_mesh_torusknot.py
@@ -138,6 +138,10 @@ class AddTorusKnot(bpy.types.Operator, object_utils.AddObjectHelper):
col.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
+
if bpy.context.mode == "OBJECT":
if context.selected_objects != [] and context.active_object and \
('TorusKnot' in context.active_object.data.keys()) and (self.change == True):
@@ -177,6 +181,12 @@ class AddTorusKnot(bpy.types.Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def TorusKnotParameters():
diff --git a/add_mesh_extra_objects/add_mesh_twisted_torus.py b/add_mesh_extra_objects/add_mesh_twisted_torus.py
index 8bc10169..ba6b4fc1 100644
--- a/add_mesh_extra_objects/add_mesh_twisted_torus.py
+++ b/add_mesh_extra_objects/add_mesh_twisted_torus.py
@@ -225,6 +225,9 @@ class AddTwistedTorus(bpy.types.Operator, object_utils.AddObjectHelper):
col.prop(self, 'rotation', expand=True)
def execute(self, context):
+ # turn off 'Enter Edit Mode'
+ use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
+ bpy.context.preferences.edit.use_enter_edit_mode = False
if self.use_abso is True:
extra_helper = (self.abso_major_rad - self.abso_minor_rad) * 0.5
@@ -288,6 +291,12 @@ class AddTwistedTorus(bpy.types.Operator, object_utils.AddObjectHelper):
context.active_object.name = name_active_object
bpy.ops.object.mode_set(mode='EDIT')
+ if use_enter_edit_mode:
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+ # restore pre operator state
+ bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
+
return {'FINISHED'}
def TwistedTorusParameters():
diff --git a/ant_landscape/ant_functions.py b/ant_landscape/ant_functions.py
index b4e1e1f5..47de9ef2 100644
--- a/ant_landscape/ant_functions.py
+++ b/ant_landscape/ant_functions.py
@@ -59,32 +59,28 @@ def create_mesh_object(context, verts, edges, faces, name):
def grid_gen(sub_d_x, sub_d_y, tri, meshsize_x, meshsize_y, props, water_plane, water_level):
verts = []
faces = []
+ vappend = verts.append
+ fappend = faces.append
for i in range (0, sub_d_x):
x = meshsize_x * (i / (sub_d_x - 1) - 1 / 2)
for j in range(0, sub_d_y):
y = meshsize_y * (j / (sub_d_y - 1) - 1 / 2)
- if water_plane:
- z = water_level
- else:
+ if not water_plane:
z = noise_gen((x, y, 0), props)
-
- verts.append((x,y,z))
-
- count = 0
- for i in range (0, sub_d_y * (sub_d_x - 1)):
- if count < sub_d_y - 1 :
- A = i + 1
- B = i
- C = (i + sub_d_y)
- D = (i + sub_d_y) + 1
- if tri:
- faces.append((A, B, D))
- faces.append((B, C, D))
else:
- faces.append((A, B, C, D))
- count = count + 1
- else:
- count = 0
+ z = water_level
+ vappend((x,y,z))
+
+ if i > 0 and j > 0:
+ A = i * sub_d_y + (j - 1)
+ B = i * sub_d_y + j
+ C = (i - 1) * sub_d_y + j
+ D = (i - 1) * sub_d_y + (j - 1)
+ if not tri:
+ fappend((A, B, C, D))
+ else:
+ fappend((A, B, D))
+ fappend((B, C, D))
return verts, faces
@@ -93,6 +89,8 @@ def grid_gen(sub_d_x, sub_d_y, tri, meshsize_x, meshsize_y, props, water_plane,
def sphere_gen(sub_d_x, sub_d_y, tri, meshsize, props, water_plane, water_level):
verts = []
faces = []
+ vappend = verts.append
+ fappend = faces.append
sub_d_x += 1
sub_d_y += 1
for i in range(0, sub_d_x):
@@ -104,7 +102,7 @@ def sphere_gen(sub_d_x, sub_d_y, tri, meshsize, props, water_plane, water_level)
h = water_level
else:
h = noise_gen((u, v, w), props) / meshsize
- verts.append(((u + u * h), (v + v * h), (w + w * h)))
+ vappend(((u + u * h), (v + v * h), (w + w * h)))
count = 0
for i in range (0, sub_d_y * (sub_d_x - 1)):
@@ -114,10 +112,10 @@ def sphere_gen(sub_d_x, sub_d_y, tri, meshsize, props, water_plane, water_level)
C = (i + sub_d_y)
D = (i + sub_d_y) + 1
if tri:
- faces.append((A, B, D))
- faces.append((B, C, D))
+ fappend((A, B, D))
+ fappend((B, C, D))
else:
- faces.append((A, B, C, D))
+ fappend((A, B, C, D))
count = count + 1
else:
count = 0
@@ -137,8 +135,7 @@ class AntLandscapeRefresh(bpy.types.Operator):
@classmethod
def poll(cls, context):
ob = bpy.context.active_object
- return (ob.ant_landscape and not ob.ant_landscape['sphere_mesh'])
-
+ return (ob.ant_landscape and not ob.ant_landscape.sphere_mesh)
def execute(self, context):
# ant object items
diff --git a/ant_landscape/ant_noise.py b/ant_landscape/ant_noise.py
index c1ddda19..7d6b12e8 100644
--- a/ant_landscape/ant_noise.py
+++ b/ant_landscape/ant_noise.py
@@ -565,15 +565,15 @@ def noise_gen(coords, props):
o_range = 1.0
else:
# Randomise origin
- o_range = 10000.0
+ o_range = 100
seed_set(rseed)
origin = random_unit_vector()
ox = (origin[0] * o_range)
oy = (origin[1] * o_range)
- oz = (origin[2] * o_range)
- origin_x = (ox - (ox / 2)) + x_offset
- origin_y = (oy - (oy / 2)) + y_offset
- origin_z = (oz - (oz / 2)) + z_offset
+ oz = 0
+ origin_x = (ox - (ox * 0.5)) + x_offset
+ origin_y = (oy - (oy * 0.5)) + y_offset
+ origin_z = oz + z_offset
ncoords = (x / (nsize * size_x) + origin_x, y / (nsize * size_y) + origin_y, z / (nsize * size_z) + origin_z)
diff --git a/archipack/archipack_manipulator.py b/archipack/archipack_manipulator.py
index 0eba8aba..fb454f69 100644
--- a/archipack/archipack_manipulator.py
+++ b/archipack/archipack_manipulator.py
@@ -118,9 +118,11 @@ class ArchipackActiveManip:
Check for manipulable validity
to disable modal when required
"""
+ o = bpy.data.objects.get(self.object_name)
return (
self.manipulable is None or
- bpy.data.objects.find(self.object_name) < 0
+ o is None or
+ not o.select_get()
)
def exit(self):
@@ -167,7 +169,6 @@ def check_stack(key):
# print("check_stack : key.dirty %s" % (key))
remove_manipulable(key)
return True
-
return False
diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index 40ca5fc4..b935768d 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -95,7 +95,7 @@ class ImportFBX(bpy.types.Operator, ImportHelper):
default=1.0,
)
bake_space_transform: BoolProperty(
- name="!EXPERIMENTAL! Apply Transform",
+ name="Apply Transform",
description="Bake space transform into object data, avoids getting unwanted rotations to objects when "
"target space is not aligned with Blender's space "
"(WARNING! experimental option, use at own risks, known broken with armatures/animations)",
@@ -103,7 +103,7 @@ class ImportFBX(bpy.types.Operator, ImportHelper):
)
use_custom_normals: BoolProperty(
- name="Import Normals",
+ name="Custom Normals",
description="Import custom normals, if available (otherwise Blender will recompute them)",
default=True,
)
@@ -138,13 +138,13 @@ class ImportFBX(bpy.types.Operator, ImportHelper):
)
use_subsurf: BoolProperty(
- name="Import Subdivision Surface",
+ name="Subdivision Data",
description="Import FBX subdivision information as subdivision surface modifiers",
default=False,
)
use_custom_props: BoolProperty(
- name="Import User Properties",
+ name="Custom Properties",
description="Import user properties as custom properties",
default=True,
)
@@ -273,7 +273,9 @@ class FBX_PT_import_transform(bpy.types.Panel):
layout.prop(operator, "global_scale")
layout.prop(operator, "decal_offset")
- layout.prop(operator, "bake_space_transform")
+ row = layout.row()
+ row.prop(operator, "bake_space_transform")
+ row.label(text="", icon='ERROR')
layout.prop(operator, "use_prepost_rot")
@@ -425,7 +427,7 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
"but many other applications do not handle the same way)",
)
bake_space_transform: BoolProperty(
- name="!EXPERIMENTAL! Apply Transform",
+ name="Apply Transform",
description="Bake space transform into object data, avoids getting unwanted rotations to objects when "
"target space is not aligned with Blender's space "
"(WARNING! experimental option, use at own risks, known broken with armatures/animations)",
@@ -688,7 +690,7 @@ class FBX_PT_export_include(bpy.types.Panel):
sfile = context.space_data
operator = sfile.active_operator
- sublayout = layout.column()
+ sublayout = layout.column(heading="Limit to")
sublayout.enabled = (operator.batch_mode == 'OFF')
sublayout.prop(operator, "use_selection")
sublayout.prop(operator, "use_active_collection")
@@ -725,7 +727,9 @@ class FBX_PT_export_transform(bpy.types.Panel):
layout.prop(operator, "axis_up")
layout.prop(operator, "apply_unit_scale")
- layout.prop(operator, "bake_space_transform")
+ row = layout.row()
+ row.prop(operator, "bake_space_transform")
+ row.label(text="", icon='ERROR')
class FBX_PT_export_geometry(bpy.types.Panel):
diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 648cedc7..336a35df 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -15,8 +15,8 @@
bl_info = {
'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin SchmithĂĽsen, Jim Eckerlein, and many external contributors',
- "version": (1, 2, 75),
- 'blender': (2, 83, 9),
+ "version": (1, 3, 12),
+ 'blender': (2, 90, 0),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',
'warning': '',
@@ -26,6 +26,7 @@ bl_info = {
'category': 'Import-Export',
}
+
def get_version_string():
return str(bl_info['version'][0]) + '.' + str(bl_info['version'][1]) + '.' + str(bl_info['version'][2])
@@ -560,10 +561,13 @@ class GLTF_PT_export_include(bpy.types.Panel):
sfile = context.space_data
operator = sfile.active_operator
- layout.prop(operator, 'use_selection')
- layout.prop(operator, 'export_extras')
- layout.prop(operator, 'export_cameras')
- layout.prop(operator, 'export_lights')
+ col = layout.column(heading = "Limit to", align = True)
+ col.prop(operator, 'use_selection')
+
+ col = layout.column(heading = "Data", align = True)
+ col.prop(operator, 'export_extras')
+ col.prop(operator, 'export_cameras')
+ col.prop(operator, 'export_lights')
class GLTF_PT_export_transform(bpy.types.Panel):
bl_space_type = 'FILE_BROWSER'
@@ -891,6 +895,9 @@ class ImportGLTF2(Operator, ImportHelper):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
layout.prop(self, 'import_pack_images')
layout.prop(self, 'import_shading')
layout.prop(self, 'guess_original_bind_pose')
diff --git a/io_scene_obj/__init__.py b/io_scene_obj/__init__.py
index 997deee2..e9fc8259 100644
--- a/io_scene_obj/__init__.py
+++ b/io_scene_obj/__init__.py
@@ -234,97 +234,6 @@ class OBJ_PT_import_geometry(bpy.types.Panel):
col.prop(operator, "use_groups_as_vgroups")
-class OBJ_PT_export_include(bpy.types.Panel):
- bl_space_type = 'FILE_BROWSER'
- bl_region_type = 'TOOL_PROPS'
- bl_label = "Include"
- bl_parent_id = "FILE_PT_operator"
-
- @classmethod
- def poll(cls, context):
- sfile = context.space_data
- operator = sfile.active_operator
-
- return operator.bl_idname == "EXPORT_SCENE_OT_obj"
-
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False # No animation.
-
- sfile = context.space_data
- operator = sfile.active_operator
-
- layout.prop(operator, 'use_selection')
- layout.prop(operator, 'use_blen_objects')
- layout.prop(operator, 'group_by_object')
- layout.prop(operator, 'group_by_material')
- layout.prop(operator, 'use_animation')
-
-
-class OBJ_PT_export_transform(bpy.types.Panel):
- bl_space_type = 'FILE_BROWSER'
- bl_region_type = 'TOOL_PROPS'
- bl_label = "Transform"
- bl_parent_id = "FILE_PT_operator"
-
- @classmethod
- def poll(cls, context):
- sfile = context.space_data
- operator = sfile.active_operator
-
- return operator.bl_idname == "EXPORT_SCENE_OT_obj"
-
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False # No animation.
-
- sfile = context.space_data
- operator = sfile.active_operator
-
- layout.prop(operator, 'global_scale')
- layout.prop(operator, 'path_mode')
- layout.prop(operator, 'axis_forward')
- layout.prop(operator, 'axis_up')
-
-
-class OBJ_PT_export_geometry(bpy.types.Panel):
- bl_space_type = 'FILE_BROWSER'
- bl_region_type = 'TOOL_PROPS'
- bl_label = "Geometry"
- bl_parent_id = "FILE_PT_operator"
- bl_options = {'DEFAULT_CLOSED'}
-
- @classmethod
- def poll(cls, context):
- sfile = context.space_data
- operator = sfile.active_operator
-
- return operator.bl_idname == "EXPORT_SCENE_OT_obj"
-
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False # No animation.
-
- sfile = context.space_data
- operator = sfile.active_operator
-
- layout.prop(operator, 'use_mesh_modifiers')
- # Property definition disabled, not working in 2.8 currently.
- # layout.prop(operator, 'use_mesh_modifiers_render')
- layout.prop(operator, 'use_smooth_groups')
- layout.prop(operator, 'use_smooth_groups_bitflags')
- layout.prop(operator, 'use_normals')
- layout.prop(operator, 'use_uvs')
- layout.prop(operator, 'use_materials')
- layout.prop(operator, 'use_triangles')
- layout.prop(operator, 'use_nurbs', text="Curves as NURBS")
- layout.prop(operator, 'use_vertex_groups')
- layout.prop(operator, 'keep_vertex_order')
-
-
@orientation_helper(axis_forward='-Z', axis_up='Y')
class ExportOBJ(bpy.types.Operator, ExportHelper):
"""Save a Wavefront OBJ File"""
@@ -415,18 +324,18 @@ class ExportOBJ(bpy.types.Operator, ExportHelper):
# grouping group
use_blen_objects: BoolProperty(
- name="Objects as OBJ Objects",
- description="",
+ name="OBJ Objects",
+ description="Export Blender objects as OBJ objects",
default=True,
)
group_by_object: BoolProperty(
- name="Objects as OBJ Groups ",
- description="",
+ name="OBJ Groups",
+ description="Export Blender objects as OBJ groups",
default=False,
)
group_by_material: BoolProperty(
name="Material Groups",
- description="",
+ description="Generate an OBJ group for each part of a geometry using a different material",
default=False,
)
keep_vertex_order: BoolProperty(
@@ -468,6 +377,103 @@ class ExportOBJ(bpy.types.Operator, ExportHelper):
pass
+class OBJ_PT_export_include(bpy.types.Panel):
+ bl_space_type = 'FILE_BROWSER'
+ bl_region_type = 'TOOL_PROPS'
+ bl_label = "Include"
+ bl_parent_id = "FILE_PT_operator"
+
+ @classmethod
+ def poll(cls, context):
+ sfile = context.space_data
+ operator = sfile.active_operator
+
+ return operator.bl_idname == "EXPORT_SCENE_OT_obj"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
+ sfile = context.space_data
+ operator = sfile.active_operator
+
+ col = layout.column(heading="Limit to")
+ col.prop(operator, 'use_selection')
+
+ col = layout.column(heading="Objects as", align=True)
+ col.prop(operator, 'use_blen_objects')
+ col.prop(operator, 'group_by_object')
+ col.prop(operator, 'group_by_material')
+
+ layout.separator()
+
+ layout.prop(operator, 'use_animation')
+
+
+class OBJ_PT_export_transform(bpy.types.Panel):
+ bl_space_type = 'FILE_BROWSER'
+ bl_region_type = 'TOOL_PROPS'
+ bl_label = "Transform"
+ bl_parent_id = "FILE_PT_operator"
+
+ @classmethod
+ def poll(cls, context):
+ sfile = context.space_data
+ operator = sfile.active_operator
+
+ return operator.bl_idname == "EXPORT_SCENE_OT_obj"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
+ sfile = context.space_data
+ operator = sfile.active_operator
+
+ layout.prop(operator, 'global_scale')
+ layout.prop(operator, 'path_mode')
+ layout.prop(operator, 'axis_forward')
+ layout.prop(operator, 'axis_up')
+
+
+class OBJ_PT_export_geometry(bpy.types.Panel):
+ bl_space_type = 'FILE_BROWSER'
+ bl_region_type = 'TOOL_PROPS'
+ bl_label = "Geometry"
+ bl_parent_id = "FILE_PT_operator"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ sfile = context.space_data
+ operator = sfile.active_operator
+
+ return operator.bl_idname == "EXPORT_SCENE_OT_obj"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
+ sfile = context.space_data
+ operator = sfile.active_operator
+
+ layout.prop(operator, 'use_mesh_modifiers')
+ # Property definition disabled, not working in 2.8 currently.
+ # layout.prop(operator, 'use_mesh_modifiers_render')
+ layout.prop(operator, 'use_smooth_groups')
+ layout.prop(operator, 'use_smooth_groups_bitflags')
+ layout.prop(operator, 'use_normals')
+ layout.prop(operator, 'use_uvs')
+ layout.prop(operator, 'use_materials')
+ layout.prop(operator, 'use_triangles')
+ layout.prop(operator, 'use_nurbs', text="Curves as NURBS")
+ layout.prop(operator, 'use_vertex_groups')
+ layout.prop(operator, 'keep_vertex_order')
+
+
def menu_func_import(self, context):
self.layout.operator(ImportOBJ.bl_idname, text="Wavefront (.obj)")
diff --git a/node_wrangler.py b/node_wrangler.py
index e26da88b..e9ba5e74 100644
--- a/node_wrangler.py
+++ b/node_wrangler.py
@@ -19,8 +19,8 @@
bl_info = {
"name": "Node Wrangler",
"author": "Bartek Skorupa, Greg Zaal, Sebastian Koenig, Christian Brinkmann, Florian Meyer",
- "version": (3, 36),
- "blender": (2, 80, 0),
+ "version": (3, 37),
+ "blender": (2, 83, 0),
"location": "Node Editor Toolbar or Shift-W",
"description": "Various tools to enhance and speed up node-based workflow",
"warning": "",
@@ -596,9 +596,10 @@ draw_color_sets = {
)
}
+viewer_socket_name = "tmp_viewer"
def is_visible_socket(socket):
- return not socket.hide and socket.enabled
+ return not socket.hide and socket.enabled and socket.type != 'CUSTOM'
def nice_hotkey_name(punc):
# convert the ugly string name into the actual character
@@ -1030,10 +1031,9 @@ def draw_callback_nodeoutline(self, context, mode):
bgl.glDisable(bgl.GL_BLEND)
bgl.glDisable(bgl.GL_LINE_SMOOTH)
-
-def get_nodes_links(context):
+def get_active_tree(context):
tree = context.space_data.node_tree
-
+ path = []
# Get nodes from currently edited tree.
# If user is editing a group, space_data.node_tree is still the base level (outside group).
# context.active_node is in the group though, so if space_data.node_tree.nodes.active is not
@@ -1042,9 +1042,71 @@ def get_nodes_links(context):
if tree.nodes.active:
while tree.nodes.active != context.active_node:
tree = tree.nodes.active.node_tree
+ path.append(tree)
+ return tree, path
+def get_nodes_links(context):
+ tree, path = get_active_tree(context)
return tree.nodes, tree.links
+def is_viewer_socket(socket):
+ # checks if a internal socket is a valid viewer socket
+ return socket.name == viewer_socket_name and socket.NWViewerSocket
+
+def get_internal_socket(socket):
+ #get the internal socket from a socket inside or outside the group
+ node = socket.node
+ if node.type == 'GROUP_OUTPUT':
+ source_iterator = node.inputs
+ iterator = node.id_data.outputs
+ elif node.type == 'GROUP_INPUT':
+ source_iterator = node.outputs
+ iterator = node.id_data.inputs
+ elif hasattr(node, "node_tree"):
+ if socket.is_output:
+ source_iterator = node.outputs
+ iterator = node.node_tree.outputs
+ else:
+ source_iterator = node.inputs
+ iterator = node.node_tree.inputs
+ else:
+ return None
+
+ for i, s in enumerate(source_iterator):
+ if s == socket:
+ break
+ return iterator[i]
+
+def is_viewer_link(link, output_node):
+ if "Emission Viewer" in link.to_node.name or link.to_node == output_node and link.to_socket == output_node.inputs[0]:
+ return True
+ if link.to_node.type == 'GROUP_OUTPUT':
+ socket = get_internal_socket(link.to_socket)
+ if is_viewer_socket(socket):
+ return True
+ return False
+
+def get_group_output_node(tree):
+ for node in tree.nodes:
+ if node.type == 'GROUP_OUTPUT' and node.is_active_output == True:
+ return node
+
+def get_output_location(tree):
+ # get right-most location
+ sorted_by_xloc = (sorted(tree.nodes, key=lambda x: x.location.x))
+ max_xloc_node = sorted_by_xloc[-1]
+ if max_xloc_node.name == 'Emission Viewer':
+ max_xloc_node = sorted_by_xloc[-2]
+
+ # get average y location
+ sum_yloc = 0
+ for node in tree.nodes:
+ sum_yloc += node.location.y
+
+ loc_x = max_xloc_node.location.x + max_xloc_node.dimensions.x + 80
+ loc_y = sum_yloc / len(tree.nodes)
+ return loc_x, loc_y
+
# Principled prefs
class NWPrincipledPreferences(bpy.types.PropertyGroup):
base_color: StringProperty(
@@ -1624,13 +1686,17 @@ class NWAddAttrNode(Operator, NWBase):
nodes.active.attribute_name = self.attr_name
return {'FINISHED'}
-
class NWEmissionViewer(Operator, NWBase):
bl_idname = "node.nw_emission_viewer"
bl_label = "Emission Viewer"
bl_description = "Connect active node to Emission Shader for shadeless previews"
bl_options = {'REGISTER', 'UNDO'}
+ def __init__(self):
+ self.shader_output_type = ""
+ self.shader_output_ident = ""
+ self.shader_viewer_ident = ""
+
@classmethod
def poll(cls, context):
if nw_check(context):
@@ -1643,67 +1709,172 @@ class NWEmissionViewer(Operator, NWBase):
return True
return False
- def invoke(self, context, event):
- space = context.space_data
- shader_type = space.shader_type
+ def ensure_viewer_socket(self, node, socket_type, connect_socket=None):
+ #check if a viewer output already exists in a node group otherwise create
+ if hasattr(node, "node_tree"):
+ index = None
+ if len(node.node_tree.outputs):
+ free_socket = None
+ for i, socket in enumerate(node.node_tree.outputs):
+ if is_viewer_socket(socket) and is_visible_socket(node.outputs[i]) and socket.type == socket_type:
+ #if viewer output is already used but leads to the same socket we can still use it
+ is_used = self.is_socket_used_other_mats(socket)
+ if is_used:
+ if connect_socket == None:
+ continue
+ groupout = get_group_output_node(node.node_tree)
+ groupout_input = groupout.inputs[i]
+ links = groupout_input.links
+ if connect_socket not in [link.from_socket for link in links]:
+ continue
+ index=i
+ break
+ if not free_socket:
+ free_socket = i
+ if not index and free_socket:
+ index = free_socket
+
+ if not index:
+ #create viewer socket
+ node.node_tree.outputs.new(socket_type, viewer_socket_name)
+ index = len(node.node_tree.outputs) - 1
+ node.node_tree.outputs[index].NWViewerSocket = True
+ return index
+
+ def init_shader_variables(self, space, shader_type):
if shader_type == 'OBJECT':
if space.id not in [light for light in bpy.data.lights]: # cannot use bpy.data.lights directly as iterable
- shader_output_type = "OUTPUT_MATERIAL"
- shader_output_ident = "ShaderNodeOutputMaterial"
- shader_viewer_ident = "ShaderNodeEmission"
+ self.shader_output_type = "OUTPUT_MATERIAL"
+ self.shader_output_ident = "ShaderNodeOutputMaterial"
+ self.shader_viewer_ident = "ShaderNodeEmission"
else:
- shader_output_type = "OUTPUT_LIGHT"
- shader_output_ident = "ShaderNodeOutputLight"
- shader_viewer_ident = "ShaderNodeEmission"
+ self.shader_output_type = "OUTPUT_LIGHT"
+ self.shader_output_ident = "ShaderNodeOutputLight"
+ self.shader_viewer_ident = "ShaderNodeEmission"
elif shader_type == 'WORLD':
- shader_output_type = "OUTPUT_WORLD"
- shader_output_ident = "ShaderNodeOutputWorld"
- shader_viewer_ident = "ShaderNodeBackground"
+ self.shader_output_type = "OUTPUT_WORLD"
+ self.shader_output_ident = "ShaderNodeOutputWorld"
+ self.shader_viewer_ident = "ShaderNodeBackground"
+
+ def get_shader_output_node(self, tree):
+ for node in tree.nodes:
+ if node.type == self.shader_output_type and node.is_active_output == True:
+ return node
+
+ @classmethod
+ def ensure_group_output(cls, tree):
+ #check if a group output node exists otherwise create
+ groupout = get_group_output_node(tree)
+ if not groupout:
+ groupout = tree.nodes.new('NodeGroupOutput')
+ loc_x, loc_y = get_output_location(tree)
+ groupout.location.x = loc_x
+ groupout.location.y = loc_y
+ groupout.select = False
+ return groupout
+
+ @classmethod
+ def search_sockets(cls, node, sockets, index=None):
+ #recursevley scan nodes for viewer sockets and store in list
+ for i, input_socket in enumerate(node.inputs):
+ if index and i != index:
+ continue
+ if len(input_socket.links):
+ link = input_socket.links[0]
+ next_node = link.from_node
+ external_socket = link.from_socket
+ if hasattr(next_node, "node_tree"):
+ for socket_index, s in enumerate(next_node.outputs):
+ if s == external_socket:
+ break
+ socket = next_node.node_tree.outputs[socket_index]
+ if is_viewer_socket(socket) and socket not in sockets:
+ sockets.append(socket)
+ #continue search inside of node group but restrict socket to where we came from
+ groupout = get_group_output_node(next_node.node_tree)
+ cls.search_sockets(groupout, sockets, index=socket_index)
+
+ @classmethod
+ def scan_nodes(cls, tree, sockets):
+ # get all viewer sockets in a material tree
+ for node in tree.nodes:
+ if hasattr(node, "node_tree"):
+ for socket in node.node_tree.outputs:
+ if is_viewer_socket(socket) and (socket not in sockets):
+ sockets.append(socket)
+ cls.scan_nodes(node.node_tree, sockets)
+
+ def link_leads_to_used_socket(self, link):
+ #return True if link leads to a socket that is already used in this material
+ socket = get_internal_socket(link.to_socket)
+ return (socket and self.is_socket_used_active_mat(socket))
+
+ def is_socket_used_active_mat(self, socket):
+ #ensure used sockets in active material is calculated and check given socket
+ if not hasattr(self, "used_viewer_sockets_active_mat"):
+ self.used_viewer_sockets_active_mat = []
+ materialout = self.get_shader_output_node(bpy.context.space_data.node_tree)
+ if materialout:
+ emission = self.get_viewer_node(materialout)
+ self.search_sockets((emission if emission else materialout), self.used_viewer_sockets_active_mat)
+ return socket in self.used_viewer_sockets_active_mat
+
+ def is_socket_used_other_mats(self, socket):
+ #ensure used sockets in other materials are calculated and check given socket
+ if not hasattr(self, "used_viewer_sockets_other_mats"):
+ self.used_viewer_sockets_other_mats = []
+ for mat in bpy.data.materials:
+ if mat.node_tree == bpy.context.space_data.node_tree or not hasattr(mat.node_tree, "nodes"):
+ continue
+ # get viewer node
+ materialout = self.get_shader_output_node(mat.node_tree)
+ if materialout:
+ emission = self.get_viewer_node(materialout)
+ self.search_sockets((emission if emission else materialout), self.used_viewer_sockets_other_mats)
+ return socket in self.used_viewer_sockets_other_mats
+
+ @staticmethod
+ def get_viewer_node(materialout):
+ input_socket = materialout.inputs[0]
+ if len(input_socket.links) > 0:
+ node = input_socket.links[0].from_node
+ if node.type == 'EMISSION' and node.name == "Emission Viewer":
+ return node
+
+ def invoke(self, context, event):
+ space = context.space_data
+ shader_type = space.shader_type
+ self.init_shader_variables(space, shader_type)
shader_types = [x[1] for x in shaders_shader_nodes_props]
mlocx = event.mouse_region_x
mlocy = event.mouse_region_y
select_node = bpy.ops.node.select(mouse_x=mlocx, mouse_y=mlocy, extend=False)
if 'FINISHED' in select_node: # only run if mouse click is on a node
- nodes, links = get_nodes_links(context)
- in_group = context.active_node != space.node_tree.nodes.active
+ active_tree, path_to_tree = get_active_tree(context)
+ nodes, links = active_tree.nodes, active_tree.links
+ base_node_tree = space.node_tree
active = nodes.active
output_types = [x[1] for x in shaders_output_nodes_props]
valid = False
if active:
- if (active.name != "Emission Viewer") and (active.type not in output_types) and not in_group:
+ if (active.name != "Emission Viewer") and (active.type not in output_types):
for out in active.outputs:
if is_visible_socket(out):
valid = True
break
if valid:
- # get material_output node, store selection, deselect all
+ # get material_output node
materialout = None # placeholder node
- selection = []
- for node in nodes:
- if node.type == shader_output_type:
- materialout = node
- if node.select:
- selection.append(node.name)
- node.select = False
- if not materialout:
- # get right-most location
- sorted_by_xloc = (sorted(nodes, key=lambda x: x.location.x))
- max_xloc_node = sorted_by_xloc[-1]
- if max_xloc_node.name == 'Emission Viewer':
- max_xloc_node = sorted_by_xloc[-2]
-
- # get average y location
- sum_yloc = 0
- for node in nodes:
- sum_yloc += node.location.y
+ delete_sockets = []
- new_locx = max_xloc_node.location.x + max_xloc_node.dimensions.x + 80
- new_locy = sum_yloc / len(nodes)
+ #scan through all nodes in tree including nodes inside of groups to find viewer sockets
+ self.scan_nodes(base_node_tree, delete_sockets)
- materialout = nodes.new(shader_output_ident)
- materialout.location.x = new_locx
- materialout.location.y = new_locy
+ materialout = self.get_shader_output_node(base_node_tree)
+ if not materialout:
+ materialout = base_node_tree.nodes.new(self.shader_output_ident)
+ materialout.location = get_output_location(base_node_tree)
materialout.select = False
# Analyze outputs, add "Emission Viewer" if needed, make links
out_i = None
@@ -1715,24 +1886,28 @@ class NWEmissionViewer(Operator, NWBase):
out_i = valid_outputs[0] # Start index of node's outputs
for i, valid_i in enumerate(valid_outputs):
for out_link in active.outputs[valid_i].links:
- if "Emission Viewer" in out_link.to_node.name or (out_link.to_node == materialout and out_link.to_socket == materialout.inputs[0]):
- if i < len(valid_outputs) - 1:
- out_i = valid_outputs[i + 1]
- else:
- out_i = valid_outputs[0]
+ if is_viewer_link(out_link, materialout):
+ if nodes == base_node_tree.nodes or self.link_leads_to_used_socket(out_link):
+ if i < len(valid_outputs) - 1:
+ out_i = valid_outputs[i + 1]
+ else:
+ out_i = valid_outputs[0]
+
make_links = [] # store sockets for new links
+ delete_nodes = [] # store unused nodes to delete in the end
if active.outputs:
# If output type not 'SHADER' - "Emission Viewer" needed
if active.outputs[out_i].type != 'SHADER':
+ socket_type = 'NodeSocketColor'
# get Emission Viewer node
emission_exists = False
- emission_placeholder = nodes[0]
- for node in nodes:
+ emission_placeholder = base_node_tree.nodes[0]
+ for node in base_node_tree.nodes:
if "Emission Viewer" in node.name:
emission_exists = True
emission_placeholder = node
if not emission_exists:
- emission = nodes.new(shader_viewer_ident)
+ emission = base_node_tree.nodes.new(self.shader_viewer_ident)
emission.hide = True
emission.location = [materialout.location.x, (materialout.location.y + 40)]
emission.label = "Viewer"
@@ -1742,7 +1917,7 @@ class NWEmissionViewer(Operator, NWBase):
emission.select = False
else:
emission = emission_placeholder
- make_links.append((active.outputs[out_i], emission.inputs[0]))
+ output_socket = emission.inputs[0]
# If Viewer is connected to output by user, don't change those connections (patch by gandalf3)
if emission.outputs[0].links.__len__() > 0:
@@ -1762,19 +1937,47 @@ class NWEmissionViewer(Operator, NWBase):
else:
# Output type is 'SHADER', no Viewer needed. Delete Viewer if exists.
- make_links.append((active.outputs[out_i], materialout.inputs[1 if active.outputs[out_i].name == "Volume" else 0]))
- for node in nodes:
+ socket_type = 'NodeSocketShader'
+ materialout_index = 1 if active.outputs[out_i].name == "Volume" else 0
+ make_links.append((active.outputs[out_i], materialout.inputs[materialout_index]))
+ output_socket = materialout.inputs[materialout_index]
+ for node in base_node_tree.nodes:
if node.name == 'Emission Viewer':
- node.select = True
- bpy.ops.node.delete()
+ delete_nodes.append((base_node_tree, node))
for li_from, li_to in make_links:
- links.new(li_from, li_to)
- # Restore selection
+ base_node_tree.links.new(li_from, li_to)
+
+ # Crate links through node groups until we reach the active node
+ tree = base_node_tree
+ link_end = output_socket
+ while tree.nodes.active != active:
+ node = tree.nodes.active
+ index = self.ensure_viewer_socket(node, socket_type, connect_socket=active.outputs[out_i] if node.node_tree.nodes.active == active else None)
+ link_start = node.outputs[index]
+ node_socket = node.node_tree.outputs[index]
+ if node_socket in delete_sockets:
+ delete_sockets.remove(node_socket)
+ tree.links.new(link_start, link_end)
+ # Iterate
+ link_end = self.ensure_group_output(node.node_tree).inputs[index]
+ tree = tree.nodes.active.node_tree
+ tree.links.new(active.outputs[out_i], link_end)
+
+ # Delete sockets
+ for socket in delete_sockets:
+ if not self.is_socket_used_other_mats(socket):
+ tree = socket.id_data
+ tree.outputs.remove(socket)
+
+ # Delete nodes
+ for tree, node in delete_nodes:
+ tree.nodes.remove(node)
+
nodes.active = active
- for node in nodes:
- if node.name in selection:
- node.select = True
+ active.select = True
+
force_update(context)
+
return {'FINISHED'}
else:
return {'CANCELLED'}
@@ -4847,6 +5050,11 @@ def register():
name="Source Socket!",
default=0,
description="An internal property used to store the source socket in a Lazy Connect operation")
+ bpy.types.NodeSocketInterface.NWViewerSocket = BoolProperty(
+ name="NW Socket",
+ default=False,
+ description="An internal property used to determine if a socket is generated by the addon"
+ )
for cls in classes:
register_class(cls)
@@ -4882,6 +5090,7 @@ def unregister():
del bpy.types.Scene.NWLazySource
del bpy.types.Scene.NWLazyTarget
del bpy.types.Scene.NWSourceSocket
+ del bpy.types.NodeSocketInterface.NWViewerSocket
# keymaps
for km, kmi in addon_keymaps:
diff --git a/object_fracture_cell/__init__.py b/object_fracture_cell/__init__.py
index 02e156b4..cb8cc561 100644
--- a/object_fracture_cell/__init__.py
+++ b/object_fracture_cell/__init__.py
@@ -35,13 +35,13 @@ bl_info = {
import bpy
from bpy.props import (
- StringProperty,
- BoolProperty,
- IntProperty,
- FloatProperty,
- FloatVectorProperty,
- EnumProperty,
- )
+ StringProperty,
+ BoolProperty,
+ IntProperty,
+ FloatProperty,
+ FloatVectorProperty,
+ EnumProperty,
+)
from bpy.types import Operator
@@ -80,18 +80,22 @@ def main_object(context, obj, level, **kw):
obj.display_type = 'WIRE'
objects = fracture_cell_setup.cell_fracture_objects(context, obj, **kw_copy)
- objects = fracture_cell_setup.cell_fracture_boolean(context, obj, objects,
- use_island_split=use_island_split,
- use_interior_hide=(use_interior_vgroup or use_sharp_edges),
- use_debug_bool=use_debug_bool,
- use_debug_redraw=kw_copy["use_debug_redraw"],
- level=level,
- )
+ objects = fracture_cell_setup.cell_fracture_boolean(
+ context, obj, objects,
+ use_island_split=use_island_split,
+ use_interior_hide=(use_interior_vgroup or use_sharp_edges),
+ use_debug_bool=use_debug_bool,
+ use_debug_redraw=kw_copy["use_debug_redraw"],
+ level=level,
+ )
# must apply after boolean.
if use_recenter:
- bpy.ops.object.origin_set({"selected_editable_objects": objects},
- type='ORIGIN_GEOMETRY', center='MEDIAN')
+ bpy.ops.object.origin_set(
+ {"selected_editable_objects": objects},
+ type='ORIGIN_GEOMETRY',
+ center='MEDIAN',
+ )
#----------
# Recursion
@@ -105,9 +109,10 @@ def main_object(context, obj, level, **kw):
if recursion_chance_select == 'RANDOM':
random.shuffle(objects_recurse_input)
elif recursion_chance_select in {'SIZE_MIN', 'SIZE_MAX'}:
- objects_recurse_input.sort(key=lambda ob_pair:
- (Vector(ob_pair[1].bound_box[0]) -
- Vector(ob_pair[1].bound_box[6])).length_squared)
+ objects_recurse_input.sort(key=lambda ob_pair: (
+ Vector(ob_pair[1].bound_box[0]) -
+ Vector(ob_pair[1].bound_box[6])
+ ).length_squared)
if recursion_chance_select == 'SIZE_MAX':
objects_recurse_input.reverse()
elif recursion_chance_select in {'CURSOR_MIN', 'CURSOR_MAX'}:
@@ -142,11 +147,12 @@ def main_object(context, obj, level, **kw):
if level == 0:
# import pdb; pdb.set_trace()
if use_interior_vgroup or use_sharp_edges:
- fracture_cell_setup.cell_fracture_interior_handle(objects,
- use_interior_vgroup=use_interior_vgroup,
- use_sharp_edges=use_sharp_edges,
- use_sharp_edges_apply=use_sharp_edges_apply,
- )
+ fracture_cell_setup.cell_fracture_interior_handle(
+ objects,
+ use_interior_vgroup=use_interior_vgroup,
+ use_sharp_edges=use_sharp_edges,
+ use_sharp_edges_apply=use_sharp_edges_apply,
+ )
#--------------
# Scene Options
@@ -247,168 +253,178 @@ class FractureCell(Operator):
# -------------------------------------------------------------------------
# Source Options
source: EnumProperty(
- name="Source",
- items=(('VERT_OWN', "Own Verts", "Use own vertices"),
- ('VERT_CHILD', "Child Verts", "Use child object vertices"),
- ('PARTICLE_OWN', "Own Particles", ("All particle systems of the "
- "source object")),
- ('PARTICLE_CHILD', "Child Particles", ("All particle systems of the "
- "child objects")),
- ('PENCIL', "Annotation Pencil", "Annotation Grease Pencil."),
- ),
- options={'ENUM_FLAG'},
- default={'PARTICLE_OWN'},
- )
+ name="Source",
+ items=(
+ ('VERT_OWN', "Own Verts", "Use own vertices"),
+ ('VERT_CHILD', "Child Verts", "Use child object vertices"),
+ ('PARTICLE_OWN', "Own Particles", (
+ "All particle systems of the "
+ "source object"
+ )),
+ ('PARTICLE_CHILD', "Child Particles", (
+ "All particle systems of the "
+ "child objects"
+ )),
+ ('PENCIL', "Annotation Pencil", "Annotation Grease Pencil."),
+ ),
+ options={'ENUM_FLAG'},
+ default={'PARTICLE_OWN'},
+ )
source_limit: IntProperty(
- name="Source Limit",
- description="Limit the number of input points, 0 for unlimited",
- min=0, max=5000,
- default=100,
- )
+ name="Source Limit",
+ description="Limit the number of input points, 0 for unlimited",
+ min=0, max=5000,
+ default=100,
+ )
source_noise: FloatProperty(
- name="Noise",
- description="Randomize point distribution",
- min=0.0, max=1.0,
- default=0.0,
- )
+ name="Noise",
+ description="Randomize point distribution",
+ min=0.0, max=1.0,
+ default=0.0,
+ )
cell_scale: FloatVectorProperty(
- name="Scale",
- description="Scale Cell Shape",
- size=3,
- min=0.0, max=1.0,
- default=(1.0, 1.0, 1.0),
- )
+ name="Scale",
+ description="Scale Cell Shape",
+ size=3,
+ min=0.0, max=1.0,
+ default=(1.0, 1.0, 1.0),
+ )
# -------------------------------------------------------------------------
# Recursion
recursion: IntProperty(
- name="Recursion",
- description="Break shards recursively",
- min=0, max=5000,
- default=0,
- )
+ name="Recursion",
+ description="Break shards recursively",
+ min=0, max=5000,
+ default=0,
+ )
recursion_source_limit: IntProperty(
- name="Source Limit",
- description="Limit the number of input points, 0 for unlimited (applies to recursion only)",
- min=0, max=5000,
- default=8,
- )
+ name="Source Limit",
+ description="Limit the number of input points, 0 for unlimited (applies to recursion only)",
+ min=0, max=5000,
+ default=8,
+ )
recursion_clamp: IntProperty(
- name="Clamp Recursion",
- description="Finish recursion when this number of objects is reached (prevents recursing for extended periods of time), zero disables",
- min=0, max=10000,
- default=250,
- )
+ name="Clamp Recursion",
+ description=(
+ "Finish recursion when this number of objects is reached "
+ "(prevents recursing for extended periods of time), zero disables"
+ ),
+ min=0, max=10000,
+ default=250,
+ )
recursion_chance: FloatProperty(
- name="Random Factor",
- description="Likelihood of recursion",
- min=0.0, max=1.0,
- default=0.25,
- )
+ name="Random Factor",
+ description="Likelihood of recursion",
+ min=0.0, max=1.0,
+ default=0.25,
+ )
recursion_chance_select: EnumProperty(
- name="Recurse Over",
- items=(('RANDOM', "Random", ""),
- ('SIZE_MIN', "Small", "Recursively subdivide smaller objects"),
- ('SIZE_MAX', "Big", "Recursively subdivide bigger objects"),
- ('CURSOR_MIN', "Cursor Close", "Recursively subdivide objects closer to the cursor"),
- ('CURSOR_MAX', "Cursor Far", "Recursively subdivide objects farther from the cursor"),
- ),
- default='SIZE_MIN',
- )
+ name="Recurse Over",
+ items=(
+ ('RANDOM', "Random", ""),
+ ('SIZE_MIN', "Small", "Recursively subdivide smaller objects"),
+ ('SIZE_MAX', "Big", "Recursively subdivide bigger objects"),
+ ('CURSOR_MIN', "Cursor Close", "Recursively subdivide objects closer to the cursor"),
+ ('CURSOR_MAX', "Cursor Far", "Recursively subdivide objects farther from the cursor"),
+ ),
+ default='SIZE_MIN',
+ )
# -------------------------------------------------------------------------
# Mesh Data Options
use_smooth_faces: BoolProperty(
- name="Smooth Interior",
- description="Smooth Faces of inner side",
- default=False,
- )
+ name="Smooth Interior",
+ description="Smooth Faces of inner side",
+ default=False,
+ )
use_sharp_edges: BoolProperty(
- name="Sharp Edges",
- description="Set sharp edges when disabled",
- default=True,
- )
+ name="Sharp Edges",
+ description="Set sharp edges when disabled",
+ default=True,
+ )
use_sharp_edges_apply: BoolProperty(
- name="Apply Split Edge",
- description="Split sharp hard edges",
- default=True,
- )
+ name="Apply Split Edge",
+ description="Split sharp hard edges",
+ default=True,
+ )
use_data_match: BoolProperty(
- name="Match Data",
- description="Match original mesh materials and data layers",
- default=True,
- )
+ name="Match Data",
+ description="Match original mesh materials and data layers",
+ default=True,
+ )
use_island_split: BoolProperty(
- name="Split Islands",
- description="Split disconnected meshes",
- default=True,
- )
+ name="Split Islands",
+ description="Split disconnected meshes",
+ default=True,
+ )
margin: FloatProperty(
- name="Margin",
- description="Gaps for the fracture (gives more stable physics)",
- min=0.0, max=1.0,
- default=0.001,
- )
+ name="Margin",
+ description="Gaps for the fracture (gives more stable physics)",
+ min=0.0, max=1.0,
+ default=0.001,
+ )
material_index: IntProperty(
- name="Material",
- description="Material index for interior faces",
- default=0,
- )
+ name="Material",
+ description="Material index for interior faces",
+ default=0,
+ )
use_interior_vgroup: BoolProperty(
- name="Interior VGroup",
- description="Create a vertex group for interior verts",
- default=False,
- )
+ name="Interior VGroup",
+ description="Create a vertex group for interior verts",
+ default=False,
+ )
# -------------------------------------------------------------------------
# Physics Options
mass_mode: EnumProperty(
- name="Mass Mode",
- items=(('VOLUME', "Volume", "Objects get part of specified mass based on their volume"),
- ('UNIFORM', "Uniform", "All objects get the specified mass"),
- ),
- default='VOLUME',
- )
+ name="Mass Mode",
+ items=(
+ ('VOLUME', "Volume", "Objects get part of specified mass based on their volume"),
+ ('UNIFORM', "Uniform", "All objects get the specified mass"),
+ ),
+ default='VOLUME',
+ )
mass: FloatProperty(
- name="Mass",
- description="Mass to give created objects",
- min=0.001, max=1000.0,
- default=1.0,
- )
+ name="Mass",
+ description="Mass to give created objects",
+ min=0.001, max=1000.0,
+ default=1.0,
+ )
# -------------------------------------------------------------------------
# Object Options
use_recenter: BoolProperty(
- name="Recenter",
- description="Recalculate the center points after splitting",
- default=True,
- )
+ name="Recenter",
+ description="Recalculate the center points after splitting",
+ default=True,
+ )
use_remove_original: BoolProperty(
- name="Remove Original",
- description="Removes the parents used to create the shatter",
- default=True,
- )
+ name="Remove Original",
+ description="Removes the parents used to create the shatter",
+ default=True,
+ )
# -------------------------------------------------------------------------
# Scene Options
@@ -417,30 +433,32 @@ class FractureCell(Operator):
# are setup in the scene.
collection_name: StringProperty(
- name="Collection",
- description="Create objects in a collection "
- "(use existing or create new)",
- )
+ name="Collection",
+ description=(
+ "Create objects in a collection "
+ "(use existing or create new)"
+ ),
+ )
# -------------------------------------------------------------------------
# Debug
use_debug_points: BoolProperty(
- name="Debug Points",
- description="Create mesh data showing the points used for fracture",
- default=False,
- )
+ name="Debug Points",
+ description="Create mesh data showing the points used for fracture",
+ default=False,
+ )
use_debug_redraw: BoolProperty(
- name="Show Progress Realtime",
- description="Redraw as fracture is done",
- default=True,
- )
+ name="Show Progress Realtime",
+ description="Redraw as fracture is done",
+ default=True,
+ )
use_debug_bool: BoolProperty(
- name="Debug Boolean",
- description="Skip applying the boolean modifier",
- default=False,
- )
+ name="Debug Boolean",
+ description="Skip applying the boolean modifier",
+ default=False,
+ )
def execute(self, context):
keywords = self.as_keywords() # ignore=("blah",)
diff --git a/oscurart_tools/render/material_overrides.py b/oscurart_tools/render/material_overrides.py
index 8dbed0c1..4c3e936e 100644
--- a/oscurart_tools/render/material_overrides.py
+++ b/oscurart_tools/render/material_overrides.py
@@ -22,6 +22,13 @@ def ApplyOverrides(dummy):
if ob.type == "MESH":
if not ob.hide_viewport and not ob.hide_render:
obDict.append([ob,[mat for mat in ob.data.materials]])
+ if ob.type == "EMPTY":
+ if not ob.instance_collection == None:
+ for iob in ob.instance_collection.all_objects:
+ if iob.type == "MESH":
+ if not iob.hide_viewport and not iob.hide_render:
+ obDict.append([iob,[mat for mat in iob.data.materials]])
+
for override in bpy.context.scene.ovlist:
@@ -42,6 +49,13 @@ def ApplyOverrides(dummy):
if not ob.hide_viewport and not ob.hide_render:
for i,mat in enumerate(ob.data.materials):
ob.data.materials[i] = bpy.data.materials[matClean]
+ if ob.type == "EMPTY":
+ if not ob.instance_collection == None:
+ for iob in ob.instance_collection.all_objects:
+ if iob.type == "MESH":
+ if not iob.hide_viewport and not iob.hide_render:
+ for i,mat in enumerate(iob.data.materials):
+ iob.data.materials[i] = bpy.data.materials[matClean]
@persistent
diff --git a/presets/operator/mesh.bolt_add/default.py b/presets/operator/mesh.bolt_add/default.py
index 5c1e33dd..4bd250aa 100644
--- a/presets/operator/mesh.bolt_add/default.py
+++ b/presets/operator/mesh.bolt_add/default.py
@@ -10,8 +10,13 @@ op.bf_Shank_Dia = 3.0
op.bf_Phillips_Bit_Depth = 1.1431535482406616
op.bf_Allen_Bit_Depth = 1.5
op.bf_Allen_Bit_Flat_Distance = 2.5
+op.bf_Torx_Bit_Depth = 1.5
+op.bf_Torx_Size_Type = 'bf_Torx_T10'
op.bf_Hex_Head_Height = 2.0
op.bf_Hex_Head_Flat_Distance = 5.5
+op.bf_12_Point_Head_Height = 3.0
+op.bf_12_Point_Head_Flat_Distance = 3.0
+op.bf_12_Point_Head_Flange_Dia = 5.72
op.bf_CounterSink_Head_Dia = 6.300000190734863
op.bf_Cap_Head_Height = 3.0
op.bf_Cap_Head_Dia = 5.5
@@ -27,3 +32,6 @@ op.bf_Root_Percent = 10
op.bf_Div_Count = 36
op.bf_Hex_Nut_Height = 2.4000000953674316
op.bf_Hex_Nut_Flat_Distance = 5.5
+op.bf_12_Point_Nut_Height = 3.0
+op.bf_12_Point_Nut_Flat_Distance = 3.0
+op.bf_12_Point_Nut_Flange_Dia = 5.72
diff --git a/presets/operator/mesh.bolt_add/m10.py b/presets/operator/mesh.bolt_add/m10.py
index b92d009e..2f8b5866 100644
--- a/presets/operator/mesh.bolt_add/m10.py
+++ b/presets/operator/mesh.bolt_add/m10.py
@@ -10,8 +10,13 @@ op.bf_Shank_Dia = 10.0
op.bf_Phillips_Bit_Depth = 4.082691192626953
op.bf_Allen_Bit_Depth = 5.0
op.bf_Allen_Bit_Flat_Distance = 8.0
+op.bf_Torx_Bit_Depth = 5.0
+op.bf_Torx_Size_Type = 'bf_Torx_T50'
op.bf_Hex_Head_Height = 6.400000095367432
op.bf_Hex_Head_Flat_Distance = 17.0
+op.bf_12_Point_Head_Height = 10.0
+op.bf_12_Point_Head_Flat_Distance = 10.0
+op.bf_12_Point_Head_Flange_Dia = 16.27
op.bf_CounterSink_Head_Dia = 20.0
op.bf_Cap_Head_Height = 10.0
op.bf_Cap_Head_Dia = 16.0
@@ -27,3 +32,6 @@ op.bf_Root_Percent = 10
op.bf_Div_Count = 36
op.bf_Hex_Nut_Height = 8.0
op.bf_Hex_Nut_Flat_Distance = 17.0
+op.bf_12_Point_Nut_Height = 10.0
+op.bf_12_Point_Nut_Flat_Distance = 10.0
+op.bf_12_Point_Nut_Flange_Dia = 16.27
diff --git a/presets/operator/mesh.bolt_add/m12.py b/presets/operator/mesh.bolt_add/m12.py
index cbec7589..a5040619 100644
--- a/presets/operator/mesh.bolt_add/m12.py
+++ b/presets/operator/mesh.bolt_add/m12.py
@@ -10,8 +10,13 @@ op.bf_Shank_Dia = 12.0
op.bf_Phillips_Bit_Depth = 4.899229526519775
op.bf_Allen_Bit_Depth = 6.0
op.bf_Allen_Bit_Flat_Distance = 10.0
+op.bf_Torx_Bit_Depth = 6.0
+op.bf_Torx_Size_Type = 'bf_Torx_T55'
op.bf_Hex_Head_Height = 7.5
op.bf_Hex_Head_Flat_Distance = 19.0
+op.bf_12_Point_Head_Height = 12.0
+op.bf_12_Point_Head_Flat_Distance = 12.0
+op.bf_12_Point_Head_Flange_Dia = 18.27
op.bf_CounterSink_Head_Dia = 22.0
op.bf_Cap_Head_Height = 12.0
op.bf_Cap_Head_Dia = 18.5
@@ -27,3 +32,6 @@ op.bf_Root_Percent = 10
op.bf_Div_Count = 36
op.bf_Hex_Nut_Height = 10.0
op.bf_Hex_Nut_Flat_Distance = 19.0
+op.bf_12_Point_Nut_Height = 12.0
+op.bf_12_Point_Nut_Flat_Distance = 12.0
+op.bf_12_Point_Nut_Flange_Dia = 18.27
diff --git a/presets/operator/mesh.bolt_add/m3.py b/presets/operator/mesh.bolt_add/m3.py
index 5c1e33dd..4bd250aa 100644
--- a/presets/operator/mesh.bolt_add/m3.py
+++ b/presets/operator/mesh.bolt_add/m3.py
@@ -10,8 +10,13 @@ op.bf_Shank_Dia = 3.0
op.bf_Phillips_Bit_Depth = 1.1431535482406616
op.bf_Allen_Bit_Depth = 1.5
op.bf_Allen_Bit_Flat_Distance = 2.5
+op.bf_Torx_Bit_Depth = 1.5
+op.bf_Torx_Size_Type = 'bf_Torx_T10'
op.bf_Hex_Head_Height = 2.0
op.bf_Hex_Head_Flat_Distance = 5.5
+op.bf_12_Point_Head_Height = 3.0
+op.bf_12_Point_Head_Flat_Distance = 3.0
+op.bf_12_Point_Head_Flange_Dia = 5.72
op.bf_CounterSink_Head_Dia = 6.300000190734863
op.bf_Cap_Head_Height = 3.0
op.bf_Cap_Head_Dia = 5.5
@@ -27,3 +32,6 @@ op.bf_Root_Percent = 10
op.bf_Div_Count = 36
op.bf_Hex_Nut_Height = 2.4000000953674316
op.bf_Hex_Nut_Flat_Distance = 5.5
+op.bf_12_Point_Nut_Height = 3.0
+op.bf_12_Point_Nut_Flat_Distance = 3.0
+op.bf_12_Point_Nut_Flange_Dia = 5.72
diff --git a/presets/operator/mesh.bolt_add/m4.py b/presets/operator/mesh.bolt_add/m4.py
index a4349c5a..b5595d00 100644
--- a/presets/operator/mesh.bolt_add/m4.py
+++ b/presets/operator/mesh.bolt_add/m4.py
@@ -10,8 +10,13 @@ op.bf_Shank_Dia = 4.0
op.bf_Phillips_Bit_Depth = 1.6330764293670654
op.bf_Allen_Bit_Depth = 2.0
op.bf_Allen_Bit_Flat_Distance = 3.0
+op.bf_Torx_Bit_Depth = 2.0
+op.bf_Torx_Size_Type = 'bf_Torx_T20'
op.bf_Hex_Head_Height = 2.799999952316284
op.bf_Hex_Head_Flat_Distance = 7.0
+op.bf_12_Point_Head_Height = 4.0
+op.bf_12_Point_Head_Flat_Distance = 4.0
+op.bf_12_Point_Head_Flange_Dia = 7.22
op.bf_CounterSink_Head_Dia = 9.399999618530273
op.bf_Cap_Head_Height = 4.0
op.bf_Cap_Head_Dia = 7.0
@@ -27,3 +32,6 @@ op.bf_Root_Percent = 10
op.bf_Div_Count = 36
op.bf_Hex_Nut_Height = 3.200000047683716
op.bf_Hex_Nut_Flat_Distance = 7.0
+op.bf_12_Point_Nut_Height = 4.0
+op.bf_12_Point_Nut_Flat_Distance = 4.0
+op.bf_12_Point_Nut_Flange_Dia = 7.22
diff --git a/presets/operator/mesh.bolt_add/m5.py b/presets/operator/mesh.bolt_add/m5.py
index 7f53703c..d4485119 100644
--- a/presets/operator/mesh.bolt_add/m5.py
+++ b/presets/operator/mesh.bolt_add/m5.py
@@ -10,8 +10,13 @@ op.bf_Shank_Dia = 5.0
op.bf_Phillips_Bit_Depth = 1.9392783641815186
op.bf_Allen_Bit_Depth = 2.5
op.bf_Allen_Bit_Flat_Distance = 4.0
+op.bf_Torx_Bit_Depth = 2.5
+op.bf_Torx_Size_Type = 'bf_Torx_T25'
op.bf_Hex_Head_Height = 3.5
op.bf_Hex_Head_Flat_Distance = 8.0
+op.bf_12_Point_Head_Height = 5.0
+op.bf_12_Point_Head_Flat_Distance = 5.0
+op.bf_12_Point_Head_Flange_Dia = 8.72
op.bf_CounterSink_Head_Dia = 10.399999618530273
op.bf_Cap_Head_Height = 5.0
op.bf_Cap_Head_Dia = 8.5
@@ -27,3 +32,6 @@ op.bf_Root_Percent = 10
op.bf_Div_Count = 36
op.bf_Hex_Nut_Height = 4.0
op.bf_Hex_Nut_Flat_Distance = 8.0
+op.bf_12_Point_Nut_Height = 5.0
+op.bf_12_Point_Nut_Flat_Distance = 5.0
+op.bf_12_Point_Nut_Flange_Dia = 8.72
diff --git a/presets/operator/mesh.bolt_add/m6.py b/presets/operator/mesh.bolt_add/m6.py
index 225776be..01a8408d 100644
--- a/presets/operator/mesh.bolt_add/m6.py
+++ b/presets/operator/mesh.bolt_add/m6.py
@@ -10,8 +10,13 @@ op.bf_Shank_Dia = 6.0
op.bf_Phillips_Bit_Depth = 2.4496147632598877
op.bf_Allen_Bit_Depth = 3.0
op.bf_Allen_Bit_Flat_Distance = 5.0
+op.bf_Torx_Bit_Depth = 3.0
+op.bf_Torx_Size_Type = 'bf_Torx_T30'
op.bf_Hex_Head_Height = 4.0
op.bf_Hex_Head_Flat_Distance = 10.0
+op.bf_12_Point_Head_Height = 6.0
+op.bf_12_Point_Head_Flat_Distance = 6.0
+op.bf_12_Point_Head_Flange_Dia = 10.22
op.bf_CounterSink_Head_Dia = 12.600000381469727
op.bf_Cap_Head_Height = 6.0
op.bf_Cap_Head_Dia = 10.0
@@ -27,3 +32,6 @@ op.bf_Root_Percent = 10
op.bf_Div_Count = 36
op.bf_Hex_Nut_Height = 5.0
op.bf_Hex_Nut_Flat_Distance = 10.0
+op.bf_12_Point_Nut_Height = 6.0
+op.bf_12_Point_Nut_Flat_Distance = 6.0
+op.bf_12_Point_Nut_Flange_Dia = 10.22
diff --git a/presets/operator/mesh.bolt_add/m8.py b/presets/operator/mesh.bolt_add/m8.py
index 547cc719..a7493131 100644
--- a/presets/operator/mesh.bolt_add/m8.py
+++ b/presets/operator/mesh.bolt_add/m8.py
@@ -10,8 +10,13 @@ op.bf_Shank_Dia = 8.0
op.bf_Phillips_Bit_Depth = 3.266152858734131
op.bf_Allen_Bit_Depth = 4.0
op.bf_Allen_Bit_Flat_Distance = 6.0
+op.bf_Torx_Bit_Depth = 4.0
+op.bf_Torx_Size_Type = 'bf_Torx_T40'
op.bf_Hex_Head_Height = 5.300000190734863
op.bf_Hex_Head_Flat_Distance = 13.0
+op.bf_12_Point_Head_Height = 8.0
+op.bf_12_Point_Head_Flat_Distance = 8.0
+op.bf_12_Point_Head_Flange_Dia = 13.27
op.bf_CounterSink_Head_Dia = 17.299999237060547
op.bf_Cap_Head_Height = 8.0
op.bf_Cap_Head_Dia = 13.5
@@ -27,3 +32,6 @@ op.bf_Root_Percent = 10
op.bf_Div_Count = 36
op.bf_Hex_Nut_Height = 6.5
op.bf_Hex_Nut_Flat_Distance = 13.0
+op.bf_12_Point_Nut_Height = 8.0
+op.bf_12_Point_Nut_Flat_Distance = 8.0
+op.bf_12_Point_Nut_Flange_Dia = 13.27
diff --git a/presets/pov/light/01_(5400K)_Direct_Sun.py b/presets/pov/light/01_(4800K)_Direct_Sun.py
index 6d281837..6d281837 100644
--- a/presets/pov/light/01_(5400K)_Direct_Sun.py
+++ b/presets/pov/light/01_(4800K)_Direct_Sun.py
diff --git a/rigify/rigs/chain_rigs.py b/rigify/rigs/chain_rigs.py
index fc070eb1..525626f0 100644
--- a/rigify/rigs/chain_rigs.py
+++ b/rigify/rigs/chain_rigs.py
@@ -36,9 +36,11 @@ class SimpleChainRig(BaseRig):
def find_org_bones(self, bone):
return [bone.name] + connected_children_names(self.obj, bone.name)
+ min_chain_length = 2
+
def initialize(self):
- if len(self.bones.org) <= 1:
- self.raise_error("Input to rig type must be a chain of 2 or more bones.")
+ if len(self.bones.org) < self.min_chain_length:
+ self.raise_error("Input to rig type must be a chain of {} or more bones.", self.min_chain_length)
def parent_bones(self):
self.rig_parent_bone = self.get_bone_parent(self.bones.org[0])
diff --git a/rigify/rigs/spines/spine_rigs.py b/rigify/rigs/spines/spine_rigs.py
index 070a6bd3..d23676d5 100644
--- a/rigify/rigs/spines/spine_rigs.py
+++ b/rigify/rigs/spines/spine_rigs.py
@@ -40,10 +40,10 @@ class BaseSpineRig(TweakChainRig):
"""
bbone_segments = 8
+ min_chain_length = 3
def initialize(self):
- if len(self.bones.org) < 3:
- self.raise_error("Input to rig type must be a chain of 3 or more bones.")
+ super().initialize()
self.use_torso_pivot = self.params.make_custom_pivot
self.length = sum([self.get_bone(b).length for b in self.bones.org])
diff --git a/rigify/rigs/spines/super_head.py b/rigify/rigs/spines/super_head.py
index 15f011f7..b1ba9ee0 100644
--- a/rigify/rigs/spines/super_head.py
+++ b/rigify/rigs/spines/super_head.py
@@ -40,11 +40,13 @@ class Rig(BaseHeadTailRig):
"""
use_connect_reverse = False
+ min_chain_length = 1
def initialize(self):
super().initialize()
self.long_neck = len(self.bones.org) > 3
+ self.has_neck = len(self.bones.org) > 1
####################################################
# BONES
@@ -78,8 +80,11 @@ class Rig(BaseHeadTailRig):
orgs = self.bones.org
ctrl = self.bones.ctrl
- ctrl.neck = self.make_neck_control_bone(orgs[0], 'neck', orgs[-1])
+ if self.has_neck:
+ ctrl.neck = self.make_neck_control_bone(orgs[0], 'neck', orgs[-1])
+
ctrl.head = self.make_head_control_bone(orgs[-1], 'head')
+
if self.long_neck:
ctrl.neck_bend = self.make_neck_bend_control_bone(orgs[0], 'neck_bend', ctrl.neck)
@@ -118,14 +123,16 @@ class Rig(BaseHeadTailRig):
def parent_control_chain(self):
ctrl = self.bones.ctrl
mch = self.bones.mch
- self.set_bone_parent(ctrl.neck, mch.rot_neck)
+ if self.has_neck:
+ self.set_bone_parent(ctrl.neck, mch.rot_neck)
self.set_bone_parent(ctrl.head, mch.rot_head)
if self.long_neck:
self.set_bone_parent(ctrl.neck_bend, mch.stretch)
@stage.configure_bones
def configure_control_chain(self):
- self.configure_control_bone(0, self.bones.ctrl.neck, self.bones.org[0])
+ if self.has_neck:
+ self.configure_control_bone(0, self.bones.ctrl.neck, self.bones.org[0])
self.configure_control_bone(2, self.bones.ctrl.head, self.bones.org[-1])
if self.long_neck:
self.configure_control_bone(1, self.bones.ctrl.neck_bend, self.bones.org[0])
@@ -133,7 +140,8 @@ class Rig(BaseHeadTailRig):
@stage.generate_widgets
def make_control_widgets(self):
ctrl = self.bones.ctrl
- self.make_neck_widget(ctrl.neck)
+ if self.has_neck:
+ self.make_neck_widget(ctrl.neck)
self.make_head_widget(ctrl.head)
if self.long_neck:
self.make_neck_bend_widget(ctrl.neck_bend)
@@ -178,9 +186,10 @@ class Rig(BaseHeadTailRig):
orgs = self.bones.org
mch = self.bones.mch
- mch.rot_neck = self.make_mch_follow_bone(orgs[0], 'neck', 0.5, copy_scale=True)
+ if self.has_neck:
+ mch.rot_neck = self.make_mch_follow_bone(orgs[0], 'neck', 0.5, copy_scale=True)
+ mch.stretch = self.make_mch_stretch_bone(orgs[0], 'STR-neck', orgs[-1])
mch.rot_head = self.make_mch_follow_bone(orgs[-1], 'head', 0.0, copy_scale=True)
- mch.stretch = self.make_mch_stretch_bone(orgs[0], 'STR-neck', orgs[-1])
def make_mch_stretch_bone(self, org, name, org_head):
name = self.copy_bone(org, make_derived_name(name, 'mch'), parent=False)
@@ -189,13 +198,17 @@ class Rig(BaseHeadTailRig):
@stage.parent_bones
def parent_mch_control_bones(self):
- self.set_bone_parent(self.bones.mch.rot_neck, self.rig_parent_bone)
- self.set_bone_parent(self.bones.mch.rot_head, self.bones.ctrl.neck)
- self.set_bone_parent(self.bones.mch.stretch, self.bones.ctrl.neck)
+ if self.has_neck:
+ self.set_bone_parent(self.bones.mch.rot_neck, self.rig_parent_bone)
+ self.set_bone_parent(self.bones.mch.rot_head, self.bones.ctrl.neck)
+ self.set_bone_parent(self.bones.mch.stretch, self.bones.ctrl.neck)
+ else:
+ self.set_bone_parent(self.bones.mch.rot_head, self.rig_parent_bone)
@stage.rig_bones
def rig_mch_control_bones(self):
- self.rig_mch_stretch_bone(self.bones.mch.stretch, self.bones.ctrl.head)
+ if self.has_neck:
+ self.rig_mch_stretch_bone(self.bones.mch.stretch, self.bones.ctrl.head)
def rig_mch_stretch_bone(self, mch, head):
self.make_constraint(mch, 'DAMPED_TRACK', head)
@@ -299,14 +312,19 @@ class Rig(BaseHeadTailRig):
def make_tweak_chain(self):
orgs = self.bones.org
self.bones.ctrl.tweak = map_list(self.make_tweak_bone, count(0), orgs[0:-1])
+ if not self.has_neck:
+ self.check_connect_tweak(orgs[0])
@stage.parent_bones
def parent_tweak_chain(self):
ctrl = self.bones.ctrl
mch = self.bones.mch
- for args in zip(ctrl.tweak, [ctrl.neck, *mch.chain]):
- self.set_bone_parent(*args)
+ if self.has_neck:
+ for args in zip(ctrl.tweak, [ctrl.neck, *mch.chain]):
+ self.set_bone_parent(*args)
+ elif self.connected_tweak:
+ self.set_bone_parent(self.connected_tweak, ctrl.head)
@stage.rig_bones
def generate_neck_tweak_widget(self):
@@ -333,7 +351,11 @@ class Rig(BaseHeadTailRig):
@stage.rig_bones
def rig_org_chain(self):
- tweaks = self.bones.ctrl.tweak + [self.bones.ctrl.head]
+ if self.has_neck:
+ tweaks = self.bones.ctrl.tweak + [self.bones.ctrl.head]
+ else:
+ tweaks = [self.connected_tweak or self.bones.ctrl.head]
+
for args in zip(count(0), self.bones.org, tweaks, tweaks[1:] + [None]):
self.rig_org_bone(*args)
diff --git a/space_view3d_pie_menus/pie_proportional_menu.py b/space_view3d_pie_menus/pie_proportional_menu.py
index 10575a55..009bf8a8 100644
--- a/space_view3d_pie_menus/pie_proportional_menu.py
+++ b/space_view3d_pie_menus/pie_proportional_menu.py
@@ -19,7 +19,7 @@
# <pep8 compliant>
bl_info = {
- "name": "Hotkey: 'O'",
+ "name": "Hotkey: 'Shift O'",
"description": "Proportional Object/Edit Tools",
"author": "pitiwazou, meta-androcto",
"version": (0, 1, 1),
diff --git a/ui_translate/__init__.py b/ui_translate/__init__.py
index 72f63a92..2cbf6cb0 100644
--- a/ui_translate/__init__.py
+++ b/ui_translate/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Manage UI translations",
"author": "Bastien Montagne",
- "version": (1, 2, 0),
+ "version": (1, 3, 0),
"blender": (2, 80, 0),
"location": "Main \"File\" menu, text editor, any UI control",
"description": "Allows managing UI translations directly from Blender "
diff --git a/ui_translate/update_svn.py b/ui_translate/update_svn.py
index a3228bac..70b7f0b5 100644
--- a/ui_translate/update_svn.py
+++ b/ui_translate/update_svn.py
@@ -34,6 +34,7 @@ else:
from bl_i18n_utils import utils as utils_i18n
from bl_i18n_utils import utils_languages_menu
+import concurrent.futures
import io
import os
import shutil
@@ -43,6 +44,18 @@ import tempfile
# Operators ###################################################################
+def i18n_updatetranslation_svn_branches_callback(pot, lng, settings):
+ if not lng['use']:
+ return
+ if os.path.isfile(lng['po_path']):
+ po = utils_i18n.I18nMessages(uid=lng['uid'], kind='PO', src=lng['po_path'], settings=settings)
+ po.update(pot)
+ else:
+ po = pot
+ po.write(kind="PO", dest=lng['po_path'])
+ print("{} PO written!".format(lng['uid']))
+
+
class UI_OT_i18n_updatetranslation_svn_branches(Operator):
"""Update i18n svn's branches (po files)"""
bl_idname = "ui.i18n_updatetranslation_svn_branches"
@@ -88,18 +101,15 @@ class UI_OT_i18n_updatetranslation_svn_branches(Operator):
return {'CANCELLED'}
# Now we should have a valid POT file, we have to merge it in all languages po's...
- pot = utils_i18n.I18nMessages(kind='PO', src=self.settings.FILE_NAME_POT, settings=self.settings)
- for progress, lng in enumerate(i18n_sett.langs):
- context.window_manager.progress_update(progress + 2)
- if not lng.use:
- continue
- if os.path.isfile(lng.po_path):
- po = utils_i18n.I18nMessages(uid=lng.uid, kind='PO', src=lng.po_path, settings=self.settings)
- po.update(pot)
- else:
- po = pot
- po.write(kind="PO", dest=lng.po_path)
- print("{} PO written!".format(lng.uid))
+ with concurrent.futures.ProcessPoolExecutor() as exctr:
+ pot = utils_i18n.I18nMessages(kind='PO', src=self.settings.FILE_NAME_POT, settings=self.settings)
+ num_langs = len(i18n_sett.langs)
+ for progress, _ in enumerate(exctr.map(i18n_updatetranslation_svn_branches_callback,
+ (pot,) * num_langs,
+ [dict(lng.items()) for lng in i18n_sett.langs],
+ (self.settings,) * num_langs,
+ chunksize=4)):
+ context.window_manager.progress_update(progress + 2)
context.window_manager.progress_end()
return {'FINISHED'}
@@ -108,6 +118,18 @@ class UI_OT_i18n_updatetranslation_svn_branches(Operator):
return wm.invoke_props_dialog(self)
+def i18n_cleanuptranslation_svn_branches_callback(lng, settings):
+ if not lng['use']:
+ print("Skipping {} language ({}).".format(lng['name'], lng['uid']))
+ return
+ po = utils_i18n.I18nMessages(uid=lng['uid'], kind='PO', src=lng['po_path'], settings=settings)
+ errs = po.check(fix=True)
+ po.write(kind="PO", dest=lng['po_path'])
+ print("Processing {} language ({}).\n"
+ "Cleaned up {} commented messages.\n".format(lng['name'], lng['uid'], po.clean_commented()) +
+ ("Errors in this po, solved as best as possible!\n\t" + "\n\t".join(errs) if errs else "") + "\n")
+
+
class UI_OT_i18n_cleanuptranslation_svn_branches(Operator):
"""Clean up i18n svn's branches (po files)"""
bl_idname = "ui.i18n_cleanuptranslation_svn_branches"
@@ -122,26 +144,41 @@ class UI_OT_i18n_cleanuptranslation_svn_branches(Operator):
context.window_manager.progress_begin(0, len(i18n_sett.langs) + 1)
context.window_manager.progress_update(0)
- for progress, lng in enumerate(i18n_sett.langs):
- context.window_manager.progress_update(progress + 1)
- if not lng.use:
- print("Skipping {} language ({}).".format(lng.name, lng.uid))
- continue
- print("Processing {} language ({}).".format(lng.name, lng.uid))
- po = utils_i18n.I18nMessages(uid=lng.uid, kind='PO', src=lng.po_path, settings=self.settings)
- print("Cleaned up {} commented messages.".format(po.clean_commented()))
- errs = po.check(fix=True)
- if errs:
- print("Errors in this po, solved as best as possible!")
- print("\t" + "\n\t".join(errs))
- po.write(kind="PO", dest=lng.po_path)
- print("\n")
+ with concurrent.futures.ProcessPoolExecutor() as exctr:
+ num_langs = len(i18n_sett.langs)
+ for progress, _ in enumerate(exctr.map(i18n_cleanuptranslation_svn_branches_callback,
+ [dict(lng.items()) for lng in i18n_sett.langs],
+ (self.settings,) * num_langs,
+ chunksize=4)):
+ context.window_manager.progress_update(progress + 1)
context.window_manager.progress_end()
return {'FINISHED'}
+def i18n_updatetranslation_svn_trunk_callback(lng, settings):
+ if lng['uid'] in settings.IMPORT_LANGUAGES_SKIP:
+ print("Skipping {} language ({}), edit settings if you want to enable it.\n".format(lng['name'], lng['uid']))
+ return lng['uid'], 0.0
+ if not lng['use']:
+ print("Skipping {} language ({}).\n".format(lng['name'], lng['uid']))
+ return lng['uid'], 0.0
+ po = utils_i18n.I18nMessages(uid=lng['uid'], kind='PO', src=lng['po_path'], settings=settings)
+ errs = po.check(fix=True)
+ print("Processing {} language ({}).\n"
+ "Cleaned up {} commented messages.\n".format(lng['name'], lng['uid'], po.clean_commented()) +
+ ("Errors in this po, solved as best as possible!\n\t" + "\n\t".join(errs) if errs else "") + "\n")
+ if lng['uid'] in settings.IMPORT_LANGUAGES_RTL:
+ po.write(kind="PO", dest=lng['po_path_trunk'][:-3] + "_raw.po")
+ po.rtl_process()
+ po.write(kind="PO", dest=lng['po_path_trunk'])
+ po.write(kind="PO_COMPACT", dest=lng['po_path_git'])
+ po.write(kind="MO", dest=lng['mo_path_trunk'])
+ po.update_info()
+ return lng['uid'], po.nbr_trans_msgs / po.nbr_msgs
+
+
class UI_OT_i18n_updatetranslation_svn_trunk(Operator):
"""Update i18n svn's branches (po files)"""
bl_idname = "ui.i18n_updatetranslation_svn_trunk"
@@ -156,30 +193,14 @@ class UI_OT_i18n_updatetranslation_svn_trunk(Operator):
context.window_manager.progress_begin(0, len(i18n_sett.langs) + 1)
context.window_manager.progress_update(0)
- for progress, lng in enumerate(i18n_sett.langs):
- context.window_manager.progress_update(progress + 1)
- if lng.uid in self.settings.IMPORT_LANGUAGES_SKIP:
- print("Skipping {} language ({}), edit settings if you want to enable it.".format(lng.name, lng.uid))
- continue
- if not lng.use:
- print("Skipping {} language ({}).".format(lng.name, lng.uid))
- continue
- print("Processing {} language ({}).".format(lng.name, lng.uid))
- po = utils_i18n.I18nMessages(uid=lng.uid, kind='PO', src=lng.po_path, settings=self.settings)
- print("Cleaned up {} commented messages.".format(po.clean_commented()))
- errs = po.check(fix=True)
- if errs:
- print("Errors in this po, solved as best as possible!")
- print("\t" + "\n\t".join(errs))
- if lng.uid in self.settings.IMPORT_LANGUAGES_RTL:
- po.write(kind="PO", dest=lng.po_path_trunk[:-3] + "_raw.po")
- po.rtl_process()
- po.write(kind="PO", dest=lng.po_path_trunk)
- po.write(kind="PO_COMPACT", dest=lng.po_path_git)
- po.write(kind="MO", dest=lng.mo_path_trunk)
- po.update_info()
- stats[lng.uid] = po.nbr_trans_msgs / po.nbr_msgs
- print("\n")
+ with concurrent.futures.ProcessPoolExecutor() as exctr:
+ num_langs = len(i18n_sett.langs)
+ for progress, (lng_uid, stats_val) in enumerate(exctr.map(i18n_updatetranslation_svn_trunk_callback,
+ [dict(lng.items()) for lng in i18n_sett.langs],
+ (self.settings,) * num_langs,
+ chunksize=4)):
+ context.window_manager.progress_update(progress + 1)
+ stats[lng_uid] = stats_val
# Copy pot file from branches to trunk.
shutil.copy2(self.settings.FILE_NAME_POT, self.settings.TRUNK_PO_DIR)
diff --git a/viewport_vr_preview.py b/viewport_vr_preview.py
index 1f8bbb64..ac191b56 100644
--- a/viewport_vr_preview.py
+++ b/viewport_vr_preview.py
@@ -33,7 +33,7 @@ from bpy.app.handlers import persistent
bl_info = {
"name": "VR Scene Inspection",
"author": "Julian Eisel (Severin)",
- "version": (0, 1, 0),
+ "version": (0, 2, 0),
"blender": (2, 83, 8),
"location": "3D View > Sidebar > VR",
"description": ("View the viewport with virtual reality glasses "
@@ -136,11 +136,16 @@ def xr_landmark_camera_object_poll(self, object):
def xr_landmark_active_update(self, context):
+ wm = context.window_manager
+
xr_landmark_active_type_update(self, context)
xr_landmark_active_camera_update(self, context)
xr_landmark_active_base_pose_location_update(self, context)
xr_landmark_active_base_pose_angle_update(self, context)
+ if wm.xr_session_state:
+ wm.xr_session_state.reset_to_base_pose(context)
+
class VRLandmark(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(
@@ -214,7 +219,9 @@ class VIEW3D_UL_vr_landmarks(bpy.types.UIList):
layout.prop(landmark, "name", text="")
- icon = 'SOLO_ON' if (index == landmark_active_idx) else 'SOLO_OFF'
+ icon = (
+ 'RADIOBUT_ON' if (index == landmark_active_idx) else 'RADIOBUT_OFF'
+ )
props = layout.operator(
"view3d.vr_landmark_activate", text="", icon=icon)
props.index = index
@@ -269,10 +276,9 @@ class VIEW3D_PT_vr_session_view(bpy.types.Panel):
layout.use_property_split = True
layout.use_property_decorate = False # No animation.
- layout.prop(session_settings, "show_floor", text="Floor")
- layout.prop(session_settings, "show_annotation", text="Annotations")
-
- layout.separator()
+ col = layout.column(align=True, heading="Show")
+ col.prop(session_settings, "show_floor", text="Floor")
+ col.prop(session_settings, "show_annotation", text="Annotations")
col = layout.column(align=True)
col.prop(session_settings, "clip_start", text="Clip Start")
@@ -289,8 +295,7 @@ class VIEW3D_PT_vr_session(bpy.types.Panel):
layout = self.layout
session_settings = context.window_manager.xr_session_settings
- layout.use_property_split = True
- layout.use_property_decorate = False # No animation.
+ layout.use_property_split = False
is_session_running = bpy.types.XrSessionState.is_running(context)
@@ -381,6 +386,13 @@ class VIEW3D_PT_vr_viewport_feedback(bpy.types.Panel):
layout = self.layout
view3d = context.space_data
+ col = layout.column(align=True)
+ col.label(icon='ERROR', text="Note:")
+ col.label(text="Settings here may have a significant")
+ col.label(text="performance impact!")
+
+ layout.separator()
+
layout.prop(view3d.shading, "vr_show_virtual_camera")
layout.prop(view3d, "mirror_xr_session")