0
$\begingroup$

I have a strange problem with a python script. I am generating an object with holes cut out of it in specific locations. The script works well for all of it except for 1 specific and weird problem. I run a loop for a boolean difference operation and it works for every hole except for my first hole.

I've gone back and stopped the code before the first boolean cut occurs by adding an extra editmode toggle (to break it) and tried to manually add the difference boolean to generate the hole and it doesn't want to work manually either. I have no idea what is going on---especially since it works on all the other holes and also since it won't even seem to let me do it manually.

My code is attached below. I have no idea why it won't build my first hole--all assistance will be greatly appreciated.

Thanks!

enter image description here

#imports
import bpy
import numpy as np
import math
from array import *

#Definitions
# Calculates Rotation Matrix given euler angles.  Need angle in radians.
def eulerAnglesToRotationMatrix(theta) :

    R_x = np.array([[1,         0,                  0                   ],
                    [0,         math.cos(theta[0]), -math.sin(theta[0]) ],
                    [0,         math.sin(theta[0]), math.cos(theta[0])  ]
                    ])



    R_y = np.array([[math.cos(theta[1]),    0,      math.sin(theta[1])  ],
                    [0,                     1,      0                   ],
                    [-math.sin(theta[1]),   0,      math.cos(theta[1])  ]
                    ])

    R_z = np.array([[math.cos(theta[2]),    -math.sin(theta[2]),    0],
                    [math.sin(theta[2]),    math.cos(theta[2]),     0],
                    [0,                     0,                      1]
                    ])
    R = np.dot(R_z, np.dot( R_y, R_x ))
    return R

#Variables
hemiRadius = 0.3
hemiSegments = 25
hemiRingCount = 25
hemiLocation = (0, 0, 0)
dropRadius = 0.03
dropVertices = 16

#Variables for hole placement.
maxYaw = (75) #degrees
maxPitch = (65) #degrees
radius = hemiRadius #degrees

#Sphere
bpy.ops.mesh.primitive_uv_sphere_add(segments = hemiSegments, ring_count = hemiRingCount, size=hemiRadius, view_align=False, enter_editmode=True, location=hemiLocation)

#Cut sphere in half vertically in the correct plane
#Change plane_co("X", 0.3, 0) to '0' to make it a perfect half of a sphere, increase 'X' to allow more of the other half of the sphere to be present
bpy.ops.mesh.bisect(plane_co=(0.03, 0.3, 0), plane_no=(0.999995, 0.003263, -0), clear_inner=False, clear_outer=True, xstart=681, xend=683, ystart=715, yend=102)

#add subdivide meshes 
bpy.ops.mesh.select_all(action='TOGGLE')
bpy.ops.mesh.select_all(action='TOGGLE')
bpy.ops.mesh.subdivide(smoothness=0)

#increase thickness
bpy.ops.object.modifier_remove(modifier="Solidify")
bpy.ops.object.modifier_add(type='SOLIDIFY')
bpy.context.object.modifiers["Solidify"].offset = 0
bpy.context.object.modifiers["Solidify"].thickness = 0.02
bpy.ops.object.editmode_toggle()
bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Solidify")
bpy.ops.object.editmode_toggle()

###At this point, Hemisphere is built

#Conversion degrees into radians
maxYaw = (maxYaw/180.0)*np.pi #now in radians
maxPitch = (maxPitch/180.0)*np.pi #now in radians

#locations of holes
rollPointsDeg = [[0, 0, 0],                #0 center
                [0, maxPitch, 0],          #1 top mid
                [0, maxPitch, maxYaw],     #2 top left
                [0, 0, maxYaw],            #3 mid left
                [0, -maxPitch, maxYaw],    #4 bot left
                [0, -maxPitch, 0],         #5 bot mid
                [0, -maxPitch, -maxYaw],   #6 bot rig
                [0, 0, -maxYaw],           #7 mid rig 
                [0, maxPitch, -maxYaw]]    #8 top rig

