Newer
Older
if self.gapy < 0:
self.gapy = 0
# Get the data from the profils or the object
brush = bpy.data.objects.new(
self.Profils[self.nProfil][0],
bpy.data.meshes[self.Profils[self.nProfil][0]]
)
obj = bpy.data.objects["CT_Profil"]
obfaces = brush.data.polygons
obverts = brush.data.vertices
lenverts = len(obverts)
else:
brush = bpy.data.objects["CarverBrushCopy"]
obj = context.selected_objects[0]
obverts = brush.data.vertices
obfaces = brush.data.polygons
lenverts = len(brush.data.vertices)
gapx = self.gapx
gapy = self.gapy
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
left = -((self.nbcol - 1) * (widthx + gapx)) / 2
start = -((self.nbrow - 1) * (widthy + gapy)) / 2
for i in range(self.nbrow * self.nbcol):
row = i % self.nbrow
col = i // self.nbrow
startx = left + ((widthx + gapx) * col)
starty = start + ((widthy + gapy) * row)
if (self.RandomRotation) and not (self.GridScaleX or self.GridScaleY):
rotmat = Matrix.Rotation(math.radians(360 * random.random()), 4, 'Z')
for v in obverts:
v.co = v.co * rotmat
verts.extend([((v.co.x - startx, v.co.y - starty, v.co.z)) for v in obverts])
faces.extend([[v + numface * lenverts for v in p.vertices] for p in obfaces])
numface += 1
# Create mesh data
mymesh = bpy.data.meshes.new("CT_Profil")
# Generate mesh data
mymesh.from_pydata(verts, edges, faces)
# Calculate the edges
mymesh.update(calc_edges=True)
# Update data
obj.data = mymesh
# Make the object active to remove doubles
context.scene.objects.active = obj
def boolean_operation(bool_type="DIFFERENCE"):
ActiveObj = bpy.context.active_object
sel_index = 0 if bpy.context.selected_objects[0] != bpy.context.active_object else 1
bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
BoolMod = ActiveObj.modifiers.new(
"CT_" + bpy.context.selected_objects[sel_index].name,
"BOOLEAN"
)
BoolMod.object = bpy.context.selected_objects[sel_index]
BoolMod.operation = bool_type
bpy.context.selected_objects[sel_index].display_type = 'WIRE'
def Rebool(context, self):
LastObj = context.active_object
Brush = context.selected_objects[0]
Brush.display_type = "WIRE"
obj = context.selected_objects[1]
bpy.ops.object.select_all(action='TOGGLE')
context.scene.objects.active = obj
obj.display_type = "SOLID"
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
obj.select = True
bpy.ops.object.duplicate_move(
OBJECT_OT_duplicate={
"linked": False,
"mode": 'TRANSLATION',
},
TRANSFORM_OT_translate={
"value": (0, 0, 0),
"constraint_axis": (False, False, False),
"constraint_orientation": 'GLOBAL',
"mirror": False,
"proportional": 'DISABLED',
"proportional_edit_falloff": 'SMOOTH',
"proportional_size": 1,
"snap": False,
"snap_target": 'CLOSEST',
"snap_point": (0, 0, 0),
"snap_align": False,
"snap_normal": (0, 0, 0),
"gpencil_strokes": False,
"texture_space": False,
"remove_on_cancel": False,
"release_confirm": False,
},
)
LastObjectCreated = context.active_object
m = LastObjectCreated.modifiers.new("CT_INTERSECT", "BOOLEAN")
m.operation = "INTERSECT"
m.object = Brush
m = obj.modifiers.new("CT_DIFFERENCE", "BOOLEAN")
m.operation = "DIFFERENCE"
m.object = Brush
for mb in LastObj.modifiers:
if mb.type == 'BEVEL':
mb.show_viewport = False
if self.ObjectBrush or self.ProfileBrush:
LastObjectCreated.show_in_front = False
try:
bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
self.report({'ERROR'}, str(exc_value))
if self.DontApply is False:
try:
bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_INTERSECT")
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
self.report({'ERROR'}, str(exc_value))
bpy.ops.object.select_all(action='TOGGLE')
for mb in LastObj.modifiers:
if mb.type == 'BEVEL':
mb.show_viewport = True
context.scene.objects.active = obj
obj.select = True
if self.DontApply is False:
try:
bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_DIFFERENCE")
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
self.report({'ERROR'}, str(exc_value))
bpy.ops.object.select_all(action='TOGGLE')
LastObjectCreated.select = True
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.
me.from_pydata(self.Profils[self.nProfil][2], [], self.Profils[self.nProfil][3])
# Update mesh with new data
me.update()
if "CT_Profil" not in bpy.data.objects:
ob = bpy.data.objects.new("CT_Profil", bpy.data.meshes[self.Profils[self.nProfil][0]])
ob.location = Vector((0.0, 0.0, 0.0))
# Link object to scene and make active
scn = bpy.context.scene
scn.objects.link(ob)
scn.objects.active = ob
ob.select = True
ob.location = Vector((10000.0, 0.0, 0.0))
ob.display_type = "WIRE"
self.SolidifyPossible = True
else:
bpy.data.objects["CT_Profil"].data = bpy.data.meshes[self.Profils[self.nProfil][0]]
def Selection_Save_Restore(self):
if "CT_Profil" in bpy.data.objects:
Selection_Save(self)
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects["CT_Profil"].select = True
bpy.context.scene.objects.active = bpy.data.objects["CT_Profil"]
if bpy.data.objects["CT_Profil"] in self.SavSel:
self.SavSel.remove(bpy.data.objects["CT_Profil"])
bpy.ops.object.delete(use_global=False)
Selection_Restore(self)
obj_name = getattr(bpy.context.active_object, "name", None)
self.SavSel = bpy.context.selected_objects.copy()
def Selection_Restore(self):
for o in self.SavSel:
o.select = True
if self.Sav_ac:
bpy.context.scene.objects.active = bpy.data.objects.get(self.Sav_ac, None)
# Modal Operator
class Carver(bpy.types.Operator):
bl_idname = "object.carver"
bl_label = "Carver"
bl_description = "Cut or create Meshes in Object mode"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
ob = None
if len(context.selected_objects) > 0:
ob = context.selected_objects[0]
# Test if selected object or none (for create mode)
return (
(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
region_types = {'WINDOW', 'UI'}
win = context.window
for area in win.screen.areas:
if area.type in ('VIEW_3D'):
for region in area.regions:
if not region_types or region.type in region_types:
region.tag_redraw()
if event.type in {
'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE',
'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_6',
'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9', 'NUMPAD_5'}:
return {'PASS_THROUGH'}
try:
# [Shift]
self.shift = True if event.shift else False
self.ctrl = True if event.ctrl else False
# [Alt]
self.alt = False
if event.alt:
if self.InitPosition is False:
# Initialise position variable for start position
self.xpos = 0
self.ypos = 0
self.last_mouse_region_x = event.mouse_region_x
self.last_mouse_region_y = event.mouse_region_y
self.InitPosition = True
self.alt = True
# [Alt] release
if self.InitPosition and self.alt is False:
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
for i in range(0, len(self.mouse_path)):
l = list(self.mouse_path[i])
l[0] += self.xpos
l[1] += self.ypos
self.mouse_path[i] = tuple(l)
self.xpos = self.ypos = 0
self.InitPosition = False
# Mode change (cut type)
if event.type == 'SPACE' and event.value == 'PRESS':
if self.ObjectMode or self.ProfileMode:
# If grid, remove double with intersect meshes
if ((self.nbcol + self.nbrow) > 3):
# Go in edit mode mode
bpy.ops.object.mode_set(mode='EDIT')
# Remove duplicate vertices
bpy.ops.mesh.remove_doubles()
# Return in object mode
bpy.ops.object.mode_set(mode='OBJECT')
if self.alt:
# Save selected objects
self.SavSel = context.selected_objects.copy()
if len(context.selected_objects) > 0:
bpy.ops.object.select_all(action='TOGGLE')
if self.ObjectMode:
SelectObject(self, self.ObjectBrush)
else:
SelectObject(self, self.ProfileBrush)
duplicateObject(self)
else:
# Brush Cut
self.Cut()
# Save selected objects
if self.ObjectMode:
if len(self.ObjectBrush.children) > 0:
self.SavSel = context.selected_objects.copy()
if len(context.selected_objects) > 0:
bpy.ops.object.select_all(action='TOGGLE')
if self.ObjectMode:
SelectObject(self, self.ObjectBrush)
else:
SelectObject(self, self.ProfileBrush)
duplicateObject(self)
UndoListUpdate(self)
# Save cursor position
self.SavMousePos = self.CurLoc
else:
# Cut Mode
self.CutMode += 1
if self.CutMode > 2:
self.CutMode = 0
else:
if self.CutMode == LINE:
# Cuts creation
CreateCutLine(self, context)
if self.CreateMode:
# Object creation
self.CreateGeometry()
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
# Cursor Snap
context.scene.mesh_carver.DepthCursor = self.snapCursor
context.scene.mesh_carver.OInstanciate = self.Instantiate
context.scene.mesh_carver.ORandom = self.RandomRotation
return {'FINISHED'}
else:
self.Cut()
UndoListUpdate(self)
# Object creation
if event.type == context.scene.Key_Create and event.value == 'PRESS':
if self.ExclusiveCreateMode is False:
self.CreateMode = not self.CreateMode
# Auto Bevel Update
if event.type == context.scene.Key_Update and event.value == 'PRESS':
self.Auto_BevelUpdate = not self.Auto_BevelUpdate
# Boolean operation type
if event.type == context.scene.Key_Bool and event.value == 'PRESS':
if (self.ProfileMode is True) or (self.ObjectMode is True):
if self.BoolOps == DIFFERENCE:
self.BoolOps = UNION
else:
self.BoolOps = DIFFERENCE
# Brush Mode
if event.type == context.scene.Key_Brush and event.value == 'PRESS':
self.DontApply = False
if (self.ProfileMode is False) and (self.ObjectMode is False):
self.ProfileMode = True
else:
self.ProfileMode = False
if self.ObjectBrush is not None:
if self.ObjectMode is False:
self.ObjectMode = True
self.BrushSolidify = False
self.CList = self.OB_List
Selection_Save_Restore(self)
context.scene.mesh_carver.nProfile = self.nProfil
else:
self.ObjectMode = False
else:
self.BrushSolidify = False
Selection_Save_Restore(self)
if self.ProfileMode:
createMeshFromData(self)
self.ProfileBrush = bpy.data.objects["CT_Profil"]
Selection_Save(self)
self.BrushSolidify = True
bpy.ops.object.select_all(action='TOGGLE')
self.ProfileBrush.select = True
context.scene.objects.active = self.ProfileBrush
# Set xRay
self.ProfileBrush.show_in_front = True
bpy.ops.object.modifier_add(type='SOLIDIFY')
context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
Selection_Restore(self)
self.CList = self.CurrentSelection
else:
if self.ObjectBrush is not None:
if self.ObjectMode is False:
if self.ObjectBrush is not None:
self.ObjectBrush.location = self.InitBrushPosition
self.ObjectBrush.scale = self.InitBrushScale
self.ObjectBrush.rotation_quaternion = self.InitBrushQRotation
self.ObjectBrush.rotation_euler = self.InitBrushERotation
self.ObjectBrush.display_type = self.ObjectBrush_DT
self.ObjectBrush.show_in_front = self.XRay
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
# Remove solidify modifier
Selection_Save(self)
self.BrushSolidify = False
bpy.ops.object.select_all(action='TOGGLE')
self.ObjectBrush.select = True
context.scene.objects.active = self.ObjectBrush
bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
Selection_Restore(self)
else:
if self.Solidify_Active_Start:
Selection_Save(self)
self.BrushSolidify = True
self.SolidifyPossible = True
bpy.ops.object.select_all(action='TOGGLE')
self.ObjectBrush.select = True
context.scene.objects.active = self.ObjectBrush
# Set xRay
self.ObjectBrush.show_in_front = True
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
bpy.ops.object.modifier_add(type='SOLIDIFY')
context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
Selection_Restore(self)
# Help display
if event.type == context.scene.Key_Help and event.value == 'PRESS':
self.AskHelp = not self.AskHelp
# Instantiate object
if event.type == context.scene.Key_Instant and event.value == 'PRESS':
self.Instantiate = not self.Instantiate
# Close polygonal shape
if event.type == context.scene.Key_Close and event.value == 'PRESS':
if self.CreateMode:
self.Closed = not self.Closed
if event.type == context.scene.Key_Apply and event.value == 'PRESS':
self.DontApply = not self.DontApply
# Scale object
if event.type == context.scene.Key_Scale and event.value == 'PRESS':
if self.ObjectScale is False:
self.am = event.mouse_region_x, event.mouse_region_y
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
self.ObjectScale = True
# Grid : Add column
if event.type == 'UP_ARROW' and event.value == 'PRESS':
self.nbcol += 1
update_grid(self, context)
# Grid : Add row
elif event.type == 'RIGHT_ARROW' and event.value == 'PRESS':
self.nbrow += 1
update_grid(self, context)
# Grid : Delete column
elif event.type == 'DOWN_ARROW' and event.value == 'PRESS':
self.nbcol -= 1
update_grid(self, context)
# Grid : Delete row
elif event.type == 'LEFT_ARROW' and event.value == 'PRESS':
self.nbrow -= 1
update_grid(self, context)
# Grid : Scale gap between columns
if event.type == context.scene.Key_Gapy and event.value == 'PRESS':
if self.GridScaleX is False:
self.am = event.mouse_region_x, event.mouse_region_y
self.GridScaleX = True
# Grid : Scale gap between rows
if event.type == context.scene.Key_Gapx and event.value == 'PRESS':
if self.GridScaleY is False:
self.am = event.mouse_region_x, event.mouse_region_y
self.GridScaleY = True
# Cursor depth or solidify pattern
if event.type == context.scene.Key_Depth and event.value == 'PRESS':
if (self.ObjectMode is False) and (self.ProfileMode is False):
self.snapCursor = not self.snapCursor
else:
# Solidify
if (self.ObjectMode or self.ProfileMode) and (self.SolidifyPossible):
solidify = True
if self.ObjectMode:
z = self.ObjectBrush.data.vertices[0].co.z
ErrorMarge = 0.01
for v in self.ObjectBrush.data.vertices:
if abs(v.co.z - z) > ErrorMarge:
solidify = False
self.am = event.mouse_region_x, event.mouse_region_y
break
if solidify:
if self.ObjectMode:
for mb in self.ObjectBrush.modifiers:
if mb.type == 'SOLIDIFY':
AlreadySoldify = True
else:
for mb in self.ProfileBrush.modifiers:
if mb.type == 'SOLIDIFY':
AlreadySoldify = True
if AlreadySoldify is False:
Selection_Save(self)
self.BrushSolidify = True
bpy.ops.object.select_all(action='TOGGLE')
if self.ObjectMode:
self.ObjectBrush.select = True
context.scene.objects.active = self.ObjectBrush
# Active le xray
self.ObjectBrush.show_in_front = True
else:
self.ProfileBrush.select = True
context.scene.objects.active = self.ProfileBrush
# Active le xray
self.ProfileBrush.show_in_front = True
bpy.ops.object.modifier_add(type='SOLIDIFY')
context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
Selection_Restore(self)
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
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
# Random rotation
if event.type == 'R' and event.value == 'PRESS':
self.RandomRotation = not self.RandomRotation
# Undo
if event.type == 'Z' and event.value == 'PRESS':
if self.ctrl:
if (self.CutMode == LINE) and (self.bDone):
if len(self.mouse_path) > 1:
self.mouse_path[len(self.mouse_path) - 1:] = []
else:
Undo(self)
# Mouse move
if event.type == 'MOUSEMOVE':
if self.ObjectMode or self.ProfileMode:
fac = 50.0
if self.shift:
fac = 500.0
if self.WidthSolidify:
if self.ObjectMode:
bpy.data.objects[self.ObjectBrush.name].modifiers[
"CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.am[0]) / fac
elif self.ProfileMode:
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
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
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
else:
if (self.GridScaleX):
self.gapx += (event.mouse_region_x - self.am[0]) / 50
self.am = event.mouse_region_x, event.mouse_region_y
update_grid(self, context)
return {'RUNNING_MODAL'}
elif (self.GridScaleY):
self.gapy += (event.mouse_region_x - self.am[0]) / 50
self.am = event.mouse_region_x, event.mouse_region_y
update_grid(self, context)
return {'RUNNING_MODAL'}
elif self.ObjectScale:
self.ascale = -(event.mouse_region_x - self.am[0])
self.am = event.mouse_region_x, event.mouse_region_y
if self.ObjectMode:
self.ObjectBrush.scale.x -= float(self.ascale) / 150.0
if self.ObjectBrush.scale.x <= 0.0:
self.ObjectBrush.scale.x = 0.0
self.ObjectBrush.scale.y -= float(self.ascale) / 150.0
if self.ObjectBrush.scale.y <= 0.0:
self.ObjectBrush.scale.y = 0.0
self.ObjectBrush.scale.z -= float(self.ascale) / 150.0
if self.ObjectBrush.scale.z <= 0.0:
self.ObjectBrush.scale.z = 0.0
elif self.ProfileMode:
if self.ProfileBrush is not None:
self.ProfileBrush.scale.x -= float(self.ascale) / 150.0
self.ProfileBrush.scale.y -= float(self.ascale) / 150.0
self.ProfileBrush.scale.z -= float(self.ascale) / 150.0
else:
if self.LMB:
if self.ctrl:
self.aRotZ = - \
((int((event.mouse_region_x - self.xSavMouse) / 10.0) * PI / 4.0) * 25.0)
else:
self.aRotZ -= event.mouse_region_x - self.am[0]
self.ascale = 0.0
self.am = event.mouse_region_x, event.mouse_region_y
else:
vBack = Pick(context, event, self)
if vBack[0] is not None:
self.ShowCursor = True
NormalObject = Vector((0.0, 0.0, 1.0))
qR = RBenVe(NormalObject, vBack[1])
MoveCursor(qR, vBack[0], self)
self.SavCurLoc = vBack[0]
if self.ctrl:
if self.SavMousePos is not None:
xEcart = abs(self.SavMousePos.x - self.SavCurLoc.x)
yEcart = abs(self.SavMousePos.y - self.SavCurLoc.y)
zEcart = abs(self.SavMousePos.z - self.SavCurLoc.z)
if (xEcart > yEcart) and (xEcart > zEcart):
(vBack[0].x, self.SavMousePos.y, self.SavMousePos.z))
if (yEcart > xEcart) and (yEcart > zEcart):
(self.SavMousePos.x, vBack[0].y, self.SavMousePos.z))
if (zEcart > xEcart) and (zEcart > yEcart):
(self.SavMousePos.x, self.SavMousePos.y, vBack[0].z))
else:
self.CurLoc = vBack[0]
else:
self.CurLoc = vBack[0]
else:
if self.bDone:
if self.bDone:
if self.ctrl and (self.CutMode == LINE):
# Incremental mode
coord = list(self.mouse_path[len(self.mouse_path) - 1])
coord[0] = int(
self.mouse_path[len(self.mouse_path) - 2][0] +
int((event.mouse_region_x -
self.mouse_path[len(self.mouse_path) - 2][0]
) / self.Increment) * self.Increment
)
coord[1] = int(
self.mouse_path[len(self.mouse_path) - 2][1] +
int((event.mouse_region_y -
self.mouse_path[len(self.mouse_path) - 2][1]
) / self.Increment) * self.Increment
)
self.mouse_path[len(self.mouse_path) - 1] = tuple(coord)
else:
if len(self.mouse_path) > 0:
self.mouse_path[len(self.mouse_path) -
1] = (event.mouse_region_x, event.mouse_region_y)
else:
# [ALT] press, update position
self.xpos += (event.mouse_region_x - self.last_mouse_region_x)
self.ypos += (event.mouse_region_y - self.last_mouse_region_y)
self.last_mouse_region_x = event.mouse_region_x
self.last_mouse_region_y = event.mouse_region_y
elif event.type == 'LEFTMOUSE' and event.value == 'PRESS':
if self.ObjectMode or self.ProfileMode:
vBack = Pick(context, event, self)
if vBack[0] is not None:
NormalObject = Vector((0.0, 0.0, 1.0))
self.aqR = RBenVe(NormalObject, vBack[1])
self.am = event.mouse_region_x, event.mouse_region_y
self.xSavMouse = event.mouse_region_x
if self.ctrl:
self.nRotZ = int((self.aRotZ / 25.0) / (PI / 4.0))
self.aRotZ = self.nRotZ * (PI / 4.0) * 25.0
self.LMB = True
# LEFTMOUSE
elif event.type == 'LEFTMOUSE' and event.value == 'RELEASE':
if self.ObjectMode or self.ProfileMode:
# Rotation and scale
self.LMB = False
if self.ObjectScale is True:
self.ObjectScale = False
if self.GridScaleX is True:
if self.GridScaleY is True:
self.GridScaleY = False
if self.WidthSolidify:
self.WidthSolidify = False
if self.CarveDepth is True:
if self.BrushDepth is True:
self.BrushDepth = False
else:
if self.ctrl:
Picking(context, event)
else:
if self.CutMode == LINE:
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
self.mouse_path.clear()
self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
else:
self.mouse_path[0] = (event.mouse_region_x, event.mouse_region_y)
self.mouse_path[1] = (event.mouse_region_x, event.mouse_region_y)
self.bDone = True
else:
if self.CutMode != LINE:
# Cut creation
if self.CutMode == RECTANGLE:
CreateCutSquare(self, context)
if self.CutMode == CIRCLE:
CreateCutCircle(self, context)
if self.CutMode == LINE:
CreateCutLine(self, context)
if self.CreateMode:
# Object creation
self.CreateGeometry()
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
# Depth Cursor
context.scene.mesh_carver.DepthCursor = self.snapCursor
context.scene.mesh_carver.OInstanciate = self.Instantiate
context.scene.mesh_carver.ORandom = self.RandomRotation
context.scene.mesh_carver.DontApply = self.DontApply
# if Object mode, set intiale state
if self.ObjectBrush is not None:
self.ObjectBrush.location = self.InitBrushPosition
self.ObjectBrush.scale = self.InitBrushScale
self.ObjectBrush.rotation_quaternion = self.InitBrushQRotation
self.ObjectBrush.rotation_euler = self.InitBrushERotation
self.ObjectBrush.display_type = self.ObjectBrush_DT
self.ObjectBrush.show_in_front = self.XRay
# remove solidify
Selection_Save(self)
self.BrushSolidify = False
bpy.ops.object.select_all(action='TOGGLE')
self.ObjectBrush.select = True
context.scene.objects.active = self.ObjectBrush
bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
Selection_Restore(self)
context.scene.mesh_carver.nProfile = self.nProfil
return {'FINISHED'}
else:
self.Cut()
UndoListUpdate(self)
else:
# Line
self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
# Change circle subdivisions
elif (event.type == 'COMMA' and event.value == 'PRESS') or \
(event.type == context.scene.Key_Subrem and event.value == 'PRESS'):
if self.ProfileMode:
self.nProfil += 1
if self.nProfil >= self.MaxProfil:
self.nProfil = 0
createMeshFromData(self)
# Circle rotation
if self.CutMode == CIRCLE:
if self.ctrl:
self.stepRotation += 1
else:
self.step += 1
if self.step >= len(self.stepAngle):
self.step = len(self.stepAngle) - 1
elif (event.type == 'PERIOD' and event.value == 'PRESS') or \
(event.type == context.scene.Key_Subadd and event.value == 'PRESS'):
if self.ProfileMode:
self.nProfil -= 1
if self.nProfil < 0:
self.nProfil = self.MaxProfil - 1
createMeshFromData(self)
if self.CutMode == CIRCLE:
if self.ctrl:
self.stepRotation -= 1
else:
if self.step > 0:
self.step -= 1
# Quit
elif event.type in {'RIGHTMOUSE', 'ESC'}:
# Depth Cursor
context.scene.mesh_carver.DepthCursor = self.snapCursor
context.scene.mesh_carver.OInstanciate = self.Instantiate
context.scene.mesh_carver.ORandom = self.RandomRotation
context.scene.mesh_carver.DontApply = self.DontApply
# Reset Object
if self.ObjectBrush is not None:
self.ObjectBrush.location = self.InitBrushPosition
self.ObjectBrush.scale = self.InitBrushScale
self.ObjectBrush.rotation_quaternion = self.InitBrushQRotation
self.ObjectBrush.rotation_euler = self.InitBrushERotation
self.ObjectBrush.display_type = self.ObjectBrush_DT
self.ObjectBrush.show_in_front = self.XRay
# Remove solidify modifier
Selection_Save(self)
self.BrushSolidify = False
bpy.ops.object.select_all(action='TOGGLE')
self.ObjectBrush.select = True
context.scene.objects.active = self.ObjectBrush
bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
bpy.ops.object.select_all(action='TOGGLE')
Selection_Restore(self)
Selection_Save_Restore(self)
context.scene.objects.active = self.CurrentActive
context.scene.mesh_carver.nProfile = self.nProfil
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
# Remove Copy Object Brush
if bpy.data.objects.get("CarverBrushCopy") is not None:
brush = bpy.data.objects["CarverBrushCopy"]
self.ObjectBrush.data = bpy.data.meshes[brush.data.name]
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects["CarverBrushCopy"].select = True
bpy.ops.object.delete()
return {'FINISHED'}
return {'RUNNING_MODAL'}
except:
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)")
def cancel(self, context):
# Note: used to prevent memory leaks on quiting Blender while the modal operator
# is still running, gets called on return {"CANCELLED"}
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
def invoke(self, context, event):
if context.area.type != 'VIEW_3D':
self.report({'WARNING'},
"View3D not found or not currently active. Operation Cancelled")
return {'CANCELLED'}
if context.mode == 'EDIT_MESH':
bpy.ops.object.mode_set(mode='OBJECT')
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
# test if some other object types are selected that are not meshes
test_selection = True
for obj in context.selected_objects:
if obj.type != "MESH":
test_selection = False
break
if not test_selection:
self.report({'WARNING'},
"Some selected objects are not of the Mesh type. Operation Cancelled")
return {"CANCELLED"}
# Get default patterns
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,
Vector((o.location.x, o.location.y, o.location.z)),
vertices, faces)
)
self.nProfil = context.scene.mesh_carver.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.mesh_carver.nProfile = 0
# Save selection
self.CurrentSelection = context.selected_objects.copy()
self.CurrentActive = context.active_object
self.SavSel = context.selected_objects.copy()
self.Sav_ac = None
self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
self.mouse_path = [(0, 0), (0, 0)]
self.shift = False
self.ctrl = False
self.alt = False
self.bDone = False
self.DontApply = context.scene.mesh_carver.DontApply
self.Auto_BevelUpdate = True
# Cut type (Rectangle, Circle, Line)
self.CutMode = 0
self.BoolOps = DIFFERENCE
# Circle variables
self.stepAngle = [2, 4, 5, 6, 9, 10, 15, 20, 30, 40, 45, 60, 72, 90]
self.step = 4
self.stepRotation = 0
# Primitives Position
self.xpos = 0
self.ypos = 0
self.InitPosition = False
# Line Increment
self.Increment = 15
# Close polygonal shape
self.Closed = False
# Depth Cursor
self.snapCursor = context.scene.mesh_carver.DepthCursor