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:
authorCampbell Barton <ideasman42@gmail.com>2020-03-05 04:32:28 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-03-05 04:32:28 +0300
commitaec5a36c12a3ec1d068adb8270017e509087dff6 (patch)
treedcc0408cf538f1fb39a41dd84c775342863b8a32 /object_carver/carver_draw.py
parent353492b181e08663b8cd3bc5733920b6fcdbcbe4 (diff)
Cleanup: tabs -> spaces
Diffstat (limited to 'object_carver/carver_draw.py')
-rw-r--r--object_carver/carver_draw.py940
1 files changed, 470 insertions, 470 deletions
diff --git a/object_carver/carver_draw.py b/object_carver/carver_draw.py
index 922807ee..f2a3aadc 100644
--- a/object_carver/carver_draw.py
+++ b/object_carver/carver_draw.py
@@ -6,494 +6,494 @@ import numpy as np
import gpu
from gpu_extras.batch import batch_for_shader
from math import(
- cos,
- sin,
- ceil,
- floor,
- )
+ cos,
+ sin,
+ ceil,
+ floor,
+ )
from bpy_extras.view3d_utils import (
- region_2d_to_location_3d,
- location_3d_to_region_2d,
+ region_2d_to_location_3d,
+ location_3d_to_region_2d,
)
from .carver_utils import (
- draw_circle,
- draw_shader,
- objDiagonal,
- mini_grid,
- )
+ draw_circle,
+ draw_shader,
+ objDiagonal,
+ mini_grid,
+ )
from mathutils import (
- Color,
- Euler,
- Vector,
- Quaternion,
+ Color,
+ Euler,
+ Vector,
+ Quaternion,
)
def get_text_info(self, context, help_txt):
- """ Return the dimensions of each part of the text """
+ """ Return the dimensions of each part of the text """
- #Extract the longest first option in sublist
- max_option = max(list(blf.dimensions(0, row[0])[0] for row in help_txt))
+ #Extract the longest first option in sublist
+ max_option = max(list(blf.dimensions(0, row[0])[0] for row in help_txt))
- #Extract the longest key in sublist
- max_key = max(list(blf.dimensions(0, row[1])[0] for row in help_txt))
+ #Extract the longest key in sublist
+ max_key = max(list(blf.dimensions(0, row[1])[0] for row in help_txt))
- #Space between option and key with a comma separator (" : ")
- comma = blf.dimensions(0, "_:_")[0]
+ #Space between option and key with a comma separator (" : ")
+ comma = blf.dimensions(0, "_:_")[0]
- #Get a default height for all the letters
- line_height = (blf.dimensions(0, "gM")[1] * 1.45)
+ #Get a default height for all the letters
+ line_height = (blf.dimensions(0, "gM")[1] * 1.45)
- #Get the total height of the text
- bloc_height = 0
- for row in help_txt:
- bloc_height += line_height
+ #Get the total height of the text
+ bloc_height = 0
+ for row in help_txt:
+ bloc_height += line_height
- return(help_txt, bloc_height, max_option, max_key, comma)
+ return(help_txt, bloc_height, max_option, max_key, comma)
def draw_string(self, color1, color2, left, bottom, text, max_option, divide = 1):
- """ Draw the text like 'option : key' or just 'option' """
-
- font_id = 0
- ui_scale = bpy.context.preferences.system.ui_scale
-
- blf.enable(font_id,blf.SHADOW)
- blf.shadow(font_id, 0, 0.0, 0.0, 0.0, 1.0)
- blf.shadow_offset(font_id,2,-2)
- line_height = (blf.dimensions(font_id, "gM")[1] * 1.45)
- y_offset = 5
-
- # Test if the text is a list formatted like : ('option', 'key')
- if isinstance(text,list):
- spacer_text = " : "
- spacer_width = blf.dimensions(font_id, spacer_text)[0]
- for string in text:
- blf.position(font_id, (left), (bottom + y_offset), 0)
- blf.color(font_id, *color1)
- blf.draw(font_id, string[0])
- blf.position(font_id, (left + max_option), (bottom + y_offset), 0)
- blf.draw(font_id, spacer_text)
- blf.color(font_id, *color2)
- blf.position(font_id, (left + max_option + spacer_width), (bottom + y_offset), 0)
- blf.draw(font_id, string[1])
- y_offset += line_height
- else:
- # The text is formatted like : ('option')
- blf.position(font_id, left, (bottom + y_offset), 0)
- blf.color(font_id, *color1)
- blf.draw(font_id, text)
- y_offset += line_height
-
- blf.disable(font_id,blf.SHADOW)
+ """ Draw the text like 'option : key' or just 'option' """
+
+ font_id = 0
+ ui_scale = bpy.context.preferences.system.ui_scale
+
+ blf.enable(font_id,blf.SHADOW)
+ blf.shadow(font_id, 0, 0.0, 0.0, 0.0, 1.0)
+ blf.shadow_offset(font_id,2,-2)
+ line_height = (blf.dimensions(font_id, "gM")[1] * 1.45)
+ y_offset = 5
+
+ # Test if the text is a list formatted like : ('option', 'key')
+ if isinstance(text,list):
+ spacer_text = " : "
+ spacer_width = blf.dimensions(font_id, spacer_text)[0]
+ for string in text:
+ blf.position(font_id, (left), (bottom + y_offset), 0)
+ blf.color(font_id, *color1)
+ blf.draw(font_id, string[0])
+ blf.position(font_id, (left + max_option), (bottom + y_offset), 0)
+ blf.draw(font_id, spacer_text)
+ blf.color(font_id, *color2)
+ blf.position(font_id, (left + max_option + spacer_width), (bottom + y_offset), 0)
+ blf.draw(font_id, string[1])
+ y_offset += line_height
+ else:
+ # The text is formatted like : ('option')
+ blf.position(font_id, left, (bottom + y_offset), 0)
+ blf.color(font_id, *color1)
+ blf.draw(font_id, text)
+ y_offset += line_height
+
+ blf.disable(font_id,blf.SHADOW)
# Opengl draw on screen
def draw_callback_px(self, context):
- font_id = 0
- region = context.region
- UIColor = (0.992, 0.5518, 0.0, 1.0)
-
- # Cut Type
- RECTANGLE = 0
- LINE = 1
- CIRCLE = 2
- self.carver_prefs = context.preferences.addons[__package__].preferences
-
- # Color
- color1 = (1.0, 1.0, 1.0, 1.0)
- color2 = UIColor
-
- #The mouse is outside the active region
- if not self.in_view_3d:
- color1 = color2 = (1.0, 0.2, 0.1, 1.0)
-
- # Primitives type
- PrimitiveType = "Rectangle"
- if self.CutType == CIRCLE:
- PrimitiveType = "Circle"
- if self.CutType == LINE:
- PrimitiveType = "Line"
-
- # Width screen
- overlap = context.preferences.system.use_region_overlap
-
- t_panel_width = 0
- if overlap:
- for region in context.area.regions:
- if region.type == 'TOOLS':
- t_panel_width = region.width
-
- # Initial position
- region_width = int(region.width / 2.0)
- y_txt = 10
-
-
- # Draw the center command from bottom to top
-
- # Get the size of the text
- text_size = 18 if region.width >= 850 else 12
- ui_scale = bpy.context.preferences.system.ui_scale
- blf.size(0, round(text_size * ui_scale), 72)
-
- # Help Display
- if (self.ObjectMode is False) and (self.ProfileMode is False):
-
- # Depth Cursor
- TypeStr = "Cursor Depth [" + self.carver_prefs.Key_Depth + "]"
- BoolStr = "(ON)" if self.snapCursor else "(OFF)"
- help_txt = [[TypeStr, BoolStr]]
-
- # Close poygonal shape
- if self.CreateMode and self.CutType == LINE:
- TypeStr = "Close [" + self.carver_prefs.Key_Close + "]"
- BoolStr = "(ON)" if self.Closed else "(OFF)"
- help_txt += [[TypeStr, BoolStr]]
-
- if self.CreateMode is False:
- # Apply Booleans
- TypeStr = "Apply Operations [" + self.carver_prefs.Key_Apply + "]"
- BoolStr = "(OFF)" if self.dont_apply_boolean else "(ON)"
- help_txt += [[TypeStr, BoolStr]]
-
- #Auto update for bevel
- TypeStr = "Bevel Update [" + self.carver_prefs.Key_Update + "]"
- BoolStr = "(ON)" if self.Auto_BevelUpdate else "(OFF)"
- help_txt += [[TypeStr, BoolStr]]
-
- # Circle subdivisions
- if self.CutType == CIRCLE:
- TypeStr = "Subdivisions [" + self.carver_prefs.Key_Subrem + "][" + self.carver_prefs.Key_Subadd + "]"
- BoolStr = str((int(360 / self.stepAngle[self.step])))
- help_txt += [[TypeStr, BoolStr]]
-
- if self.CreateMode:
- help_txt += [["Type [Space]", PrimitiveType]]
- else:
- help_txt += [["Cut Type [Space]", PrimitiveType]]
-
- else:
- # Instantiate
- TypeStr = "Instantiate [" + self.carver_prefs.Key_Instant + "]"
- BoolStr = "(ON)" if self.Instantiate else "(OFF)"
- help_txt = [[TypeStr, BoolStr]]
-
- # Random rotation
- if self.alt:
- TypeStr = "Random Rotation [" + self.carver_prefs.Key_Randrot + "]"
- BoolStr = "(ON)" if self.RandomRotation else "(OFF)"
- help_txt += [[TypeStr, BoolStr]]
-
- # Thickness
- if self.BrushSolidify:
- TypeStr = "Thickness [" + self.carver_prefs.Key_Depth + "]"
- if self.ProfileMode:
- BoolStr = str(round(self.ProfileBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
- if self.ObjectMode:
- BoolStr = str(round(self.ObjectBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
- help_txt += [[TypeStr, BoolStr]]
-
- # Brush depth
- if (self.ObjectMode):
- TypeStr = "Carve Depth [" + self.carver_prefs.Key_Depth + "]"
- BoolStr = str(round(self.ObjectBrush.data.vertices[0].co.z, 2))
- help_txt += [[TypeStr, BoolStr]]
-
- TypeStr = "Brush Depth [" + self.carver_prefs.Key_BrushDepth + "]"
- BoolStr = str(round(self.BrushDepthOffset, 2))
- help_txt += [[TypeStr, BoolStr]]
-
- help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
- xCmd = region_width - (max_option + max_key + comma) / 2
- draw_string(self, color1, color2, xCmd, y_txt, help_txt, max_option, divide = 2)
-
-
- # Separator (Line)
- LineWidth = (max_option + max_key + comma) / 2
- if region.width >= 850:
- LineWidth = 140
-
- LineWidth = (max_option + max_key + comma)
- coords = [(int(region_width - LineWidth/2), y_txt + bloc_height + 8), \
- (int(region_width + LineWidth/2), y_txt + bloc_height + 8)]
- draw_shader(self, UIColor, 1, 'LINES', coords, self.carver_prefs.LineWidth)
-
- # Command Display
- if self.CreateMode and ((self.ObjectMode is False) and (self.ProfileMode is False)):
- BooleanMode = "Create"
- else:
- if self.ObjectMode or self.ProfileMode:
- BooleanType = "Difference) [T]" if self.BoolOps == self.difference else "Union) [T]"
- BooleanMode = \
- "Object Brush (" + BooleanType if self.ObjectMode else "Profil Brush (" + BooleanType
- else:
- BooleanMode = \
- "Difference" if (self.shift is False) and (self.ForceRebool is False) else "Rebool"
-
- # Display boolean mode
- text_size = 40 if region.width >= 850 else 20
- blf.size(0, round(text_size * ui_scale), 72)
-
- draw_string(self, color2, color2, region_width - (blf.dimensions(0, BooleanMode)[0]) / 2, \
- y_txt + bloc_height + 16, BooleanMode, 0, divide = 2)
-
- if region.width >= 850:
-
- if self.AskHelp is False:
- # "H for Help" text
- blf.size(0, round(13 * ui_scale), 72)
- help_txt = "[" + self.carver_prefs.Key_Help + "] for help"
- txt_width = blf.dimensions(0, help_txt)[0]
- txt_height = (blf.dimensions(0, "gM")[1] * 1.45)
-
- # Draw a rectangle and put the text "H for Help"
- xrect = 40
- yrect = 40
- rect_vertices = [(xrect - 5, yrect - 5), (xrect + txt_width + 5, yrect - 5), \
- (xrect + txt_width + 5, yrect + txt_height + 5), (xrect - 5, yrect + txt_height + 5)]
- draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', rect_vertices, self.carver_prefs.LineWidth)
- draw_string(self, color1, color2, xrect, yrect, help_txt, 0)
-
- else:
- #Draw the help text
- xHelp = 30 + t_panel_width
- yHelp = 10
-
- if self.ObjectMode or self.ProfileMode:
- if self.ProfileMode:
- help_txt = [["Object Mode", self.carver_prefs.Key_Brush]]
- else:
- help_txt = [["Cut Mode", self.carver_prefs.Key_Brush]]
-
- else:
- help_txt =[
- ["Profil Brush", self.carver_prefs.Key_Brush],\
- ["Move Cursor", "Ctrl + LMB"]
- ]
-
- if (self.ObjectMode is False) and (self.ProfileMode is False):
- if self.CreateMode is False:
- help_txt +=[
- ["Create geometry", self.carver_prefs.Key_Create],\
- ]
- else:
- help_txt +=[
- ["Cut", self.carver_prefs.Key_Create],\
- ]
- if self.CutMode == RECTANGLE:
- help_txt +=[
- ["Dimension", "MouseMove"],\
- ["Move all", "Alt"],\
- ["Validate", "LMB"],\
- ["Rebool", "Shift"]
- ]
-
- elif self.CutMode == CIRCLE:
- help_txt +=[
- ["Rotation and Radius", "MouseMove"],\
- ["Move all", "Alt"],\
- ["Subdivision", self.carver_prefs.Key_Subrem + " " + self.carver_prefs.Key_Subadd],\
- ["Incremental rotation", "Ctrl"],\
- ["Rebool", "Shift"]
- ]
-
- elif self.CutMode == LINE:
- help_txt +=[
- ["Dimension", "MouseMove"],\
- ["Move all", "Alt"],\
- ["Validate", "Space"],\
- ["Rebool", "Shift"],\
- ["Snap", "Ctrl"],\
- ["Scale Snap", "WheelMouse"],\
- ]
- else:
- # ObjectMode
- help_txt +=[
- ["Difference", "Space"],\
- ["Rebool", "Shift + Space"],\
- ["Duplicate", "Alt + Space"],\
- ["Scale", self.carver_prefs.Key_Scale],\
- ["Rotation", "LMB + Move"],\
- ["Step Angle", "CTRL + LMB + Move"],\
- ]
-
- if self.ProfileMode:
- help_txt +=[["Previous or Next Profile", self.carver_prefs.Key_Subadd + " " + self.carver_prefs.Key_Subrem]]
-
- help_txt +=[
- ["Create / Delete rows", chr(8597)],\
- ["Create / Delete cols", chr(8596)],\
- ["Gap for rows or columns", self.carver_prefs.Key_Gapy + " " + self.carver_prefs.Key_Gapx]
- ]
-
- blf.size(0, round(15 * ui_scale), 72)
- help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
- draw_string(self, color1, color2, xHelp, yHelp, help_txt, max_option)
-
- if self.ProfileMode:
- xrect = region.width - t_panel_width - 80
- yrect = 80
- coords = [(xrect, yrect), (xrect+60, yrect), (xrect+60, yrect-60), (xrect, yrect-60)]
-
- # Draw rectangle background in the lower right
- draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
-
- # Use numpy to get the vertices and indices of the profile object to draw
- WidthProfil = 50
- location = Vector((region.width - t_panel_width - WidthProfil, 50, 0))
- ProfilScale = 20.0
- coords = []
- mesh = bpy.data.meshes[self.Profils[self.nProfil][0]]
- mesh.calc_loop_triangles()
- vertices = np.empty((len(mesh.vertices), 3), 'f')
- indices = np.empty((len(mesh.loop_triangles), 3), 'i')
- mesh.vertices.foreach_get("co", np.reshape(vertices, len(mesh.vertices) * 3))
- mesh.loop_triangles.foreach_get("vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
-
- for idx, vals in enumerate(vertices):
- coords.append([
- vals[0] * ProfilScale + location.x,
- vals[1] * ProfilScale + location.y,
- vals[2] * ProfilScale + location.z
- ])
-
- #Draw the silhouette of the mesh
- draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
-
-
- if self.CutMode:
-
- if len(self.mouse_path) > 1:
- x0 = self.mouse_path[0][0]
- y0 = self.mouse_path[0][1]
- x1 = self.mouse_path[1][0]
- y1 = self.mouse_path[1][1]
-
- # Cut rectangle
- if self.CutType == RECTANGLE:
- coords = [
- (x0 + self.xpos, y0 + self.ypos), (x1 + self.xpos, y0 + self.ypos), \
- (x1 + self.xpos, y1 + self.ypos), (x0 + self.xpos, y1 + self.ypos)
- ]
- indices = ((0, 1, 2), (2, 0, 3))
-
- self.rectangle_coord = coords
-
- draw_shader(self, UIColor, 1, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
-
- #Draw points
- draw_shader(self, UIColor, 1, 'POINTS', coords, size=3)
-
- if self.shift or self.CreateMode:
- draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
-
- # Draw grid (based on the overlay options) to show the incremental snapping
- if self.ctrl:
- mini_grid(self, context, UIColor)
-
- # Cut Line
- elif self.CutType == LINE:
- coords = []
- indices = []
- top_grid = False
-
- for idx, vals in enumerate(self.mouse_path):
- coords.append([vals[0] + self.xpos, vals[1] + self.ypos])
- indices.append([idx])
-
- # Draw lines
- if self.Closed:
- draw_shader(self, UIColor, 1.0, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
- else:
- draw_shader(self, UIColor, 1.0, 'LINE_STRIP', coords, size=self.carver_prefs.LineWidth)
-
- # Draw points
- draw_shader(self, UIColor, 1.0, 'POINTS', coords, size=3)
-
- # Draw polygon
- if (self.shift) or (self.CreateMode and self.Closed):
- draw_shader(self, UIColor, 0.5, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
-
- # Draw grid (based on the overlay options) to show the incremental snapping
- if self.ctrl:
- mini_grid(self, context, UIColor)
-
- # Circle Cut
- elif self.CutType == CIRCLE:
- # Create a circle using a tri fan
- tris_coords, indices = draw_circle(self, x0, y0)
-
- # Remove the vertex in the center to get the outer line of the circle
- line_coords = tris_coords[1:]
- draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=self.carver_prefs.LineWidth)
-
- if self.shift or self.CreateMode:
- draw_shader(self, UIColor, 0.5, 'TRIS', tris_coords, size=self.carver_prefs.LineWidth, indices=indices)
-
- if (self.ObjectMode or self.ProfileMode) and len(self.CurrentSelection) > 0:
- if self.ShowCursor:
- region = context.region
- rv3d = context.space_data.region_3d
-
- if self.ObjectMode:
- ob = self.ObjectBrush
- if self.ProfileMode:
- ob = self.ProfileBrush
- mat = ob.matrix_world
-
- # 50% alpha, 2 pixel width line
- bgl.glEnable(bgl.GL_BLEND)
-
- bbox = [mat @ Vector(b) for b in ob.bound_box]
- objBBDiagonal = objDiagonal(self.CurrentSelection[0])
-
- if self.shift:
- gl_size = 4
- UIColor = (0.5, 1.0, 0.0, 1.0)
- else:
- gl_size = 2
- UIColor = (1.0, 0.8, 0.0, 1.0)
-
- line_coords = []
- idx = 0
- CRadius = ((bbox[7] - bbox[0]).length) / 2
- for i in range(int(len(self.CLR_C) / 3)):
- vector3d = (self.CLR_C[idx * 3] * CRadius + self.CurLoc.x, \
- self.CLR_C[idx * 3 + 1] * CRadius + self.CurLoc.y, \
- self.CLR_C[idx * 3 + 2] * CRadius + self.CurLoc.z)
- vector2d = bpy_extras.view3d_utils.location_3d_to_region_2d(region, rv3d, vector3d)
- if vector2d is not None:
- line_coords.append((vector2d[0], vector2d[1]))
- idx += 1
- if len(line_coords) > 0 :
- draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=gl_size)
-
- # Object display
- if self.quat_rot is not None:
- ob.location = self.CurLoc
- v = Vector()
- v.x = v.y = 0.0
- v.z = self.BrushDepthOffset
- ob.location += self.quat_rot @ v
-
- e = Euler()
- e.x = 0.0
- e.y = 0.0
- e.z = self.aRotZ / 25.0
-
- qe = e.to_quaternion()
- qRot = self.quat_rot @ qe
- ob.rotation_mode = 'QUATERNION'
- ob.rotation_quaternion = qRot
- ob.rotation_mode = 'XYZ'
-
- if self.ProfileMode:
- if self.ProfileBrush is not None:
- self.ProfileBrush.location = self.CurLoc
- self.ProfileBrush.rotation_mode = 'QUATERNION'
- self.ProfileBrush.rotation_quaternion = qRot
- self.ProfileBrush.rotation_mode = 'XYZ'
-
- # Opengl defaults
- bgl.glLineWidth(1)
- bgl.glDisable(bgl.GL_BLEND)
+ font_id = 0
+ region = context.region
+ UIColor = (0.992, 0.5518, 0.0, 1.0)
+
+ # Cut Type
+ RECTANGLE = 0
+ LINE = 1
+ CIRCLE = 2
+ self.carver_prefs = context.preferences.addons[__package__].preferences
+
+ # Color
+ color1 = (1.0, 1.0, 1.0, 1.0)
+ color2 = UIColor
+
+ #The mouse is outside the active region
+ if not self.in_view_3d:
+ color1 = color2 = (1.0, 0.2, 0.1, 1.0)
+
+ # Primitives type
+ PrimitiveType = "Rectangle"
+ if self.CutType == CIRCLE:
+ PrimitiveType = "Circle"
+ if self.CutType == LINE:
+ PrimitiveType = "Line"
+
+ # Width screen
+ overlap = context.preferences.system.use_region_overlap
+
+ t_panel_width = 0
+ if overlap:
+ for region in context.area.regions:
+ if region.type == 'TOOLS':
+ t_panel_width = region.width
+
+ # Initial position
+ region_width = int(region.width / 2.0)
+ y_txt = 10
+
+
+ # Draw the center command from bottom to top
+
+ # Get the size of the text
+ text_size = 18 if region.width >= 850 else 12
+ ui_scale = bpy.context.preferences.system.ui_scale
+ blf.size(0, round(text_size * ui_scale), 72)
+
+ # Help Display
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+
+ # Depth Cursor
+ TypeStr = "Cursor Depth [" + self.carver_prefs.Key_Depth + "]"
+ BoolStr = "(ON)" if self.snapCursor else "(OFF)"
+ help_txt = [[TypeStr, BoolStr]]
+
+ # Close poygonal shape
+ if self.CreateMode and self.CutType == LINE:
+ TypeStr = "Close [" + self.carver_prefs.Key_Close + "]"
+ BoolStr = "(ON)" if self.Closed else "(OFF)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ if self.CreateMode is False:
+ # Apply Booleans
+ TypeStr = "Apply Operations [" + self.carver_prefs.Key_Apply + "]"
+ BoolStr = "(OFF)" if self.dont_apply_boolean else "(ON)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ #Auto update for bevel
+ TypeStr = "Bevel Update [" + self.carver_prefs.Key_Update + "]"
+ BoolStr = "(ON)" if self.Auto_BevelUpdate else "(OFF)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ # Circle subdivisions
+ if self.CutType == CIRCLE:
+ TypeStr = "Subdivisions [" + self.carver_prefs.Key_Subrem + "][" + self.carver_prefs.Key_Subadd + "]"
+ BoolStr = str((int(360 / self.stepAngle[self.step])))
+ help_txt += [[TypeStr, BoolStr]]
+
+ if self.CreateMode:
+ help_txt += [["Type [Space]", PrimitiveType]]
+ else:
+ help_txt += [["Cut Type [Space]", PrimitiveType]]
+
+ else:
+ # Instantiate
+ TypeStr = "Instantiate [" + self.carver_prefs.Key_Instant + "]"
+ BoolStr = "(ON)" if self.Instantiate else "(OFF)"
+ help_txt = [[TypeStr, BoolStr]]
+
+ # Random rotation
+ if self.alt:
+ TypeStr = "Random Rotation [" + self.carver_prefs.Key_Randrot + "]"
+ BoolStr = "(ON)" if self.RandomRotation else "(OFF)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ # Thickness
+ if self.BrushSolidify:
+ TypeStr = "Thickness [" + self.carver_prefs.Key_Depth + "]"
+ if self.ProfileMode:
+ BoolStr = str(round(self.ProfileBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
+ if self.ObjectMode:
+ BoolStr = str(round(self.ObjectBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
+ help_txt += [[TypeStr, BoolStr]]
+
+ # Brush depth
+ if (self.ObjectMode):
+ TypeStr = "Carve Depth [" + self.carver_prefs.Key_Depth + "]"
+ BoolStr = str(round(self.ObjectBrush.data.vertices[0].co.z, 2))
+ help_txt += [[TypeStr, BoolStr]]
+
+ TypeStr = "Brush Depth [" + self.carver_prefs.Key_BrushDepth + "]"
+ BoolStr = str(round(self.BrushDepthOffset, 2))
+ help_txt += [[TypeStr, BoolStr]]
+
+ help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
+ xCmd = region_width - (max_option + max_key + comma) / 2
+ draw_string(self, color1, color2, xCmd, y_txt, help_txt, max_option, divide = 2)
+
+
+ # Separator (Line)
+ LineWidth = (max_option + max_key + comma) / 2
+ if region.width >= 850:
+ LineWidth = 140
+
+ LineWidth = (max_option + max_key + comma)
+ coords = [(int(region_width - LineWidth/2), y_txt + bloc_height + 8), \
+ (int(region_width + LineWidth/2), y_txt + bloc_height + 8)]
+ draw_shader(self, UIColor, 1, 'LINES', coords, self.carver_prefs.LineWidth)
+
+ # Command Display
+ if self.CreateMode and ((self.ObjectMode is False) and (self.ProfileMode is False)):
+ BooleanMode = "Create"
+ else:
+ if self.ObjectMode or self.ProfileMode:
+ BooleanType = "Difference) [T]" if self.BoolOps == self.difference else "Union) [T]"
+ BooleanMode = \
+ "Object Brush (" + BooleanType if self.ObjectMode else "Profil Brush (" + BooleanType
+ else:
+ BooleanMode = \
+ "Difference" if (self.shift is False) and (self.ForceRebool is False) else "Rebool"
+
+ # Display boolean mode
+ text_size = 40 if region.width >= 850 else 20
+ blf.size(0, round(text_size * ui_scale), 72)
+
+ draw_string(self, color2, color2, region_width - (blf.dimensions(0, BooleanMode)[0]) / 2, \
+ y_txt + bloc_height + 16, BooleanMode, 0, divide = 2)
+
+ if region.width >= 850:
+
+ if self.AskHelp is False:
+ # "H for Help" text
+ blf.size(0, round(13 * ui_scale), 72)
+ help_txt = "[" + self.carver_prefs.Key_Help + "] for help"
+ txt_width = blf.dimensions(0, help_txt)[0]
+ txt_height = (blf.dimensions(0, "gM")[1] * 1.45)
+
+ # Draw a rectangle and put the text "H for Help"
+ xrect = 40
+ yrect = 40
+ rect_vertices = [(xrect - 5, yrect - 5), (xrect + txt_width + 5, yrect - 5), \
+ (xrect + txt_width + 5, yrect + txt_height + 5), (xrect - 5, yrect + txt_height + 5)]
+ draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', rect_vertices, self.carver_prefs.LineWidth)
+ draw_string(self, color1, color2, xrect, yrect, help_txt, 0)
+
+ else:
+ #Draw the help text
+ xHelp = 30 + t_panel_width
+ yHelp = 10
+
+ if self.ObjectMode or self.ProfileMode:
+ if self.ProfileMode:
+ help_txt = [["Object Mode", self.carver_prefs.Key_Brush]]
+ else:
+ help_txt = [["Cut Mode", self.carver_prefs.Key_Brush]]
+
+ else:
+ help_txt =[
+ ["Profil Brush", self.carver_prefs.Key_Brush],\
+ ["Move Cursor", "Ctrl + LMB"]
+ ]
+
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+ if self.CreateMode is False:
+ help_txt +=[
+ ["Create geometry", self.carver_prefs.Key_Create],\
+ ]
+ else:
+ help_txt +=[
+ ["Cut", self.carver_prefs.Key_Create],\
+ ]
+ if self.CutMode == RECTANGLE:
+ help_txt +=[
+ ["Dimension", "MouseMove"],\
+ ["Move all", "Alt"],\
+ ["Validate", "LMB"],\
+ ["Rebool", "Shift"]
+ ]
+
+ elif self.CutMode == CIRCLE:
+ help_txt +=[
+ ["Rotation and Radius", "MouseMove"],\
+ ["Move all", "Alt"],\
+ ["Subdivision", self.carver_prefs.Key_Subrem + " " + self.carver_prefs.Key_Subadd],\
+ ["Incremental rotation", "Ctrl"],\
+ ["Rebool", "Shift"]
+ ]
+
+ elif self.CutMode == LINE:
+ help_txt +=[
+ ["Dimension", "MouseMove"],\
+ ["Move all", "Alt"],\
+ ["Validate", "Space"],\
+ ["Rebool", "Shift"],\
+ ["Snap", "Ctrl"],\
+ ["Scale Snap", "WheelMouse"],\
+ ]
+ else:
+ # ObjectMode
+ help_txt +=[
+ ["Difference", "Space"],\
+ ["Rebool", "Shift + Space"],\
+ ["Duplicate", "Alt + Space"],\
+ ["Scale", self.carver_prefs.Key_Scale],\
+ ["Rotation", "LMB + Move"],\
+ ["Step Angle", "CTRL + LMB + Move"],\
+ ]
+
+ if self.ProfileMode:
+ help_txt +=[["Previous or Next Profile", self.carver_prefs.Key_Subadd + " " + self.carver_prefs.Key_Subrem]]
+
+ help_txt +=[
+ ["Create / Delete rows", chr(8597)],\
+ ["Create / Delete cols", chr(8596)],\
+ ["Gap for rows or columns", self.carver_prefs.Key_Gapy + " " + self.carver_prefs.Key_Gapx]
+ ]
+
+ blf.size(0, round(15 * ui_scale), 72)
+ help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
+ draw_string(self, color1, color2, xHelp, yHelp, help_txt, max_option)
+
+ if self.ProfileMode:
+ xrect = region.width - t_panel_width - 80
+ yrect = 80
+ coords = [(xrect, yrect), (xrect+60, yrect), (xrect+60, yrect-60), (xrect, yrect-60)]
+
+ # Draw rectangle background in the lower right
+ draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
+
+ # Use numpy to get the vertices and indices of the profile object to draw
+ WidthProfil = 50
+ location = Vector((region.width - t_panel_width - WidthProfil, 50, 0))
+ ProfilScale = 20.0
+ coords = []
+ mesh = bpy.data.meshes[self.Profils[self.nProfil][0]]
+ mesh.calc_loop_triangles()
+ vertices = np.empty((len(mesh.vertices), 3), 'f')
+ indices = np.empty((len(mesh.loop_triangles), 3), 'i')
+ mesh.vertices.foreach_get("co", np.reshape(vertices, len(mesh.vertices) * 3))
+ mesh.loop_triangles.foreach_get("vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
+
+ for idx, vals in enumerate(vertices):
+ coords.append([
+ vals[0] * ProfilScale + location.x,
+ vals[1] * ProfilScale + location.y,
+ vals[2] * ProfilScale + location.z
+ ])
+
+ #Draw the silhouette of the mesh
+ draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
+
+
+ if self.CutMode:
+
+ if len(self.mouse_path) > 1:
+ x0 = self.mouse_path[0][0]
+ y0 = self.mouse_path[0][1]
+ x1 = self.mouse_path[1][0]
+ y1 = self.mouse_path[1][1]
+
+ # Cut rectangle
+ if self.CutType == RECTANGLE:
+ coords = [
+ (x0 + self.xpos, y0 + self.ypos), (x1 + self.xpos, y0 + self.ypos), \
+ (x1 + self.xpos, y1 + self.ypos), (x0 + self.xpos, y1 + self.ypos)
+ ]
+ indices = ((0, 1, 2), (2, 0, 3))
+
+ self.rectangle_coord = coords
+
+ draw_shader(self, UIColor, 1, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
+
+ #Draw points
+ draw_shader(self, UIColor, 1, 'POINTS', coords, size=3)
+
+ if self.shift or self.CreateMode:
+ draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
+
+ # Draw grid (based on the overlay options) to show the incremental snapping
+ if self.ctrl:
+ mini_grid(self, context, UIColor)
+
+ # Cut Line
+ elif self.CutType == LINE:
+ coords = []
+ indices = []
+ top_grid = False
+
+ for idx, vals in enumerate(self.mouse_path):
+ coords.append([vals[0] + self.xpos, vals[1] + self.ypos])
+ indices.append([idx])
+
+ # Draw lines
+ if self.Closed:
+ draw_shader(self, UIColor, 1.0, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
+ else:
+ draw_shader(self, UIColor, 1.0, 'LINE_STRIP', coords, size=self.carver_prefs.LineWidth)
+
+ # Draw points
+ draw_shader(self, UIColor, 1.0, 'POINTS', coords, size=3)
+
+ # Draw polygon
+ if (self.shift) or (self.CreateMode and self.Closed):
+ draw_shader(self, UIColor, 0.5, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
+
+ # Draw grid (based on the overlay options) to show the incremental snapping
+ if self.ctrl:
+ mini_grid(self, context, UIColor)
+
+ # Circle Cut
+ elif self.CutType == CIRCLE:
+ # Create a circle using a tri fan
+ tris_coords, indices = draw_circle(self, x0, y0)
+
+ # Remove the vertex in the center to get the outer line of the circle
+ line_coords = tris_coords[1:]
+ draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=self.carver_prefs.LineWidth)
+
+ if self.shift or self.CreateMode:
+ draw_shader(self, UIColor, 0.5, 'TRIS', tris_coords, size=self.carver_prefs.LineWidth, indices=indices)
+
+ if (self.ObjectMode or self.ProfileMode) and len(self.CurrentSelection) > 0:
+ if self.ShowCursor:
+ region = context.region
+ rv3d = context.space_data.region_3d
+
+ if self.ObjectMode:
+ ob = self.ObjectBrush
+ if self.ProfileMode:
+ ob = self.ProfileBrush
+ mat = ob.matrix_world
+
+ # 50% alpha, 2 pixel width line
+ bgl.glEnable(bgl.GL_BLEND)
+
+ bbox = [mat @ Vector(b) for b in ob.bound_box]
+ objBBDiagonal = objDiagonal(self.CurrentSelection[0])
+
+ if self.shift:
+ gl_size = 4
+ UIColor = (0.5, 1.0, 0.0, 1.0)
+ else:
+ gl_size = 2
+ UIColor = (1.0, 0.8, 0.0, 1.0)
+
+ line_coords = []
+ idx = 0
+ CRadius = ((bbox[7] - bbox[0]).length) / 2
+ for i in range(int(len(self.CLR_C) / 3)):
+ vector3d = (self.CLR_C[idx * 3] * CRadius + self.CurLoc.x, \
+ self.CLR_C[idx * 3 + 1] * CRadius + self.CurLoc.y, \
+ self.CLR_C[idx * 3 + 2] * CRadius + self.CurLoc.z)
+ vector2d = bpy_extras.view3d_utils.location_3d_to_region_2d(region, rv3d, vector3d)
+ if vector2d is not None:
+ line_coords.append((vector2d[0], vector2d[1]))
+ idx += 1
+ if len(line_coords) > 0 :
+ draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=gl_size)
+
+ # Object display
+ if self.quat_rot is not None:
+ ob.location = self.CurLoc
+ v = Vector()
+ v.x = v.y = 0.0
+ v.z = self.BrushDepthOffset
+ ob.location += self.quat_rot @ v
+
+ e = Euler()
+ e.x = 0.0
+ e.y = 0.0
+ e.z = self.aRotZ / 25.0
+
+ qe = e.to_quaternion()
+ qRot = self.quat_rot @ qe
+ ob.rotation_mode = 'QUATERNION'
+ ob.rotation_quaternion = qRot
+ ob.rotation_mode = 'XYZ'
+
+ if self.ProfileMode:
+ if self.ProfileBrush is not None:
+ self.ProfileBrush.location = self.CurLoc
+ self.ProfileBrush.rotation_mode = 'QUATERNION'
+ self.ProfileBrush.rotation_quaternion = qRot
+ self.ProfileBrush.rotation_mode = 'XYZ'
+
+ # Opengl defaults
+ bgl.glLineWidth(1)
+ bgl.glDisable(bgl.GL_BLEND)