Hi jspoh86.
It was an interesting theme, so I tried it.
A library for 'blender' has been released, I used that library.
https://michelanders.blogspot.com/2012/02/3d-convex-hull-in-python.html
https://github.com/varkenvarken/blenderaddons/blob/master/chull.py
Therefore, 'chull.py' needs to be in the same folder as the split file.
#FusionAPI_python test_ConvexHull3D
#Author-kantoku
#Description-新たなスケッチを作成し、ランダムに3Dな点を作成し、3Dな凸包を作成
import adsk.core, adsk.fusion, traceback
import random, os, sys
this_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(this_dir)
#thx-varkenvarken
#chttps://michelanders.blogspot.com/2012/02/3d-convex-hull-in-python.html
#https://github.com/varkenvarken/blenderaddons/blob/master/chull.py
import chull
def run(context):
#Create Point Count
p_count = 100
ui = None
try:
#extension
chull.Vertex.toPnt = ToPoint3d
chull.Face.toSkt = ToSketch
adsk.core.Point3D.toVec = ToCHullVector
adsk.fusion.Sketch.initSurf = InitSurface
#preparation
app = adsk.core.Application.get()
ui = app.userInterface
des = app.activeProduct
root = des.rootComponent
#スケッチと点の作成
skt = root.sketches.add(root.xYConstructionPlane)
skt.name = 'points'
CreateRandomPoint(skt, -10.0, 10.0, p_count)
#time
import time
t = time.time()
#coordinate array
pnts = [p.geometry.asArray() for p in skt.sketchPoints]
del pnts[0] #remove origin point
#edges sketch
skt = root.sketches.add(root.xYConstructionPlane)
skt.name = 'edges'
#ConvexHull
face_count = InitConvexHull(pnts,skt)
#finish
ui.messageBox('Point Count:{}\nface Count:{}\ntime:{:.2f}s'
.format(p_count,face_count,time.time()- t))
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
#ConvexHull
def InitConvexHull(point3d_list,target_sketch):
if len(point3d_list) < 4: return
#hull
pnts = [chull.Vector(ary[0],ary[1],ary[2]) for ary in point3d_list]
hull = chull.Hull(pnts)
#edges
[f.toSkt(target_sketch) for f in hull.faces]
#faces
target_sketch.initSurf()
return len(hull.faces)
#RandomPoint
def CreateRandomPoint(skt, low, upp, count):
pnts = [adsk.core.Point3D.create(
random.uniform(low,upp),random.uniform(low,upp),random.uniform(low,upp))
for dmy in range(count)]
skt_Pnts = skt.sketchPoints
[skt_Pnts.add(pnt) for pnt in pnts]
# --- extension method ---
#chull.Vertex
def ToPoint3d(self):
return adsk.core.Point3D.create(
self.v.x,self.v.y,self.v.z)
#chull.Face
def ToSketch(self, skt):
#Vertex
pnts = skt.sketchPoints
ps = [pnts.add(p.toPnt()) for p in self.vertex]
#edge
lins = skt.sketchCurves.sketchLines
edges =[(ps[0],ps[1]),(ps[1],ps[2]),(ps[2],ps[0])]
[lins.addByTwoPoints(p0,p1) for p0,p1 in edges]
#adsk.core.Point3D
def ToCHullVector(self):
ary = self.asArray()
return chull.Vector(ary[0],ary[1],ary[2])
#adsk.fusion.Sketch
def InitSurface(self,tolerance = 0.001):
if len(self.profiles) < 1:
return
newBodyOpe = adsk.fusion.FeatureOperations.NewBodyFeatureOperation
comp = self.parentComponent
feats = comp.features
objs = adsk.core.ObjectCollection.create()
[objs.add(v) for v in self.profiles]
patches = feats.patchFeatures
pats = patches.add(patches.createInput(objs,newBodyOpe))
objs.clear()
[objs.add(v) for v in pats.bodies]
tol = adsk.core.ValueInput.createByReal(tolerance)
stitches = feats.stitchFeatures
stitches.add(stitches.createInput(objs, tol, newBodyOpe))