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:
Diffstat (limited to 'object_fracture/fracture_ops.py')
-rw-r--r--object_fracture/fracture_ops.py490
1 files changed, 0 insertions, 490 deletions
diff --git a/object_fracture/fracture_ops.py b/object_fracture/fracture_ops.py
deleted file mode 100644
index 19cd4bce..00000000
--- a/object_fracture/fracture_ops.py
+++ /dev/null
@@ -1,490 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-import bpy
-from bpy.props import *
-import os
-import random
-import mathutils
-from mathutils import *
-
-
-def create_cutter(context, crack_type, scale, roughness):
- ncuts = 12
- if crack_type == 'FLAT' or crack_type == 'FLAT_ROUGH':
- bpy.ops.mesh.primitive_cube_add(
- view_align=False,
- enter_editmode=False,
- location=(0, 0, 0),
- rotation=(0, 0, 0),
- layers=(True, False, False, False,
- False, False, False, False,
- False, False, False, False,
- False, False, False, False,
- False, False, False, False))
-
- for v in context.scene.objects.active.data.vertices:
- v.co[0] += 1
- v.co[0] *= scale
- v.co[1] *= scale
- v.co[2] *= scale
-
- bpy.ops.object.editmode_toggle()
- bpy.ops.mesh.faces_shade_smooth()
- bpy.ops.uv.reset()
-
- if crack_type == 'FLAT_ROUGH':
- bpy.ops.mesh.subdivide(
- number_cuts=ncuts,
- fractal=roughness * 7 * scale,
- smoothness=0)
-
- bpy.ops.mesh.vertices_smooth(repeat=5)
-
- bpy.ops.object.editmode_toggle()
-
- if crack_type == 'SPHERE' or crack_type == 'SPHERE_ROUGH':
- bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4,
- size=1,
- view_align=False,
- enter_editmode=False,
- location=(0, 0, 0),
- rotation=(0, 0, 0),
- layers=(True, False, False, False,
- False, False, False, False,
- False, False, False, False,
- False, False, False, False,
- False, False, False, False,
- False, False, False, False,
- False, False, False, False,
- False, False, False, False))
-
- bpy.ops.object.editmode_toggle()
- bpy.ops.mesh.faces_shade_smooth()
- bpy.ops.uv.smart_project(angle_limit=66, island_margin=0)
-
- bpy.ops.object.editmode_toggle()
- for v in context.scene.objects.active.data.vertices:
- v.co[0] += 1
- v.co[0] *= scale
- v.co[1] *= scale
- v.co[2] *= scale
-
- if crack_type == 'SPHERE_ROUGH':
- for v in context.scene.objects.active.data.vertices:
- v.co[0] += roughness * scale * 0.2 * (random.random() - 0.5)
- v.co[1] += roughness * scale * 0.1 * (random.random() - 0.5)
- v.co[2] += roughness * scale * 0.1 * (random.random() - 0.5)
-
- bpy.context.scene.objects.active.select = True
-
- '''
- # Adding fracture material
- # @todo Doesn't work at all yet.
- sce = bpy.context.scene
- if bpy.data.materials.get('fracture')==None:
- bpy.ops.material.new()
- bpy.ops.object.material_slot_add()
- sce.objects.active.material_slots[0].material.name = 'fracture'
- else:
- bpy.ops.object.material_slot_add()
- sce.objects.active.material_slots[0].material
- = bpy.data.materials['fracture']
- '''
-
-
-#UNWRAP
-def getsizefrommesh(ob):
- bb = ob.bound_box
- return (
- bb[5][0] - bb[0][0],
- bb[3][1] - bb[0][1],
- bb[1][2] - bb[0][2])
-
-
-def getIslands(shard):
- sm = shard.data
- islands = []
- vgroups = []
- fgroups = []
-
- vgi = []
- for v in sm.vertices:
- vgi.append(-1)
-
- gindex = 0
- for i in range(len(vgi)):
- if vgi[i] == -1:
- gproc = [i]
- vgroups.append([i])
- fgroups.append([])
-
- while len(gproc) > 0:
- i = gproc.pop(0)
- for f in sm.faces:
- #if i in f.vertices:
- for v in f.vertices:
- if v == i:
- for v1 in f.vertices:
- if vgi[v1] == -1:
- vgi[v1] = gindex
- vgroups[gindex].append(v1)
- gproc.append(v1)
-
- fgroups[gindex].append(f.index)
-
- gindex += 1
-
- #print( gindex)
-
- if gindex == 1:
- shards = [shard]
-
- else:
- shards = []
- for gi in range(0, gindex):
- bpy.ops.object.select_all(action='DESELECT')
- bpy.context.scene.objects.active = shard
- shard.select = True
- bpy.ops.object.duplicate(linked=False, mode=1)
- a = bpy.context.scene.objects.active
- sm = a.data
- print (a.name)
-
- bpy.ops.object.editmode_toggle()
- bpy.ops.mesh.select_all(action='DESELECT')
- bpy.ops.object.editmode_toggle()
-
- for x in range(len(sm.vertices) - 1, -1, -1):
- if vgi[x] != gi:
- #print('getIslands: selecting')
- #print('getIslands: ' + str(x))
- a.data.vertices[x].select = True
-
- print(bpy.context.scene.objects.active.name)
-
- bpy.ops.object.editmode_toggle()
- bpy.ops.mesh.delete()
- bpy.ops.object.editmode_toggle()
-
- bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
-
- shards.append(a)
-
- bpy.context.scene.objects.unlink(shard)
-
- return shards
-
-
-def boolop(ob, cutter, op):
- sce = bpy.context.scene
-
- fault = 0
- new_shards = []
-
- sizex, sizey, sizez = getsizefrommesh(ob)
- gsize = sizex + sizey + sizez
-
- bpy.ops.object.select_all()
- ob.select = True
- sce.objects.active = ob
- cutter.select = False
-
- bpy.ops.object.modifier_add(type='BOOLEAN')
- a = sce.objects.active
- a.modifiers['Boolean'].object = cutter
- a.modifiers['Boolean'].operation = op
-
- nmesh = a.create_mesh(sce, apply_modifiers=True, settings='PREVIEW')
-
- if len(nmesh.vertices) > 0:
- a.modifiers.remove(a.modifiers['Boolean'])
- bpy.ops.object.duplicate(linked=False, mode=1)
-
- new_shard = sce.objects.active
- new_shard.data = nmesh
- #scene.objects.link(new_shard)
-
- new_shard.location = a.location
- bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
-
- sizex, sizey, sizez = getsizefrommesh(new_shard)
- gsize2 = sizex + sizey + sizez
-
- if gsize2 > gsize * 1.01: # Size check
- print (gsize2, gsize, ob.name, cutter.name)
- fault = 1
- #print ('boolop: sizeerror')
-
- elif min(nmesh.edge_face_count) < 2: # Manifold check
- fault = 1
-
- if not fault:
- new_shards = getIslands(new_shard)
-
- else:
- sce.objects.unlink(new_shard)
-
- else:
- fault = 2
-
- return fault, new_shards
-
-
-def splitobject(context, ob, crack_type, roughness):
- scene = context.scene
-
- size = getsizefrommesh(ob)
- shards = []
- scale = max(size) * 1.3
-
- create_cutter(context, crack_type, scale, roughness)
- cutter = context.active_object
- cutter.location = ob.location
-
- cutter.location[0] += random.random() * size[0] * 0.1
- cutter.location[1] += random.random() * size[1] * 0.1
- cutter.location[2] += random.random() * size[2] * 0.1
- cutter.rotation_euler = [
- random.random() * 5000.0,
- random.random() * 5000.0,
- random.random() * 5000.0]
-
- scene.objects.active = ob
- operations = ['INTERSECT', 'DIFFERENCE']
-
- for op in operations:
- fault, newshards = boolop(ob, cutter, op)
-
- shards.extend(newshards)
- if fault > 0:
- # Delete all shards in case of fault from previous operation.
- for s in shards:
- scene.objects.unlink(s)
-
- scene.objects.unlink(cutter)
- #print('splitobject: fault')
-
- return [ob]
-
- if shards[0] != ob:
- bpy.context.scene.objects.unlink(ob)
-
- bpy.context.scene.objects.unlink(cutter)
-
- return shards
-
-
-def fracture_basic(context, nshards, crack_type, roughness):
- tobesplit = []
- shards = []
-
- for ob in context.scene.objects:
- if ob.select:
- tobesplit.append(ob)
-
- i = 1 # I counts shards, starts with 1 - the original object
- iter = 0 # counts iterations, to prevent eternal loops in case
- # of boolean faults
-
- maxshards = nshards * len(tobesplit)
-
- while i < maxshards and len(tobesplit) > 0 and iter < maxshards * 10:
- ob = tobesplit.pop(0)
- newshards = splitobject(context, ob, crack_type, roughness)
-
- tobesplit.extend(newshards)
-
- if len(newshards) > 1:
- shards.extend(newshards)
- #shards.remove(ob)
-
- i += (len(newshards) - 1)
-
- #print('fracture_basic: ' + str(i))
- #print('fracture_basic: lenobs', len(context.scene.objects))
-
- iter += 1
-
-
-def fracture_group(context, group):
- tobesplit = []
- shards = []
-
- for ob in context.scene.objects:
- if (ob.select
- and (len(ob.users_group) == 0 or ob.users_group[0].name != group)):
- tobesplit.append(ob)
-
- cutters = bpy.data.groups[group].objects
-
- # @todo This can be optimized.
- # Avoid booleans on obs where bbox doesn't intersect.
- i = 0
- for ob in tobesplit:
- for cutter in cutters:
- fault, newshards = boolop(ob, cutter, 'INTERSECT')
- shards.extend(newshards)
-
- if fault == 1:
- # Delete all shards in case of fault from previous operation.
- for s in shards:
- bpy.context.scene.objects.unlink(s)
-
- #print('fracture_group: fault')
- #print('fracture_group: ' + str(i))
-
- return
-
- i += 1
-
-
-class FractureSimple(bpy.types.Operator):
- '''Split object with boolean operations for simulation, uses an object.'''
- bl_idname = "object.fracture_simple"
- bl_label = "Fracture Object"
- bl_options = {'REGISTER', 'UNDO'}
-
- exe = BoolProperty(name="Execute",
- description="If it shall actually run, for optimal performance...",
- default=False)
-
- hierarchy = BoolProperty(name="Generate hierarchy",
- description="Hierarchy is usefull for simulation of objects" \
- " breaking in motion.",
- default=False)
-
- nshards = IntProperty(name="Number of shards",
- description="Number of shards the object should be split into.",
- min=2,
- default=5)
-
- crack_type = EnumProperty(name='Crack type',
- items=(
- ('FLAT', 'Flat', 'a'),
- ('FLAT_ROUGH', 'Flat rough', 'a'),
- ('SPHERE', 'Spherical', 'a'),
- ('SPHERE_ROUGH', 'Spherical rough', 'a')),
- description='Look of the fracture surface',
- default='FLAT')
-
- roughness = FloatProperty(name="Roughness",
- description="Roughness of the fracture surface",
- min=0.0,
- max=3.0,
- default=0.5)
-
- def execute(self, context):
- #getIslands(context.object)
- if self.exe:
- fracture_basic(context,
- self.nshards,
- self.crack_type,
- self.roughness)
-
- return {'FINISHED'}
-
-
-class FractureGroup(bpy.types.Operator):
- '''Split object with boolean operations for simulation, uses a group.'''
- bl_idname = "object.fracture_group"
- bl_label = "Fracture Object (Group)"
- bl_options = {'REGISTER', 'UNDO'}
-
- exe = BoolProperty(name="Execute",
- description="If it shall actually run, for optimal performance...",
- default=False)
-
- e = []
- for i, g in enumerate(bpy.data.groups):
- e.append((g.name, g.name, ''))
-
- group = EnumProperty(name='Group (hit F8 to refresh list)',
- items=e,
- description='Specify the group used for fracturing')
-
- def execute(self, context):
- #getIslands(context.object)
-
- if self.properties.exe:
- fracture_group(context, self.properties.group)
-
- return {'FINISHED'}
-
-
-#####################################################################
-# Import Functions
-
-def import_object(obname):
- opath = "//data.blend\\Object\\" + obname
- s = os.sep
- dpath = bpy.utils.script_paths()[0] + \
- '%saddons%sobject_fracture%sdata.blend\\Object\\' % (s, s, s)
-
- # DEBUG
- #print('import_object: ' + opath)
-
- bpy.ops.wm.link_append(
- filepath=opath,
- filename=obname,
- directory=dpath,
- filemode=1,
- link=False,
- autoselect=True,
- active_layer=True,
- instance_groups=True,
- relative_path=True)
-
- for ob in bpy.context.selected_objects:
- ob.location = bpy.context.scene.cursor_location
-
-
-class ImportFractureRecorder(bpy.types.Operator):
- '''Imports a rigidbody recorder'''
- bl_idname = "object.import_fracture_recorder"
- bl_label = "Add Rigidbody Recorder (Fracture)"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- import_object("RECORDER")
-
- return {'FINISHED'}
-
-
-class ImportFractureBomb(bpy.types.Operator):
- '''Import a bomb'''
- bl_idname = "object.import_fracture_bomb"
- bl_label = "Add Bomb (Fracture)"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- import_object("BOMB")
-
- return {'FINISHED'}
-
-
-class ImportFractureProjectile(bpy.types.Operator, ):
- '''Imports a projectile'''
- bl_idname = "object.import_fracture_projectile"
- bl_label = "Add Projectile (Fracture)"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- import_object("PROJECTILE")
-
- return {'FINISHED'}