[Cineema4D] 세계 좌표와 평행한 포위권 사이즈를 얻고 싶어요.

4348 단어 Cinema4DPython
CG 소프트웨어를 사용하면 포위 사이즈를 얻으려고 할 수도 있습니다. Cineema4D도 포위 사이즈를 얻는 편리한 함수가 있지만 로컬 좌표와 평행으로 포위 사이즈만 얻을 수 있다는 단점이 있습니다.
다음 그림의 사각 추이를 예로 들면 높이 5, 밑면 5*5, 밑면 중심을 축으로 하고 이를 기준으로 세계 좌표를 기준으로 H.B로 30도 기울어집니다. GetMp()는 객체의 모든 정점을 반환하는 중심 좌표입니다. GetRad()는 GetMp()를 기점으로 하는 로컬 축과 평행하는 각 축의 반지름을 반환합니다.GetMp () 로 얻은 좌표값에 GetRad () 의 값을 더하여 빼면 로컬 충돌파의 크기를 알 수 있습니다. 그러나 세계 좌표에서 본 대상의 최대 크기와 최소 크기 (빨간색 상자) 를 원한다면 곤란합니다.

GetRad() 및 GetMp()를 사용할 경우 H.B에서 -30도 이하로 객체를 복원하여 세계 좌표와 평행하게 만듭니다. 역행렬을 곱하면 간단합니다. 이때 정점도 -30도에 달합니다.각 정점은 H.B로 30도 기울어져 있으며, 점만 원래 위치로 되돌려줍니다. 이렇게 하면 세계 좌표와 축이 병행하고, 점위 위치는 원래 상태로 돌아갑니다. 파이톤에서는 축 모드를 사용하여 축의 방향만 세계와 평행하게 하려고 하지만, 이것은 파이톤에서는 불가능한 것 같습니다.이런 질문은 씨네마4D의 Plugincafe에서도 자주 제기된다.
이 상태에서 GetMp()와 GetRad()는 빨간 상자의 중심 좌표와 위아래 앞뒤 치수를 얻을 수 있습니다.
그러면, 우리는 실제적으로 이 작업의 각본을 만들어서, 얻은 크기에서 포위함의 크기와 같은 다각형을 만들 것이다.
주의: 우선 선택한 대상의 복제물을 가져온 다음 캐시를 가져옵니다. 작업op은 선택한 대상을 조작합니다. 또한 원시물이라면 캐시를 사용합니다.대상물에 따라 최종 다각형을 추가 처리해야 합니다. 또한 복제체에 대해 중간에 메시지(c4d.MSG UPDAATE)를 실행한 후 이벤트add()로 자세를 정해야 합니다. MSG가Cineema4D 측에서 조작했기 때문에,정보를 업데이트해 달라는 메시지를 드리겠습니다. 사실 이것은 여러 곳에서 사용되고 실제로도 많은 정보 유형이 있습니다.
def main():
    doc = c4d.documents.GetActiveDocument()
    op = doc.GetActiveObject()
    if op is None:
        return
    doc.StartUndo()

    # 選択オブジェクトからキャッシュを取得
    # デフォーマなどを使っている場合は,別途GetDeformeCache()などを用いて取得
    if op.GetCache():
        clone = op.GetCache().GetClone()
    else:
        clone = op.GetClone()

    # 自身の逆行列を乗算して姿勢をワールドと平行にする
    clone.SetMg(~op.GetMg() * op.GetMg())

    # 頂点を元の位置に戻す
    pcount = clone.GetPointCount()
    points = clone.GetAllPoints()
    for p in xrange(pcount):
        clone.SetPoint(p, op.GetMg() * points[p])

    # クローンをアップデートしてEventAdd()すること
    clone.Message(c4d.MSG_UPDATE)
    c4d.EventAdd()

    # センター位置からXYZの最大,最小を取得
    center = clone.GetMp()
    xMin = center.x + clone.GetRad().x * -1
    xMax = center.x + clone.GetRad().x
    yMin = center.y + clone.GetRad().y * -1
    yMax = center.y + clone.GetRad().y
    zMin = center.z + clone.GetRad().z * -1
    zMax = center.z + clone.GetRad().z
    print xMin
    print xMax
    print yMin
    print yMax
    print zMin
    print zMax

    # 新規バウンディングボックス用のポリゴンオブジェクトを作成して,座標をセットしていく
    box = c4d.BaseObject(c4d.Opolygon)
    box.ResizeObject(8,6)
    box.SetPoint(0,c4d.Vector(xMin, yMin, zMin))
    box.SetPoint(1,c4d.Vector(xMin, yMax, zMin))
    box.SetPoint(2,c4d.Vector(xMax, yMin, zMin))
    box.SetPoint(3,c4d.Vector(xMax, yMax, zMin))
    box.SetPoint(4,c4d.Vector(xMax, yMin, zMax))
    box.SetPoint(5,c4d.Vector(xMax, yMax, zMax))
    box.SetPoint(6,c4d.Vector(xMin, yMin, zMax))
    box.SetPoint(7,c4d.Vector(xMin, yMax, zMax))
    box.SetPolygon(0, c4d.CPolygon(0,1,3,2))
    box.SetPolygon(1, c4d.CPolygon(2,3,5,4))
    box.SetPolygon(2, c4d.CPolygon(4,5,7,6))
    box.SetPolygon(3, c4d.CPolygon(6,7,1,0))
    box.SetPolygon(4, c4d.CPolygon(1,7,5,3))
    box.SetPolygon(5, c4d.CPolygon(6,0,2,4))
    doc.InsertObject(box)

    # 表示タグで線表示にする
    tag = c4d.BaseTag(c4d.Tdisplay)
    tag[c4d.DISPLAYTAG_AFFECT_DISPLAYMODE] = True
    tag[c4d.DISPLAYTAG_SDISPLAYMODE] = 6
    tag[c4d.DISPLAYTAG_WDISPLAYMODE] = 0
    box.InsertTag(tag)

    box.Message(c4d.MSG_UPDATE)

    doc.AddUndo(c4d.UNDOTYPE_NEW,box)
    doc.EndUndo()
    c4d.EventAdd()

이렇게 하면 각종 자세가 존재하는 대상에서 세계 좌표에 평행하는 포위함을 얻을 수 있다.
무엇에 쓰이느냐면, 예를 들어 세계와 평행하는 포위함의 한쪽 끝에 대상을 놓으려면 내부에 이런 포위함을 생성하면 좌표를 얻을 수 있다. 참고로box=c4d.BaseObject(c4d.opolygon)의 줄에 빈 다각형 대상이 생성되었지만, 다음 줄에 있는 InsertObject는 존재하든 존재하지 않든 메모리에 계속 존재하기 때문에 주의해야 합니다. Insert가 없으면 Remove로 삭제합니다.
다 됐습니다.



다각형의 수량이 많으면 정점을 복원하는 처리에 시간이 걸리기 때문에 팔분목 등을 이용하여 최대, 최소 좌표를 계산하는 것이 좋다.

좋은 웹페이지 즐겨찾기