Перейти к содержанию
  • Здравствуйте, гость! 

    Чтобы вы могли использовать все функции нашего портала, а именно создавать сообщения, скачивать вложения и т.д., вам необходимо зарегистрироваться. Если вы уже зарегистрированные, то войдите в систему. Если у вас есть какие-либо сложности с регистрацией или ваш логин не срабатывает, то свяжитесь с нами через контактную форму, которую вы найдёте внизу каждой страницы. 

Magnus

Ориентация пивота по вектору нормали

Рекомендуемые сообщения

Magnus

Здравствуйте, подскажите пожалуйста, как развернуть пивот по направлению вектора нормали выбранного полигона через питон? Центрую оси нормально, нахожу вектор нормали полигона, а дальше ...
 

Спойлер

 


import c4d
from c4d import utils

def CenterAxis(obj, normal_vector):
    bBoxCenter = obj.GetMp()

    objMg = obj.GetMg()
    objPos = objMg.off
    objV1 = objMg.v1
    objV2 = objMg.v2
    objV3 = objMg.v3

    rot = obj.GetAbsRot()
    rotOrder = obj.GetRotationOrder()

    #HBPRotation = utils.VectorToHPB(normal_vector)

    rotM = utils.HPBToMatrix(rot,rotOrder)
    newCenter = bBoxCenter * rotM + objPos
    offsetV =  - bBoxCenter

    allPts = obj.GetAllPoints()
    for i in xrange(len(allPts)):
        obj.SetPoint(i,allPts[i] + offsetV)

    obj.Message(c4d.MSG_UPDATE)
    newMg = c4d.Matrix(newCenter,objV1,objV2,objV3)
    obj.SetMg(newMg)

def NormalVector(obj):
    polSel = obj.GetPolygonS()
    polSel.DeselectAll()
    polSel.Select(0)

    pol_nb = obj.GetPolygonCount()
    polSel_nor = c4d.Vector(0, 0, 0)

    for i, sel in enumerate(polSel.GetAll(pol_nb)):
        if not sel: continue
        pol = obj.GetPolygon(i)
        posA = obj.GetPoint(pol.a)
        posB = obj.GetPoint(pol.b)
        posC = obj.GetPoint(pol.c)
        posD = obj.GetPoint(pol.d)
        v1 = posA - posC
        v2 = posB - posD
        v3 = v1.Cross(v2)
        polSel_nor += v3

    polSel_nor.Normalize()
    return polSel_nor

def main():
    obj = doc.GetActiveObject()
    doc.StartUndo()
    doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)

    CenterAxis(obj, NormalVector(obj))

    doc.EndUndo()
    c4d.EventAdd()
if __name__=='__main__':
    main()

 

 

 

 

Изменено пользователем Magnus

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
zero21

а дальше находишь матрицу поворота нормали относительно нового базиса и применяешь к текущему объекту или можно попробовать найти обратную матрицу нормали... не знаю есть ли в синеме готовые решения, надо смотреть в мануале

Изменено пользователем zero21

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Magnus

Вроде и документацию по матрицам почитал, и все равно не догоняю - у меня теперь объект разворачивается, хотя и смотрит относительно выбранного полигона, а его пивот нет.

Спойлер

 


import c4d
from c4d import gui, utils, Vector

def NormalVector(obj):
    polSel = obj.GetPolygonS()
    polSel.DeselectAll()
    polSel.Select(0)

    pol_nb = obj.GetPolygonCount()
    polSel_nor = c4d.Vector(0, 0, 0)

    for i, sel in enumerate(polSel.GetAll(pol_nb)):
        if not sel: continue
        pol = obj.GetPolygon(i)
        posA = obj.GetPoint(pol.a)
        posB = obj.GetPoint(pol.b)
        posC = obj.GetPoint(pol.c)
        posD = obj.GetPoint(pol.d)
        v1 = posA - posC
        v2 = posB - posD
        v3 = v1.Cross(v2)
        polSel_nor += v3

    polSel_nor.Normalize()
    rotOrder = obj.GetRotationOrder()
    rotR = utils.HPBToMatrix(polSel_nor,rotOrder)
    return rotR

def main():
    doc.StartUndo()
    doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)

    bBoxCenter    = op.GetMp()
    mg_pos        = op.GetMg().off
    nrm_mg        = NormalVector(op)
    nrm_mg_V1     = nrm_mg.v1
    nrm_mg_V2     = nrm_mg.v2
    nrm_mg_V3     = nrm_mg.v3

    rot           = op.GetAbsRot()
    rotOrder      = op.GetRotationOrder()
    rotR          = utils.HPBToMatrix(rot,rotOrder)
    new_Center    = bBoxCenter * rotR + mg_pos
    new_mg        = c4d.Matrix(new_Center,nrm_mg_V1,nrm_mg_V2,nrm_mg_V3)

    points        = op.GetAllPoints()
    for i in xrange(len(points)):
        op.SetPoint(i,points + -bBoxCenter)

    op.Message(c4d.MSG_UPDATE)
    op.SetMg(new_mg)

    doc.EndUndo()
    c4d.EventAdd()
if __name__=='__main__':
    main()

 

 

Изменено пользователем Magnus

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

×

Важная информация

Мы разместили cookie-файлы на ваше устройство, чтобы помочь сделать этот сайт лучше. Вы можете изменить свои настройки cookie-файлов, или продолжить без изменения настроек.