iCAD SXのボディをワイヤに変換

2024/04/06 categories:iCAD SX| tags:iCAD SX|Python|

iCAD SXの3D上のボディに含まれるエッジをワイヤとして作成するプログラムを作ってみました。

パーツの選択

sxnet.SxSys.getEntListでCAD上で選択したパーツを取得します。引数にsxnet.SxSys.ENTMODE_PARTを渡すことで、CAD上で選択できる要素をパーツに限定しています。選択せずにGOをした場合はトップパーツを処理するようにしています。

    wf = sxnet.SxWF.getActive()
    if wf is None:
        return
    
    entparts = sxnet.SxSys.getEntList(sxnet.SxSys.ENTMODE_PART)

    if entparts is None:
        part_to_edge(wf, None)
    else:
        for entpart in entparts:
            part_to_edge(wf, entpart)

ボディからエッジを取得

3D上のボディに含まれるエッジをワイヤとして作成するために、まずは3D上に含まれるボディを取得します。パーツを選択していなければSxWF.getTopSegListでトップパーツの要素を取得します。パーツを選択していれば、entpart.getEntList()でパーツに含まれる要素を取得しています。

取得した要素にはボディ以外の要素も含まれるので、if seg.Type in _body_types:でボディの要素のみに限定しています。ボディとして扱うタイプはbody_types()に書かれている要素です。

そのボディの要素からSxEntSeg.getEdgeListでエッジを取得して、エッジから線、円、円弧を取得しています。それ以外のエッジもあるようですが、そのような要素からはジオメトリを取得できないようなので、線、円、円弧のみを取得しています。取得したエッジのジオメトリは種類ごとに、lines, circles, arcsに入れています。

def part_to_edge(wf, entpart):
    if entpart is None:
        seglist = wf.getTopSegList(offset=0, num=0, visi=True, layer=True, type=True)
    else:
        seglist = entpart.getEntList()
        
    if seglist is None:
        return

    bodies, _body_types = [], body_types()
    for seg in seglist:
        if seg.Type in _body_types:
            bodies.append(seg)
    
    edges = sxnet.SxEntSeg.getEdgeList(bodies)
    if edges is None:
        return
    
    edges = sum([ list(edges2) for edges2 in edges ], [])
    geoms = sxnet.SxEdge.getGeomList(edges)
    
    lines, circles, arcs = [], [], []
    for geom in geoms:
        if geom.type == sxnet.SxGeom.TYPE_LINE3D:
            lines.append(geom)
        elif geom.type == sxnet.SxGeom.TYPE_CIRCLE3D:
            circles.append(geom)
        elif geom.type == sxnet.SxGeom.TYPE_ARC3D:
            arcs.append(geom)
            
def body_types():
    return [
        sxnet.SxEntSeg.SEGTYPE_BOX,     # 直方体  
        sxnet.SxEntSeg.SEGTYPE_CAP,     # キャップ  
        sxnet.SxEntSeg.SEGTYPE_CONE,    # 円錐/円錐台  
        sxnet.SxEntSeg.SEGTYPE_CYL,     # 円柱  
        sxnet.SxEntSeg.SEGTYPE_EPRJ,    # 拡張投影体  
        sxnet.SxEntSeg.SEGTYPE_FCSOLID, # F.C.ソリッド  
        sxnet.SxEntSeg.SEGTYPE_LPRJ,    # 偏心投影体  
        sxnet.SxEntSeg.SEGTYPE_PCON,    # 正多角錐/正多角錐台  
        sxnet.SxEntSeg.SEGTYPE_PCYL,    # 正多角柱  
        sxnet.SxEntSeg.SEGTYPE_PRJT,    # 投影体  
        sxnet.SxEntSeg.SEGTYPE_PRSM,    # 多角錐/多角錐台  
        sxnet.SxEntSeg.SEGTYPE_ROT,     # 回転体  
        sxnet.SxEntSeg.SEGTYPE_SOLID,   # ソリッド  
        sxnet.SxEntSeg.SEGTYPE_SPHR,    # 球/部分球  
        sxnet.SxEntSeg.SEGTYPE_TORUS    # トーラス  
    ]

ジオメトリからワイヤを作成

