blender瞎玩7:自制曲线切割工具(三)
把 曲线切割工具 和 刚性绑定工具 集成在一个插件里了
(1)
新插件名为SKtools
集成了 曲线切割工具 v2.0 和 刚性绑定工具 v1.3
后者在之前的文章“blender瞎玩4:自制刚性绑定插件”里有讲解

安装好后在边栏里找到

操作步骤如下:

当然,也可以用挤出光标来画曲线
你甚至可以在雕刻时切割

(2)
思路:
[1]
因为我不知道怎样实现“绘制完曲线后自动切割”,所以只能分成两步操作。
第一步操作,创建一条“干净”的曲线,准备绘制。
此阶段还要把被切割模型的名字保存起来,这其实是个难点,我试用了 继承,静态变量 都不能实现,这可能是因为blen的context限制导致的。最后用了sf_prop命令实现了
props = bpy.context.scene.sf_props
props.selectobj_name = bpy.context.object.name
# 这两行命令copy了一个老外的代码,我并不懂sf_prop是怎么运作的,总之就是用来保存被切割物体的名字
bpy.ops.curve.primitive_bezier_curve_add(radius=1, enter_editmode=False, location=(0, 0, 0)) # 创建曲线
bpy.ops.object.editmode_toggle()
bpy.ops.curve.delete(type='VERT') # 删除默认曲线点
[2]
第二步操作,自动切割曲线。
此阶段的难点在于,“判断3d视图是否为正交模式”。
这个难点不是因为命令难找——blen有专门的命令来判断——而又是因为context的具体情况难以判断,因而该命令有时根本无法使用。最后我还是试出了正确结果,不过难保不会出现别的问题。
没经验的话你根本不知道现在的context到底是啥,这是个很浪费时间的问题。
解决了判断正交的问题,接下来就简单了
bpy.ops.curve.cyclic_toggle() # 将绘制的曲线闭合
bpy.ops.object.editmode_toggle()
bpy.ops.object.convert(target='MESH') # 曲线转换为网格
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.fill() # 网格转换为平面
[3]
正交模式下很好理解,顺着生成的平面的法线创建一个超长柱体,
然后进行布尔就好了
bpy.ops.mesh.extrude_region_shrink_fatten(TRANSFORM_OT_shrink_fatten={"value":1000}) # 沿法线挤出1000米(是不是有点太长了?还有,你可以通过修改一个小值来达到“挖浅洞”的效果)
bpy.ops.mesh.select_all(action='INVERT')
bpy.ops.transform.translate(value=(0, 0, -1000),orient_type='NORMAL') # 沿柱体另一端移动1000米
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.normals_make_consistent(inside=False) # 统一柱体的法线
bpy.ops.object.editmode_toggle()
[4]
透视模式的切割方法比较难想到,我觉得这是我的一个绝妙idea。
学过透视学的都知道,透视中的一个闭合圆环,沿你的视线向远处无限扫描,得到的是一个锥形,而这个锥形的锥点就是你的视点。于是,我们只要找出视点坐标就可以实现透视切割!
我没有找到直接调出视点坐标的命令,于是姑且借用了摄像机的“活动相机对齐当前视角”命令,但context又导致了一些问题,最后只好做了一些修改
bpy.ops.object.camera_add() # 添加摄影机
camera_name=bpy.context.object.name # 获取摄影机名字
bpy.context.scene.camera = bpy.context.object # 将所选摄影机作为场景摄影机
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
for region in area.regions:
if region.type == 'WINDOW':
override = {'area': area, 'region': region}
bpy.ops.view3d.camera_to_view(override)
# 这段命令也是copy了老外的,普通的“活动相机对齐当前视角”命令并不能使用
cursorloc_zero = bpy.context.scene.cursor.location # 获取游标位置
cursor_loc = bpy.context.object.location # 获取摄影机坐标
bpy.context.scene.cursor.location = cursor_loc # 将游标移到摄影机坐标
remove_obj.select_set(True) # 选择之前曲线生成的平面
bpy.context.view_layer.objects.active = remove_obj # 激活平面
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.region_to_loop() # 选择平面边界
bpy.ops.mesh.extrude_edges_move() # 挤出边界
bpy.ops.mesh.merge(type='CURSOR') # 挤出的边合并到游标,这样就生成了一个锥体
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.normals_make_consistent(inside=False) # 统一法线
bpy.ops.object.editmode_toggle()
bpy.ops.object.origin_set(type='ORIGIN_CURSOR') # 调整椎体原点到游标
bpy.ops.transform.resize(value=(100, 100, 100))
# 锥体放大100倍。这里有个问题,有时候锥体切不干净,这样就会在很远的地方留下一些碎面,这样的话当你焦点集中到物体时视图可能会飞掉,目前没啥好办法。本来是500倍,我改成100倍了
总之,大功告成!
主体命令就是这些
省略的部分请自行参考文章右下角的附件代码
(3)
我想要的命令基本已经都做出来了,我觉得我暂时都不想再研究代码了
附上此插件的代码
仅供参考
glhf















































































