понедельник, 28 марта 2016 г.

Выравнивание объектов друг относительно друга.

Очень редко, но требуется точно выровнять одинаковые объекты со сбитыми пивотами и с разной трансформацией.


Это можно сделать этим скриптом:

--------------------------------------------------------
(  
fn AlignPivotTo Obj Trgt =
(
    -- Current offset transform matrix
    TmScale = scaleMatrix Obj.objectOffsetScale
    TmRot = Obj.objectOffsetRot as matrix3
    TmPos = transMatrix Obj.objectOffsetPos
    TmOffset = TmScale * TmRot * TmPos
    -- New offset transform matrix
    TmOffset *= obj.transform * inverse Trgt
    -- Apply matrix
    Obj.transform = Trgt
    -- Restore offsets
    Obj.objectOffsetPos = TmOffset.translation
    Obj.objectOffsetRot = TmOffset.rotation
    Obj.objectOffsetScale = TmOffset.scale
)

fn localMatrix p1 p2 p3 =
(
    v1 = p1 - p3
    v2 = p2 - p3
    e1 = normalize( cross v1 v2)
    e2 = normalize( cross e1 v1)
    e3 = normalize( cross e1 e2)
    mat3 = matrix3 1
    mat3[1] = e1
    mat3[2] = e2
    mat3[3] = e3
    mat3[4] = p1
    return mat3
    )
   
   
fn AlignObjects mainObj tempObj numberFace =
(
--zapishem masshtab objectov
ScaleMainObj = mainObj.scale
ScaleTempObj = tempObj.scale
--vistavim 100pr masshtab
mainObj.scale = [1,1,1]
tempObj.scale = [1,1,1]   
   
   
VertUseFacesT = ((meshop.getVertsUsingFace tempObj numberFace) as array)
VertUseFacesM = ((meshop.getVertsUsingFace mainObj numberFace) as array)
----------------------------------------------   
NumV = tempObj.numverts
t1 = VertUseFacesT[1]
t2 = VertUseFacesT[2]
t3 = VertUseFacesT[3]
m1 = VertUseFacesM[1]
m2 = VertUseFacesM[2]
m3 = VertUseFacesM[3]
----------------------------------------------
theMt = localMatrix (getVert tempObj t1) (getVert tempObj t2) (getVert tempObj t3)
theMm = localMatrix (getVert mainObj m1) (getVert mainObj m2) (getVert mainObj m3)
AlignPivotTo tempObj theMt
tempObj.transform = theMm
tempObj.pivot = mainObj.pivot

--vistavim stariy masshtab
mainObj.scale = ScaleMainObj
tempObj.scale = ScaleTempObj
    )

   
fn roundNum A B  =     floor (10000.0*sqrt((A-B)^2))
   
   
fn compareObjByAreas MainObj CompareObj =
(
--zapishem masshtab objectov
ScaleMainObj = MainObj.scale
ScaleCompareObj = CompareObj.scale
--vistavim 100pr masshtab
MainObj.scale = [1,1,1]
CompareObj.scale = [1,1,1]   

tempMainObj = snapshot  MainObj  --zaskrinshotim objecty
tempCompObj = snapshot  CompareObj
   
numFacesM = tempMainObj.numFaces   
numFacesC = tempCompObj.numFaces

if numFacesM == numFacesC then
(
    local theSummAreas = 0.0
    for i = 1 to 10 do --viberem 10 proizvolnih fasov dlya sravneniya
    (
        randFace = random 1 numFacesM
        Sqare_mf = meshop.getFaceArea tempMainObj randFace
        Sqare_cf = meshop.getFaceArea tempCompObj randFace
        theSummAreas = theSummAreas + (Sqare_mf - Sqare_cf)
        )
    if theSummAreas <= 0.1 then CompareIndex = 1 else CompareIndex = 0
    ) else CompareIndex = 0

delete tempMainObj
delete tempCompObj

--vistavim stariy masshtab
MainObj.scale = ScaleMainObj
CompareObj.scale = ScaleCompareObj
   
return  CompareIndex   
    )   
   
   
   
   
if (compareObjByAreas $1 $2) == 1 do AlignObjects $1 $2 1   
   
    )
--------------------------------------------------------


Для выполнения необходимо базовый объект переименовать в "1", а совмещаемый в "2".

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


Комментариев нет:

Отправить комментарий