ジオメトリの種類に応じてワイヤを作成します。作成したワイヤは「エッジ」というパーツ名のパーツを作成して、そのパーツにワイヤを移動しています。トップパーツにパーツを作成するときはsetActiveTopでトップパーツをアクティブにしてから、sxnet.SxEntPart.createでパーツを作成してます。選択したパーツの子部品としてパーツを作成するときは、entpart.setActive(False)でパーツを入力パーツにして、entpart.create(‘エッジ’)でパーツを作成して、created_part.add(created)でワイヤを追加しています。

    for line in lines:
        created_line = sxnet.SxEntSeg.createLine3D(line.sp, line.vec, line.leng)
        created.append(created_line)

    for circle in circles:
        created_circle = sxnet.SxEntSeg.createCircle3D(circle.cp, circle.radius, circle.axis)
        created.append(created_circle)

    for arc in arcs:
        created_arc = sxnet.SxEntSeg.createArc3D(arc.cp, arc.radius*2.0, arc.axis, arc.vecs, arc.vece)
        created.append(created_arc)

    if len(created) == 0:
        return
    
    if entpart is None:
        sxnet.SxEntPart.setActiveTop()
        sxnet.SxEntPart.create(created, 'エッジ', '', 1)
    else:
        entpart.setActive(False)
        created_part = entpart.create('エッジ')
        created_part.add(created)

実行の様子

プログラムを実行すると、ボディからワイヤを作成して、パーツに入れます。

実行ファイル

body_to_edges.exeを実行すると処理できます。

body_to_edges.exeをダウンロード

Pythonコード

import clr
import os
clr.AddReference( os.getenv('ICADDIR') + '\\bin\\sxnet.dll' )
import sxnet


def main():

    wf = sxnet.SxWF.getActive()
    if wf is None:
        return
    
    entparts = sxnet.SxSys.getEntList(sxnet.SxSys.ENTMODE_PART)

    if entparts is None:
        part_to_edge(wf, None)
    else:
        for entpart in entparts:
            part_to_edge(wf, entpart)

    sxnet.SxEntPart.setActiveTop()

def part_to_edge(wf, entpart):
    if entpart is None:
        seglist = wf.getTopSegList(offset=0, num=0, visi=True, layer=True, type=True)
    else:
        seglist = entpart.getEntList()
        
    if seglist is None:
        return

    bodies, _body_types = [], body_types()
    for seg in seglist:
        if seg.Type in _body_types:
            bodies.append(seg)
    
    edges = sxnet.SxEntSeg.getEdgeList(bodies)
    if edges is None:
        return
    
    edges = sum([ list(edges2) for edges2 in edges ], [])
    geoms = sxnet.SxEdge.getGeomList(edges)
    
    lines, circles, arcs = [], [], []
    for geom in geoms:
        if geom.type == sxnet.SxGeom.TYPE_LINE3D:
            lines.append(geom)
        elif geom.type == sxnet.SxGeom.TYPE_CIRCLE3D:
            circles.append(geom)
        elif geom.type == sxnet.SxGeom.TYPE_ARC3D:
            arcs.append(geom)
    
    created = []

    for line in lines:
        created_line = sxnet.SxEntSeg.createLine3D(line.sp, line.vec, line.leng)
        created.append(created_line)

    for circle in circles:
        created_circle = sxnet.SxEntSeg.createCircle3D(circle.cp, circle.radius*2.0, circle.axis)
        created.append(created_circle)

    for arc in arcs:
        created_arc = sxnet.SxEntSeg.createArc3D(arc.cp, arc.radius*2.0, arc.axis, arc.vecs, arc.vece)
        created.append(created_arc)

    if len(created) == 0:
        return
    
    if entpart is None:
        sxnet.SxEntPart.setActiveTop()
        sxnet.SxEntPart.create(created, 'エッジ', '', 1)
    else:
        entpart.setActive(False)
        created_part = entpart.create('エッジ')
        created_part.add(created)


def body_types():
    return [
        sxnet.SxEntSeg.SEGTYPE_BOX,     # 直方体  
        sxnet.SxEntSeg.SEGTYPE_CAP,     # キャップ  
        sxnet.SxEntSeg.SEGTYPE_CONE,    # 円錐/円錐台  
        sxnet.SxEntSeg.SEGTYPE_CYL,     # 円柱  
        sxnet.SxEntSeg.SEGTYPE_EPRJ,    # 拡張投影体  
        sxnet.SxEntSeg.SEGTYPE_FCSOLID, # F.C.ソリッド  
        sxnet.SxEntSeg.SEGTYPE_LPRJ,    # 偏心投影体  
        sxnet.SxEntSeg.SEGTYPE_PCON,    # 正多角錐/正多角錐台  
        sxnet.SxEntSeg.SEGTYPE_PCYL,    # 正多角柱  
        sxnet.SxEntSeg.SEGTYPE_PRJT,    # 投影体  
        sxnet.SxEntSeg.SEGTYPE_PRSM,    # 多角錐/多角錐台  
        sxnet.SxEntSeg.SEGTYPE_ROT,     # 回転体  
        sxnet.SxEntSeg.SEGTYPE_SOLID,   # ソリッド  
        sxnet.SxEntSeg.SEGTYPE_SPHR,    # 球/部分球  
        sxnet.SxEntSeg.SEGTYPE_TORUS    # トーラス  
    ]


if __name__ == '__main__':
    main()

Share post

Related Posts

コメント