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:
authorlijenstina <lijenstina@gmail.com>2017-01-28 07:04:05 +0300
committerlijenstina <lijenstina@gmail.com>2017-01-28 07:04:05 +0300
commit31112922764d65181f310f2e9d5541afe7c01ce3 (patch)
tree661bc0708d6320f16d56168402cdcec139c7e239
parent827975878e751788a9a85513ba769444c52b70e6 (diff)
Fix T50456: Carver MT update to 1.1.6
Patch by Ted Milker (TedMilker) with minor modification, thanks. Bump Version to 1.1.6 Add In-scene profiles, brush depth adjustment, fix rotation bug Add the possibility of switching Solver between BMesh and Carve (default key is v) Minor style clean up and translation to English of comments Update some descriptions Switch the type for Enable_Tab_01 and 02 from scene properties to add-on preferences Add traceback to the modal except message
-rw-r--r--mesh_carver.py237
1 files changed, 189 insertions, 48 deletions
diff --git a/mesh_carver.py b/mesh_carver.py
index 5320b681..9fbb6eff 100644
--- a/mesh_carver.py
+++ b/mesh_carver.py
@@ -20,8 +20,8 @@
bl_info = {
"name": "Carver MT",
"category": "Object",
- "author": "Pixivore, Cédric LEPILLER",
- "version": (1, 1, 5),
+ "author": "Pixivore, Cedric LEPILLER, Ted Milker",
+ "version": (1, 1, 6),
"blender": (2, 77, 0),
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
"Scripts/Modeling/Carver",
@@ -455,8 +455,16 @@ UNION = 1
class CarverPrefs(bpy.types.AddonPreferences):
bl_idname = __name__
- bpy.types.Scene.Enable_Tab_01 = bpy.props.BoolProperty(default=False)
- bpy.types.Scene.Enable_Tab_02 = bpy.props.BoolProperty(default=False)
+ Enable_Tab_01 = bpy.props.BoolProperty(
+ name="Info",
+ description="Some general information and settings about the add-on",
+ default=False
+ )
+ Enable_Tab_02 = bpy.props.BoolProperty(
+ name="Hotkeys",
+ description="List of the shortcuts used during carving",
+ default=False
+ )
bpy.types.Scene.Key_Create = bpy.props.StringProperty(
name="Object creation",
@@ -529,6 +537,12 @@ class CarverPrefs(bpy.types.AddonPreferences):
maxlen=1,
default="D",
)
+ bpy.types.Scene.Key_BrushDepth = bpy.props.StringProperty(
+ name="Brush Depth",
+ description="Brush depth",
+ maxlen=1,
+ default="C",
+ )
bpy.types.Scene.Key_Subadd = bpy.props.StringProperty(
name="Add subdivision",
description="Add subdivision",
@@ -547,19 +561,48 @@ class CarverPrefs(bpy.types.AddonPreferences):
maxlen=1,
default="R",
)
+ bpy.types.Scene.Key_Solver = bpy.props.StringProperty(
+ name="Solver",
+ description="Switch between Carve and BMesh Boolean solver\n"
+ "depending on a specific use case",
+ maxlen=1,
+ default="V",
+ )
+ bpy.types.Scene.ProfilePrefix = bpy.props.StringProperty(
+ name="Profile prefix",
+ description="Prefix to look for profiles with",
+ default="Carver_Profile-"
+ )
+ bpy.types.Scene.CarverSolver = bpy.props.EnumProperty(
+ name="Boolean Solver",
+ description="Boolean solver to use by default\n",
+ default="CARVE",
+ items=(
+ ('CARVE', 'Carve', "Carve solver, as the legacy one, can handle\n"
+ "basic coplanar but can often fail with\n"
+ "non-closed geometry"),
+ ('BMESH', 'BMesh', "BMesh solver is faster, but cannot handle\n"
+ "coplanar and self-intersecting geometry")
+ )
+ )
def draw(self, context):
scene = context.scene
layout = self.layout
- layout.prop(context.scene, "Enable_Tab_01", text="Info", icon="QUESTION")
- if scene.Enable_Tab_01:
- row = layout.row()
- layout.label(text="Carver Operator")
- layout.label(text="Select object and [CTRL]+[SHIFT]+[X] to carve")
+ layout.prop(self, "Enable_Tab_01", text="Info and Settings", icon="QUESTION")
+ if self.Enable_Tab_01:
+ layout.label(text="Carver Operator:", icon="LAYER_ACTIVE")
+ layout.label(text="Select a Mesh Object and press [CTRL]+[SHIFT]+[X] to carve",
+ icon="LAYER_USED")
+ layout.label(text="To finish carving press [ESC] or [RIGHT CLICK]",
+ icon="LAYER_USED")
- layout.prop(scene, "Enable_Tab_02", text="Keys", icon="KEYINGSET")
- if scene.Enable_Tab_02:
+ layout.prop(scene, "ProfilePrefix", text="Profile prefix")
+ layout.prop(scene, "CarverSolver", text="Solver")
+
+ layout.prop(self, "Enable_Tab_02", text="Keys", icon="KEYINGSET")
+ if self.Enable_Tab_02:
split = layout.split()
col = split.column()
col.label("Object Creation:")
@@ -568,6 +611,8 @@ class CarverPrefs(bpy.types.AddonPreferences):
col.prop(scene, "Key_Update", text="")
col.label("Boolean operation type:")
col.prop(scene, "Key_Bool", text="")
+ col.label("Solver:")
+ col.prop(scene, "Key_Solver", text="")
col = split.column()
col.label("Brush Mode:")
@@ -576,6 +621,8 @@ class CarverPrefs(bpy.types.AddonPreferences):
col.prop(scene, "Key_Help", text="")
col.label("Instantiate object:")
col.prop(scene, "Key_Instant", text="")
+ col.label("Brush Depth:")
+ col.prop(scene, "Key_BrushDepth", text="")
col = split.column()
col.label("Close polygonal shape:")
@@ -605,7 +652,7 @@ class CarverPrefs(bpy.types.AddonPreferences):
# Draw Text (Center position)
def DrawCenterText(text, xt, yt, Size, Color, self):
font_id = 0
- # Decalage Ombre
+ # Offset Shadow
Sshadow_x = 2
Sshadow_y = -2
@@ -626,7 +673,7 @@ def DrawCenterText(text, xt, yt, Size, Color, self):
# Draw text (Left position)
def DrawLeftText(text, xt, yt, Size, Color, self):
font_id = 0
- # Decalage Ombre
+ # Offset Shadow
Sshadow_x = 2
Sshadow_y = -2
@@ -646,7 +693,7 @@ def DrawLeftText(text, xt, yt, Size, Color, self):
# Draw text (Right position)
def DrawRightText(text, xt, yt, Size, Color, self):
font_id = 0
- # Decalage Ombre
+ # Offset Shadow
Sshadow_x = 2
Sshadow_y = -2
@@ -815,7 +862,7 @@ def draw_callback_px(self, context):
DrawLeftText(BoolStr, xLeftP, y, IFontSize, Color1, self)
else:
- #---INSTANTIATE:
+ # INSTANTIATE:
TypeStr = "Instantiate [" + context.scene.Key_Instant + "] : "
if self.Instantiate:
BoolStr = "(ON)"
@@ -829,7 +876,7 @@ def draw_callback_px(self, context):
DrawLeftText(TypeStr, xLeft, yCmd, IFontSize, Color0, self)
DrawLeftText(BoolStr, xLeftP, yCmd, IFontSize, Color1, self)
- #---RANDOM ROTATION:
+ # RANDOM ROTATION:
if self.alt:
TypeStr = "Random Rotation [" + context.scene.Key_Randrot + "] : "
if self.RandomRotation:
@@ -844,7 +891,7 @@ def draw_callback_px(self, context):
DrawLeftText(TypeStr, xLeft, yCmd - yInterval, IFontSize, Color0, self)
DrawLeftText(BoolStr, xLeftP, yCmd - yInterval, IFontSize, Color1, self)
- #---THICKNESS:
+ # THICKNESS:
if self.BrushSolidify:
TypeStr = "Thickness [" + context.scene.Key_Depth + "] : "
if self.ProfileMode:
@@ -863,9 +910,9 @@ def draw_callback_px(self, context):
DrawLeftText(TypeStr, xLeft, yCmd - yInterval, IFontSize, Color0, self)
DrawLeftText(BoolStr, xLeftP, yCmd - yInterval, IFontSize, Color1, self)
- #---BRUSH DEPTH:
+ # BRUSH DEPTH:
if (self.ObjectMode):
- TypeStr = "Brush Depth [" + context.scene.Key_Depth + "] : "
+ TypeStr = "Carve Depth [" + context.scene.Key_Depth + "] : "
BoolStr = str(round(self.ObjectBrush.data.vertices[0].co.z, 2))
OpsStr = TypeStr + BoolStr
blf.size(font_id, IFontSize, 72)
@@ -879,6 +926,20 @@ def draw_callback_px(self, context):
DrawLeftText(TypeStr, xLeft, yCmd - yInterval, IFontSize, Color0, self)
DrawLeftText(BoolStr, xLeftP, yCmd - yInterval, IFontSize, Color1, self)
+ TypeStr = "Brush Depth [" + context.scene.Key_BrushDepth + "] : "
+ BoolStr = str(round(self.BrushDepthOffset, 2))
+ OpsStr = TypeStr + BoolStr
+ blf.size(font_id, IFontSize, 72)
+ TotalWidth = blf.dimensions(font_id, OpsStr)[0]
+ xLeft = region.width / 2 - TotalWidth / 2
+ xLeftP = xLeft + blf.dimensions(font_id, TypeStr)[0]
+ if self.alt:
+ DrawLeftText(TypeStr, xLeft, yCmd - yInterval * 3, IFontSize, Color0, self)
+ DrawLeftText(BoolStr, xLeftP, yCmd - yInterval * 3, IFontSize, Color1, self)
+ else:
+ DrawLeftText(TypeStr, xLeft, yCmd - yInterval * 2, IFontSize, Color0, self)
+ DrawLeftText(BoolStr, xLeftP, yCmd - yInterval * 2, IFontSize, Color1, self)
+
bgl.glEnable(bgl.GL_BLEND)
if region.width >= 850:
if self.AskHelp == False:
@@ -895,7 +956,7 @@ def draw_callback_px(self, context):
if region.width >= 850:
Help_FontSize = 15
Help_Interval = 20
- yHelp = 200
+ yHelp = 220
if self.ObjectMode or self.ProfileMode:
if self.ProfileMode:
@@ -912,9 +973,9 @@ def draw_callback_px(self, context):
Help_Interval * 2, Help_FontSize, UIColor, self)
DrawLeftText(": Profil Brush", 150 + t_panel_width, yHelp +
Help_Interval * 2, Help_FontSize, None, self)
- DrawLeftText("[Ctrl + LMB]", xHelp, yHelp - Help_Interval * 5, Help_FontSize, UIColor, self)
+ DrawLeftText("[Ctrl + LMB]", xHelp, yHelp - Help_Interval * 6, Help_FontSize, UIColor, self)
DrawLeftText(": Move Cursor", 150 + t_panel_width, yHelp -
- Help_Interval * 5, Help_FontSize, None, self)
+ Help_Interval * 6, Help_FontSize, None, self)
if (self.ObjectMode == False) and (self.ProfileMode == False):
if self.CreateMode == False:
@@ -930,8 +991,10 @@ def draw_callback_px(self, context):
if self.CutMode == RECTANGLE:
DrawLeftText("MouseMove", xHelp, yHelp, Help_FontSize, UIColor, self)
DrawLeftText("[Alt]", xHelp, yHelp - Help_Interval, Help_FontSize, UIColor, self)
+ DrawLeftText("[" + context.scene.Key_Solver + "]", xHelp, yHelp - Help_Interval * 2, Help_FontSize, UIColor, self)
DrawLeftText(": Dimension", 150 + t_panel_width, yHelp, Help_FontSize, None, self)
DrawLeftText(": Move all", 150 + t_panel_width, yHelp - Help_Interval, Help_FontSize, None, self)
+ DrawLeftText(": Solver [" + context.scene.CarverSolver + "]", 150 + t_panel_width, yHelp - Help_Interval * 2, Help_FontSize, None, self)
if self.CutMode == CIRCLE:
DrawLeftText("MouseMove", xHelp, yHelp, Help_FontSize, UIColor, self)
@@ -939,24 +1002,28 @@ def draw_callback_px(self, context):
DrawLeftText("[" + context.scene.Key_Subrem + "] [" + context.scene.Key_Subadd + "]",
xHelp, yHelp - Help_Interval * 2, Help_FontSize, UIColor, self)
DrawLeftText("[Ctrl]", xHelp, yHelp - Help_Interval * 3, Help_FontSize, UIColor, self)
+ DrawLeftText("[" + context.scene.Key_Solver + "]", xHelp, yHelp - Help_Interval * 4, Help_FontSize, UIColor, self)
DrawLeftText(": Rotation and Radius", 150 + t_panel_width, yHelp, Help_FontSize, None, self)
DrawLeftText(": Move all", 150 + t_panel_width, yHelp - Help_Interval, Help_FontSize, None, self)
DrawLeftText(": Subdivision", 150 + t_panel_width, yHelp -
Help_Interval * 2, Help_FontSize, None, self)
DrawLeftText(": Incremental rotation", 150 + t_panel_width,
yHelp - Help_Interval * 3, Help_FontSize, None, self)
+ DrawLeftText(": Solver [" + context.scene.CarverSolver + "]", 150 + t_panel_width, yHelp - Help_Interval * 4, Help_FontSize, None, self)
if self.CutMode == LINE:
DrawLeftText("MouseMove", xHelp, yHelp, Help_FontSize, UIColor, self)
DrawLeftText("[Alt]", xHelp, yHelp - Help_Interval, Help_FontSize, UIColor, self)
DrawLeftText("[Space]", xHelp, yHelp - Help_Interval * 2, Help_FontSize, UIColor, self)
DrawLeftText("[Ctrl]", xHelp, yHelp - Help_Interval * 3, Help_FontSize, UIColor, self)
+ DrawLeftText("[" + context.scene.Key_Solver + "]", xHelp, yHelp - Help_Interval * 4, Help_FontSize, UIColor, self)
DrawLeftText(": Dimension", 150 + t_panel_width, yHelp, Help_FontSize, None, self)
DrawLeftText(": Move all", 150 + t_panel_width, yHelp - Help_Interval, Help_FontSize, None, self)
DrawLeftText(": Validate", 150 + t_panel_width, yHelp -
Help_Interval * 2, Help_FontSize, None, self)
DrawLeftText(": Incremental", 150 + t_panel_width, yHelp -
Help_Interval * 3, Help_FontSize, None, self)
+ DrawLeftText(": Solver [" + context.scene.CarverSolver + "]", 150 + t_panel_width, yHelp - Help_Interval * 4, Help_FontSize, None, self)
if self.CreateMode:
DrawLeftText("[" + context.scene.Key_Subadd + "]", xHelp, yHelp -
Help_Interval * 4, Help_FontSize, UIColor, self)
@@ -988,13 +1055,15 @@ def draw_callback_px(self, context):
xHelp, yHelp - Help_Interval * 7, Help_FontSize, UIColor, self)
DrawLeftText(": Gap between rows or columns", 150 + t_panel_width,
yHelp - Help_Interval * 7, Help_FontSize, None, self)
+ DrawLeftText("[" + context.scene.Key_Solver + "]", xHelp, yHelp - Help_Interval * 8, Help_FontSize, UIColor, self)
+ DrawLeftText(": Solver [" + context.scene.CarverSolver + "]", 150 + t_panel_width, yHelp - Help_Interval * 8, Help_FontSize, None, self)
# Opengl Initialise
bgl.glEnable(bgl.GL_BLEND)
bgl.glColor4f(0.512, 0.919, 0.04, 1.0)
bgl.glLineWidth(2)
-# if context.space_data.region_3d.is_perspective == False:
+ # if context.space_data.region_3d.is_perspective == False:
if 1:
bgl.glEnable(bgl.GL_POINT_SMOOTH)
@@ -1175,6 +1244,10 @@ def draw_callback_px(self, context):
# Object display
if self.qRot is not None:
ob.location = self.CurLoc
+ v = mathutils.Vector()
+ v.x = v.y = 0.0
+ v.z = self.BrushDepthOffset
+ ob.location += self.qRot * v
e = mathutils.Euler()
e.x = 0.0
@@ -1812,6 +1885,7 @@ def Pick(context, event, self, ray_max=10000.0):
for obj in self.CList:
matrix = obj.matrix_world
hit, normal, face_index = obj_ray_cast(obj, matrix)
+ rotation = obj.rotation_euler.to_quaternion()
if hit is not None:
hit_world = matrix * hit
length_squared = (hit_world - ray_origin).length_squared
@@ -1823,7 +1897,7 @@ def Pick(context, event, self, ray_max=10000.0):
fs = face_index
if best_obj is not None:
- return hits, ns, fs
+ return hits, ns, fs, rotation
else:
return None, None, None
@@ -1921,6 +1995,11 @@ def duplicateObject(self):
ob_new = bpy.context.active_object
ob_new.location = self.CurLoc
+ v = mathutils.Vector()
+ v.x = v.y = 0.0
+ v.z = self.BrushDepthOffset
+ ob_new.location += self.qRot * v
+
if self.ObjectMode:
ob_new.scale = self.ObjectBrush.scale
if self.ProfileMode:
@@ -1930,7 +2009,7 @@ def duplicateObject(self):
e.x = e.y = 0.0
e.z = self.aRotZ / 25.0
-#---If duplicate with a grid, no random rotation (each mesh in the grid is already rotated randomly)
+ # If duplicate with a grid, no random rotation (each mesh in the grid is already rotated randomly)
if (self.alt == True) and ((self.nbcol + self.nbrow) < 3):
if self.RandomRotation:
e.z += random.random()
@@ -1978,7 +2057,7 @@ def update_grid(self, context):
if self.gapy < 0:
self.gapy = 0
-#---Get the data from the profils or the object
+ # Get the data from the profils or the object
if self.ProfileMode:
brush = bpy.data.objects.new(self.Profils[self.nProfil][0], bpy.data.meshes[self.Profils[self.nProfil][0]])
obj = bpy.data.objects["CT_Profil"]
@@ -1992,15 +2071,15 @@ def update_grid(self, context):
obfaces = brush.data.polygons
lenverts = len(brush.data.vertices)
-#--Gap between each row / column
+ # Gap between each row / column
gapx = self.gapx
gapy = self.gapy
-#--Width of each row / column
+ # Width of each row / column
widthx = brush.dimensions.x * self.scale_x
widthy = brush.dimensions.y * self.scale_y
-#--Compute the corners so the new object will be always at the center
+ # Compute the corners so the new object will be always at the center
left = -((self.nbcol - 1) * (widthx + gapx)) / 2
start = -((self.nbrow - 1) * (widthy + gapy)) / 2
@@ -2010,7 +2089,7 @@ def update_grid(self, context):
startx = left + ((widthx + gapx) * col)
starty = start + ((widthy + gapy) * row)
- #---Add random rotation
+ # Add random rotation
if (self.RandomRotation) and not (self.GridScaleX or self.GridScaleY):
rotmat = mathutils.Matrix.Rotation(math.radians(360 * random.random()), 4, 'Z')
for v in obverts:
@@ -2020,7 +2099,7 @@ def update_grid(self, context):
faces.extend([[v + numface * lenverts for v in p.vertices] for p in obfaces])
numface += 1
-#---Update the mesh
+ # Update the mesh
# Create mesh data
mymesh = bpy.data.meshes.new("CT_Profil")
# Generate mesh data
@@ -2041,11 +2120,13 @@ def boolean_difference():
BoolMod = ActiveObj.modifiers.new("CT_" + bpy.context.selected_objects[0].name, "BOOLEAN")
BoolMod.object = bpy.context.selected_objects[0]
BoolMod.operation = "DIFFERENCE"
+ BoolMod.solver = bpy.context.scene.CarverSolver
bpy.context.selected_objects[0].draw_type = 'WIRE'
else:
BoolMod = ActiveObj.modifiers.new("CT_" + bpy.context.selected_objects[1].name, "BOOLEAN")
BoolMod.object = bpy.context.selected_objects[1]
BoolMod.operation = "DIFFERENCE"
+ BoolMod.solver = bpy.context.scene.CarverSolver
bpy.context.selected_objects[1].draw_type = 'WIRE'
@@ -2107,10 +2188,12 @@ def Rebool(context, self):
m = LastObjectCreated.modifiers.new("CT_INTERSECT", "BOOLEAN")
m.operation = "INTERSECT"
+ m.solver = context.scene.CarverSolver
m.object = Brush
m = obj.modifiers.new("CT_DIFFERENCE", "BOOLEAN")
m.operation = "DIFFERENCE"
+ m.solver = context.scene.CarverSolver
m.object = Brush
for mb in LastObj.modifiers:
@@ -2156,7 +2239,7 @@ def createMeshFromData(self):
if self.Profils[self.nProfil][0] not in bpy.data.meshes:
# Create mesh and object
me = bpy.data.meshes.new(self.Profils[self.nProfil][0])
- # Create mesh from given verts, faces.
+ # Create mesh from given verts, faces.
me.from_pydata(self.Profils[self.nProfil][2], [], self.Profils[self.nProfil][3])
# Update mesh with new data
me.update()
@@ -2196,7 +2279,7 @@ class Carver(bpy.types.Operator):
bl_description = "Cut or create in object mode"
bl_options = {'REGISTER', 'UNDO'}
- #---------------------------------------------------------------------------------------------------
+ # --------------------------------------------------------------------------------------------------
@classmethod
def poll(cls, context):
ob = None
@@ -2207,9 +2290,9 @@ class Carver(bpy.types.Operator):
(ob and ob.type == 'MESH' and context.mode == 'OBJECT') or
(context.mode == 'OBJECT' and ob is None) or
(context.mode == 'EDIT_MESH'))
- #---------------------------------------------------------------------------------------------------
+ # --------------------------------------------------------------------------------------------------
- #---------------------------------------------------------------------------------------------------
+ # --------------------------------------------------------------------------------------------------
def modal(self, context, event):
PI = 3.14156
@@ -2457,6 +2540,12 @@ class Carver(bpy.types.Operator):
if event.type == context.scene.Key_Apply and event.value == 'PRESS':
self.DontApply = not self.DontApply
+ if event.type == context.scene.Key_Solver and event.value == 'PRESS':
+ if context.scene.CarverSolver == "CARVE":
+ context.scene.CarverSolver = "BMESH"
+ else:
+ context.scene.CarverSolver = "CARVE"
+
# Scale object
if event.type == context.scene.Key_Scale and event.value == 'PRESS':
if self.ObjectScale == False:
@@ -2511,7 +2600,7 @@ class Carver(bpy.types.Operator):
for v in self.ObjectBrush.data.vertices:
if abs(v.co.z - z) > ErrorMarge:
solidify = False
- self.BrushDepth = True
+ self.CarveDepth = True
self.am = event.mouse_region_x, event.mouse_region_y
break
@@ -2551,6 +2640,13 @@ class Carver(bpy.types.Operator):
self.WidthSolidify = not self.WidthSolidify
self.am = event.mouse_region_x, event.mouse_region_y
+ if event.type == context.scene.Key_BrushDepth and event.value == 'PRESS':
+ if self.ObjectMode:
+ self.CarveDepth = False
+
+ self.BrushDepth = True
+ self.am = event.mouse_region_x, event.mouse_region_y
+
# Random rotation
if event.type == 'R' and event.value == 'PRESS':
self.RandomRotation = not self.RandomRotation
@@ -2579,10 +2675,13 @@ class Carver(bpy.types.Operator):
bpy.data.objects[self.ProfileBrush.name].modifiers[
"CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.am[0]) / fac
self.am = event.mouse_region_x, event.mouse_region_y
- elif self.BrushDepth:
+ elif self.CarveDepth:
for v in self.ObjectBrush.data.vertices:
v.co.z += (event.mouse_region_x - self.am[0]) / fac
self.am = event.mouse_region_x, event.mouse_region_y
+ elif self.BrushDepth:
+ self.BrushDepthOffset += (event.mouse_region_x - self.am[0]) / fac
+ self.am = event.mouse_region_x, event.mouse_region_y
else:
if (self.GridScaleX):
self.gapx += (event.mouse_region_x - self.am[0]) / 50
@@ -2633,7 +2732,7 @@ class Carver(bpy.types.Operator):
self.ShowCursor = True
NormalObject = mathutils.Vector((0.0, 0.0, 1.0))
qR = RBenVe(NormalObject, vBack[1])
- self.qRot = qR
+ self.qRot = vBack[3] * qR
Pos = vBack[0]
MoveCursor(qR, vBack[0], self)
self.SavCurLoc = vBack[0]
@@ -2686,7 +2785,7 @@ class Carver(bpy.types.Operator):
if vBack[0] is not None:
NormalObject = mathutils.Vector((0.0, 0.0, 1.0))
self.aqR = RBenVe(NormalObject, vBack[1])
- self.qRot = self.aqR
+ self.qRot = vBack[3] * self.aqR
self.am = event.mouse_region_x, event.mouse_region_y
self.xSavMouse = event.mouse_region_x
@@ -2713,6 +2812,9 @@ class Carver(bpy.types.Operator):
if self.WidthSolidify:
self.WidthSolidify = False
+ if self.CarveDepth == True:
+ self.CarveDepth = False
+
if self.BrushDepth == True:
self.BrushDepth = False
@@ -2874,15 +2976,23 @@ class Carver(bpy.types.Operator):
return {'RUNNING_MODAL'}
except:
- print("Sometimes, something goes wrong...")
+ print("\n[Carver MT ERROR]\n")
+
+ import traceback
+ traceback.print_exc()
+
context.window.cursor_modal_set("DEFAULT")
context.area.header_text_set()
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+
+ self.report({'WARNING'},
+ "Operation finished. Failure during Carving (Check the console for more info)")
+
return {'FINISHED'}
- #---------------------------------------------------------------------------------------------------
+ # --------------------------------------------------------------------------------------------------
- #---------------------------------------------------------------------------------------------------
+ # --------------------------------------------------------------------------------------------------
def invoke(self, context, event):
if context.area.type == 'VIEW_3D':
if context.mode == 'EDIT_MESH':
@@ -2894,9 +3004,38 @@ class Carver(bpy.types.Operator):
self.Profils = []
for p in Profils:
self.Profils.append((p[0], p[1], p[2], p[3]))
+
+ for o in context.scene.objects:
+ if not o.name.startswith(context.scene.ProfilePrefix):
+ continue
+
+ # In-scene profiles may have changed, remove them to refresh
+ for m in bpy.data.meshes:
+ if m.name.startswith(context.scene.ProfilePrefix):
+ bpy.data.meshes.remove(m)
+
+ vertices = []
+ for v in o.data.vertices:
+ vertices.append((v.co.x, v.co.y, v.co.z))
+
+ faces = []
+ for f in o.data.polygons:
+ face = []
+
+ for v in f.vertices:
+ face.append(v)
+
+ faces.append(face)
+
+ self.Profils.append((o.name, mathutils.Vector((o.location.x, o.location.y, o.location.z)), vertices, faces))
+
self.nProfil = context.scene.nProfile
self.MaxProfil = len(self.Profils)
+ # reset selected profile if last profile exceeds length of array
+ if self.nProfil >= self.MaxProfil:
+ self.nProfil = context.scene.nProfile = 0
+
# Save selection
self.CurrentSelection = context.selected_objects.copy()
self.CurrentActive = context.active_object
@@ -2963,7 +3102,9 @@ class Carver(bpy.types.Operator):
# Brush
self.BrushSolidify = False
self.WidthSolidify = False
+ self.CarveDepth = False
self.BrushDepth = False
+ self.BrushDepthOffset = 0.0
self.ObjectScale = False
@@ -3019,7 +3160,7 @@ class Carver(bpy.types.Operator):
if len(context.selected_objects) > 1:
self.ObjectBrush = context.active_object
- #---Copy the brush object
+ # Copy the brush object
ob = bpy.data.objects.new("CarverBrushCopy", context.object.data.copy())
ob.location = self.ObjectBrush.location
scene = context.scene
@@ -3072,9 +3213,9 @@ class Carver(bpy.types.Operator):
else:
self.report({'WARNING'}, "View3D not found, cannot run operator")
return {'CANCELLED'}
- #---------------------------------------------------------------------------------------------------
+ # --------------------------------------------------------------------------------------------------
- #---------------------------------------------------------------------------------------------------
+ # --------------------------------------------------------------------------------------------------
def CreateGeometry(self):
context = bpy.context
@@ -3138,9 +3279,9 @@ class Carver(bpy.types.Operator):
self.bDone = False
self.mouse_path.clear()
self.mouse_path = [(0, 0), (0, 0)]
- #---------------------------------------------------------------------------------------------------
+ # --------------------------------------------------------------------------------------------------
- #---------------------------------------------------------------------------------------------------
+ # --------------------------------------------------------------------------------------------------
def Cut(self):
context = bpy.context
@@ -3392,7 +3533,7 @@ def register():
def unregister():
bpy.utils.unregister_class(CarverPrefs)
- # remove keymap entry
+ # remove keymap entry
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()