I have a problem with my blender program, that causes blender to crash and my notebook is heating up quite fast. I think it is, because i want to create too many objects. My goal is to produce a filter media out of (glass) fibres. In order to do that i want to create cylinders, that represent those fibers. They appear in a random spot in a specific area and are then cut, so i have a cube in the dimension 1mmx1mmx0.6mm . For my example i creat fibers in the scale of 1*e12. I can run the program and in small scales it is working, but clicking on the button for the realistic scale causes my problem. So, my question is: Is my CPU too slow 4gb RAM? is blender incapable of creating so many objects and if so, is there a way i can run this program with a regular python compiler, that creates my file? I would like to have that as an .stl-file. Thank you in advance for your help and suggestions, I really appreciate it. Sorry for my bad grammar and for my sloppy commenting in the code which follows:
bl_info = {
"name" : "filter generator",
"author" : "T W",
"version" : (1,0),
"blender" : (2, 78, 0),
"location" : "View3D > Tools",
"description" : "Generate a filter made of cylindrical fibers",
"category" : "Object"}
import bpy
import math
from bpy.props import *
from mathutils import Vector
from random import random
from random import randint
from random import uniform
name = "Fiber "
rectHeight = 0.6 # thickness of the filter media
rectRadius = 1.0 # 1mm² for the surface are
bpy.types.Scene.meanflowporeSize = FloatProperty(
name="Mean Flow Poresize", default=20.0, min=1.0, max=100.0, description="the MFP for the filter media") #MFP for the filter media
bpy.types.Scene.fiberSize = FloatProperty(
name="Fiber Radius", default=5.0, min=5.0, max=24.0, description="radius of the fibers") #Property for the fiber radius
#The Panel GridGen AddOn
class gridGen(bpy.types.Panel):
bl_space_type="VIEW_3D"
bl_region_type="TOOLS"
bl_label="FilterGenerator AddOn"
bl_category="FilterGen"
def draw(self, context):
layout = self.layout
col = layout.column(align=True)
col.label("Filter Generator:")
col.prop(bpy.context.scene, "meanflowporeSize")
col.prop(bpy.context.scene, "fiberSize")
col.operator("filter.button", icon="TEXTURE")
col.operator("remove.button", icon="CANCEL")
mfp = bpy.context.scene.meanflowporeSize
fradius = bpy.context.scene.fiberSize
mfp = mfp*1e-6
fradius = fradius*1e-6
totalPieces = ((rectRadius/(mfp + fradius))*2)*(rectHeight/fradius)
totalCounter = 1
#Progress in percent
def percentagePrint(printName, total):
global totalCounter
percent = (totalCounter/total)*100
print(" "+printName+" "+str(round(percent))+"% complete")
totalCounter+=1
#Button to remove every object in the scene
class removeButton(bpy.types.Operator):
bl_label="Remove everything!"
bl_idname="remove.button"
def execute(self, context):
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_by_type(type='MESH')
bpy.ops.object.delete(use_global=False)
for item in bpy.data.meshes: #Loop for deleting objects in the scene
bpy.data.meshes.remove(item)
print("Removed!")
return{"FINISHED"}
#Button to create the filter
class filterButton(bpy.types.Operator):
bl_label="Filter generation"
bl_idname="filter.button"
def execute(self, context):
global totalCounter
totalCounter = 1
print("---------------------------------------------------------------------------------")
print("Creating Filter")
#create random holes
def check_circle_bounbox( circC, circR, rectC, rectR ):
''' Make sure this circle does not protrude outside the rectangle's bounding box '''
maxX = rectC.x + rectR
minX = rectC.x - rectR
maxY = rectC.y + rectR
minY = rectC.y - rectR
withinX = ( circC.x + circR <= maxX ) and ( circC.x - circR >= minX )
withinY = ( circC.y + circR <= maxY ) and ( circC.y - circR >= minY )
return withinX and withinY
def check_overlap( circles, circC, circR ):
''' Make sure the distance between the current circle's center and all
other circle centers is greater than or equal to the circle's perimeter (2r)
'''
return len([ True for c in circles if ( c - circC ).length >= circR * 2 ]) == len( circles )
circleRadius = fradius
circleCount = ((rectRadius/(mfp + fradius))**2)*(rectHeight/fradius) #the number of fibers is calculated with the MFP, the Fiber radius and the fiber thickness
rectCenter = Vector((0, 0, 0))
circles = []
maxIterations = 10000000000# Set max number of loop iterations to prevent infinite loop
nameCounter = 1
i = 0 # Current loop iteration
while len( circles ) < circleCount and i < maxIterations:
x = rectCenter.x + 2 * rectRadius * random() - rectRadius # x-coordinate
y = rectCenter.y + 2 * rectRadius * random() - rectRadius # y-coordinate
z = abs(rectCenter.z + 2 * rectRadius * random() - rectRadius) #z-cootdinate always positive via abs()
circC = Vector((x, y, z ))
#no overlapping radius is checked
if check_circle_bounbox( circC, circleRadius, rectCenter, rectRadius ) and check_overlap( circles, circC, circleRadius ):
circles.append( circC )
i += 1
for c in circles:
rot_x = uniform(0, 2*math.pi) #rotation around x-axis
rot_y = uniform(0, 2*math.pi) #rotation around y-axis
rot_z = uniform(0, 2*math.pi) #rotation around z-axis
#creating a high resolution cylinder
bpy.ops.mesh.primitive_cylinder_add(vertices=256, radius = circleRadius, depth= 20, location = c, rotation=(rot_x, rot_y, rot_z))
currentPiece = bpy.context.active_object
currentPiece.name = name+str(nameCounter)
nameCounter += 1
percentagePrint("Grid", totalPieces)
#combine all objects into one
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.join()
#deselecting and sctivating the object
bpy.ops.object.select_all(action='DESELECT')
bpy.context.scene.objects.active = bpy.data.objects[currentPiece.name]
#cutting out the square that will be the final object in 6 bisections
#biscet 1 on x=.5
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.mesh.bisect(plane_co=(.5, 0, 0), plane_no=(1, 0, 0), use_fill=True, clear_inner=False, clear_outer=True, threshold=0.0001, xstart=0, xend=0, ystart=0, yend=0, cursor=1002)
#bisect 2 on x=-.5
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(-.5, 0, 0), plane_no=(-1, 0, 0), use_fill=True, clear_inner=False, clear_outer=True, threshold=0.0001, xstart=0, xend=0, ystart=0, yend=0, cursor=1002)
#bisect 3 on y=.5
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, .5, 0), plane_no=(0, 1, 0), use_fill=True, clear_inner=False, clear_outer=True, threshold=0.0001, xstart=0, xend=0, ystart=0, yend=0, cursor=1002)
#bisect 4 on y=-.5
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, -.5, 0), plane_no=(0, -1, 0), use_fill=True, clear_inner=False, clear_outer=True, threshold=0.0001, xstart=0, xend=0, ystart=0, yend=0, cursor=1002)
#bisect 5 on z=.6
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 0, .6+circleRadius/2), plane_no=(0, 0, 1), use_fill=True, clear_inner=False, clear_outer=True, threshold=0.0001, xstart=0, xend=0, ystart=0, yend=0, cursor=1002)
#bisect 6 on z=-circleRadius/2
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 0, circleRadius/2*-1), plane_no=(0, 0, -1), use_fill=True, clear_inner=False, clear_outer=True, threshold=0.0001, xstart=0, xend=0, ystart=0, yend=0, cursor=1002)
#going back to object mode
bpy.ops.object.mode_set(mode = 'OBJECT')
print("Filter created")
return{"FINISHED"}
#REGISTER
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()