Mesh to Part/ja

Partオブジェクトをメッシュに変換する
Part形状のような上位レベルのオブジェクトを メッシュのような単純なオブジェクトに変換するのは比較的簡単な処理です. Partオブジェクトの全ての面を三角形に変換して、結果の三角形（モザイク）をメッシュ構築に使用すればいいのです：

import Mesh faces = [] shape = FreeCAD.ActiveDocument.ActiveObject.Shape triangles = shape.tessellate(1) # この数値がモザイクの精度を表します for tri in triangles[1]: face = [] for i in range(3): vindex = tri[i] face.append(triangles[0][vindex]) faces.append(face) m = Mesh.Mesh(faces) Mesh.show(m)
 * 1) ドキュメントには一つだけPartオブジェクトが入っているとしましょう

ときたまOpenCascadeが出力する特定の面の三角形が非常にいびつな場合があります. もし面に長方形パラメータ空間があり、穴やトリム曲線が無ければ独自にメッシュを作成することもできます：

import Mesh def makeMeshFromFace(u,v,face): (a,b,c,d)=face.ParameterRange pts=[] for j in range(v): for i in range(u): s=1.0/(u-1)*(i*b+(u-1-i)*a) t=1.0/(v-1)*(j*d+(v-1-j)*c) pts.append(face.valueAt(s,t)) mesh=Mesh.Mesh for j in range(v-1): for i in range(u-1): mesh.addFacet(pts[u*j+i],pts[u*j+i+1],pts[u*(j+1)+i]) mesh.addFacet(pts[u*(j+1)+i],pts[u*j+i+1],pts[u*(j+1)+i+1]) return mesh

メッシュをPartオブジェクトに変換する
メッシュからPartオブジェクトへの変換はCADでの作業でも非常に重要な操作です. 他の人たちからメッシュ形式の3Dデータを受け取ったり、他のアプリケーションからメッシュ形式の3Dデータを出力するというのはよくあることだからです. 自由形状や大きな描画シーンを表現する場合にはメッシュは非常に実用的です. とても軽量だからです. しかしCADでの用途を考えた場合、一般的には三角形ではなく曲線で作成された面やソリッドなど、もっと多くの情報を保持できるより上位のオブジェクトの方が好まれます.

メッシュからこういった（FreeCADのパートモジュールで扱われる様な ）上位オブジェクトへの変換は簡単な処理ではありません. メッシュは数千もの三角形で構成されている場合もありますし（例えば3Dスキャナーによって生成されている場合）、面と同じだけの数のソリッドを持った場合には処理がとんでもなく重くなることも考えられます. 従って多くの場合、変換時に最適化を施す必要があるのです.

FreeCADでは現在、メッシュをPartオブジェクトに変換する二つのメソッドが用意されています. 一つ目は単純なもので何の最適化も施さずに直接変換を行います：

import Mesh,Part mesh = Mesh.createTorus shape = Part.Shape shape.makeShapeFromMesh(mesh.Topology,0.05) # 二つ目の引数は縫い合わせの許容誤差です solid = Part.makeSolid(shape) Part.show(solid)

二つ目のメソッドではメッシュの二つのファセットが作る角度が特定の値を下回る場合にその二つを同一面とみなします. これによってより単純な形状が作成できるのです：

import Mesh,Part,MeshPart faces = [] mesh = App.ActiveDocument.ActiveObject.Mesh segments = mesh.getPlanes(0.00001) # ここではより厳しい許容誤差を使用します for i in segments: if len(i) > 0: # 線分は内部に穴を持つことができます wires = MeshPart.wireFromSegment(mesh, i)     # 外部境界が最大のバウンディングボックスを持つものであると仮定します if len(wires) > 0: ext=None max_length=0 for i in wires: if i.BoundBox.DiagonalLength > max_length: max_length = i.BoundBox.DiagonalLength ext = i        wires.remove(ext) # 内部のワイヤーが全てマークされ、向きが反転されなければなりません. さもなければPart.Faceが失敗します for i in wires: i.reverse # 外部のワイヤーがリストの先頭になっていることを確認してください wires.insert(0, ext) faces.append(Part.Face(wires)) shell=Part.Compound(faces) Part.show(shell)
 * 1) ドキュメントには一つだけMeshオブジェクトが入っているとしましょう
 * 1) solid = Part.Solid(Part.Shell(faces))
 * 2) Part.show(solid)

Sometimes the triangulation of certain faces offered by OpenCascade is quite ugly. If the face has a rectangular parameter space and doesn't contain any holes or other trimming curves you can also create a mesh on your own:

Converting Meshes to Part objects
Converting Meshes to Part objects is an extremely important operation in CAD work, because very often you receive 3D data in mesh format from other people or outputted from other applications. Meshes are very practical to represent free-form geometry and big visual scenes, as it is very lightweight, but for CAD we generally prefer higher-level objects that carry much more information, such as the idea of solid, or faces made of curves instead of triangles.

Converting meshes to those higher-level objects (handled by the Part Module in FreeCAD) is not an easy operation. Meshes can be made of thousands of triangles (for example when generated by a 3D scanner), and having solids made of the same number of faces would be extremely heavy to manipulate. So you generally want to optimize the object when converting.

FreeCAD currently offers two methods to convert Meshes to Part objects. The first method is a simple, direct conversion, without any optimization:

The second method offers the possibility to consider mesh facets coplanar when the angle between them is under a certain value. This allows to build much simpler shapes: (let's assume our document contains one Mesh object)