#location of holes
rollPoints =    [[-radius, 0, 0],   #0
                 [0, 0, 0],         #1        
                 [0, 0, 0],         #2  
                 [0, 0, 0],         #3
                 [0, 0, 0],         #4
                 [0, 0, 0],         #5
                 [0, 0, 0],         #6
                 [0, 0, 0],         #7
                 [0, 0, 0]]         #8

#the rotational matrix variable
rotMat = np.array([[0,0,0],[0,0,0],[0,0,0]])

#Rotation Matrix Loop
i=1
while i < 9:
    rotMat = eulerAnglesToRotationMatrix(rollPointsDeg[i]) #converts the rotMat into the rotational matrix
    rollPoints[i] = np.dot (rotMat, rollPoints[0])  #dot product of rotMatrix and rollPoints[0]
    i += 1

#comment out this line if getting errors from blender about <<operation cannot performe in edit mode
bpy.ops.object.editmode_toggle()

#Loop adding circles in precise location and orientation
k = 0
while k < 9:
    bpy.context.scene.cursor_location = (0.0, 0.0, 0.0)
    bpy.ops.object.origin_set(type='ORIGIN_CURSOR')

    exitStatus = bpy.ops.mesh.primitive_circle_add(vertices=16, radius=0.03)
    scj = bpy.context.scene

# The added circle will be the active object after it is created
    ob = bpy.context.object
    me = ob.data

# If you want to move your object, simply set its location thus:
    ob.location = ( rollPoints[k][0], rollPoints[k][1],rollPoints[k][2] )    

# And you can rotate the object the same way
# Note that you need to use radians rather than angles here
    ob.rotation_euler = (0*(np.pi/2), (np.pi/2) + rollPointsDeg[k][1], rollPointsDeg[k][2])  

#Now apply shrinkwrap after orientations are correct
    bpy.ops.object.modifier_add(type='SHRINKWRAP')
    bpy.context.object.modifiers["Shrinkwrap"].target = bpy.data.objects["Sphere"]
    bpy.context.object.modifiers["Shrinkwrap"].wrap_method = 'PROJECT'
    bpy.context.object.modifiers["Shrinkwrap"].use_project_z = True
    bpy.context.object.modifiers["Shrinkwrap"].use_negative_direction = True
    bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Shrinkwrap")

#weird prep-stuff needed to make boolean operation work correctly:
#moving circles within the sphere to allow proper difference boolean operation

    bpy.ops.object.editmode_toggle()

    bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(0, 0, 0.09883128), "constraint_axis":(False, False, True), "constraint_orientation":'LOCAL', "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, "use_accurate":False})

    bpy.ops.object.editmode_toggle()

    bpy.ops.transform.translate(value=(9.31323e-010, -2.09548e-009, -0.0348931), constraint_axis=(False, False, True), constraint_orientation='LOCAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)


#boolean difference operation 

    hemmy = bpy.data.objects['Sphere']
    bpy.context.scene.objects.active = hemmy

    bpy.ops.object.select_all(action='TOGGLE')
    bpy.ops.object.select_all(action='TOGGLE')

    bpy.ops.object.modifier_apply(modifier="Auto Boolean")
    bpy.ops.btool.auto_difference(solver='BMESH')

    k +=1  
$\endgroup$
  • $\begingroup$ blender.stackexchange.com/questions/3212/… $\endgroup$ – Duarte Farrajota Ramos Apr 29 at 15:09
  • $\begingroup$ blender.stackexchange.com/questions/34781/… $\endgroup$ – Duarte Farrajota Ramos Apr 29 at 15:10
  • $\begingroup$ @DuarteFarrajotaRamos: thank you for the links. I'll review them and post an update on my progress thereafter. $\endgroup$ – user70711 Apr 30 at 6:43
  • $\begingroup$ I rewrote my code such that cylinders were generated instead of circles. This simplified the code and I was able to then perform the difference boolean operation on the cylinders and it worked. Looking through the example links you posted helped me do this. So, I was able to make my model correctly, HOWEVER, I still haven't figured out why the boolean operation would not work correctly...on only one of my circles. I would like to know as it will help me learn and develop my skills further. If anyone has ideas, please don't hesitate to comment. Thanks! $\endgroup$ – user70711 Apr 30 at 8:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.