Hi,
Is there any way to create a convex hull by using Python APIs in Fusion 360?
Thanks,
Ha-An
Solved! Go to Solution.
Solved by BrianEkins. Go to Solution.
There's not anything built into the API, but you should be able to either write your own math or find an existing library that would create the set of points that represent a convex hull. Then it depends on whether it's 2D or 3D and what you're going to use it for that would define what you do next. For example, if it's 2D you probably want to draw the shape in a sketch. If it's 3D you can create custom graphics to display the triangles.
It would be a bit painful to create a solid body of the mesh because you would need to draw the outline of each face as sketch geometry and then create a patch feature, and then finally you could stitch them all together. If there are many polygons, it will take a very long time and would likely fail.
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))
Hi jspoh86.
It was an interesting theme, so I tried it.
A library for 'blender' has been released, I used that library.
https://github.com/varkenvarken/blenderaddons/blob/master/chull.py
Therefore, 'chull.py' needs to be in the same folder as the split file.
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 #RandomPoint 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))
Hi jspoh86.
I made a sample here.
(I got an error and I could not write it well.)
http://kantoku.hatenablog.com/entry/2018/09/21/160153
This library is necessary.
Please prepare it in the same folder as the script file.
https://michelanders.blogspot.com/2012/02/3d-convex-hull-in-python.html
https://github.com/varkenvarken/blenderaddons/blob/master/chull.py