立て続けですが、こちらの続きです。
メッシュの六角形分割に挑む2 - C#ATIA
前回の物よりこちらを先に取り組んでいたのですが、悩みまくりました。
通常のボディは大まかな大きさを把握する為のBoundingBoxが簡単に
取得出来るのですが、メッシュボディは出来ないです。
分割する為には、どうしても大まかな大きさを把握したいため
BoundingBoxが欲しかったんです。その為に作りました。
但し、こちらのBoundingBox3Dでは無く
Fusion 360 Help
任意の方向を指定できるOrientedBoundingBox3Dです。
Fusion 360 Help
import statistics def getOrientedBoundingBox_Mesh( mesh: adsk.fusion.MeshBody, axisX: adsk.core.Vector3D, axisZ: adsk.core.Vector3D) -> adsk.core.OrientedBoundingBox3D: # vecter - Zが優先 if axisX.isParallelTo(axisZ): return axisY: adsk.core.Vector3D = axisZ.crossProduct(axisX) axisX = axisZ.crossProduct(axisY) axisX.normalize() axisY.normalize() axisZ.normalize() p: adsk.core.Point3D pnts = [p for p in mesh.displayMesh.nodeCoordinates] # temp center x = statistics.mean([p.x for p in pnts]) y = statistics.mean([p.y for p in pnts]) z = statistics.mean([p.z for p in pnts]) center: adsk.core.Point3D = adsk.core.Point3D.create(x, y, z) # matrix mat: adsk.core.Matrix3D = adsk.core.Matrix3D.create() mat.setWithCoordinateSystem( center, axisX, axisY, axisZ ) mat.invert() # transform for p in pnts: p.transformBy(mat) bound = adsk.core.BoundingBox3D.create(pnts[0], pnts[1]) for p in pnts[2:]: bound.expand(p) pntMin :adsk.core.Point3D = bound.minPoint pntMax :adsk.core.Point3D = bound.maxPoint pntMid: adsk.core.Point3D = adsk.core.Point3D.create( (pntMin.x + pntMax.x) * 0.5, (pntMin.y + pntMax.y) * 0.5, (pntMin.z + pntMax.z) * 0.5 ) width = abs(pntMax.x) + abs(pntMin.x) length = abs(pntMax.y) + abs(pntMin.y) height = abs(pntMax.z) + abs(pntMin.z) mat.invert() pntMid.transformBy(mat) bBox = adsk.core.OrientedBoundingBox3D.create( pntMid, axisY, axisX, length, width, height, ) return bBox
パラメータはメッシュボディとX方向とZ方向です。
XとYじゃないのは僕の都合です。
本来XとZは直交していなければいけないのですが、内部的に
直交するようにしてます。その際、Z方向が優先です。
それも僕の都合です。
その為、X方向とZ方向は平行なベクトルじゃなきゃOKとしています。
出来上がりはこんな感じで、座標系の方向には依存しません。