1. Пользоваться форумом на планшетах и телефонах стало удобнее благодаря Tapatalk

Gizmo allign

Тема в разделе "Моделирование", создана пользователем Сергей Попов 144982, 21 мар 2013.

Модераторы: He77ga, Артер
  1. Сергей Попов 144982

    Сергей Попов 144982 Пользователь сайта

    С нами с:
    27.11.2012
    Сообщения:
    25
    Симпатии:
    0
    Баллы:
    2
    Подскажите как можно поворачивать и выравнивать гизмо контейнер. На рисунке показана моя модель, вокруг неё расположен гизмо. Нужно наложить модификатор ffd box. Он позиционируется по гизмо. внутри самого модификатора можно вращать контейнер, но у меня не получилось с помощью привязок расположить ffd точно вдоль той системы координат, которая там показана.
     

    Вложения:

    • 3057862.jpg
      3057862.jpg
      Размер файла:
      70,4 КБ
      Просмотров:
      51
  2. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    В списке Reference Coordinate System выбираем World.
    На панели Display нажимаем кнопку Unhide By Name и выбираем shift_plane_igorznag.
    На панели Display нажимаем кнопку Unfreeze By Name и выбираем shift_plane_igorznag.
    Выделяем нужный объект.
    На панели Utilities нажимаем кнопку Reset XForm > Reset Selected.
    Добавляем модификатор FFD Box и активируем под-объект Lattice.
    Нажимаем кнопку Align (Alt+A).
    Нажимем кнопку Select By Name (H) и выбираем shift_plane_igorznag.
    В окне Align: Align Orientation (Local): Включаем X Axis, Y Axis, Z Axis.
    В списке Reference Coordinate System выбираем shift_plane_igorznag.
     
  3. Сергей Попов 144982

    Сергей Попов 144982 Пользователь сайта

    С нами с:
    27.11.2012
    Сообщения:
    25
    Симпатии:
    0
    Баллы:
    2
    В очередной раз спасибо. Вопрос решен. Не могли бы вы пояснить, есть ли вообще возможность вращать и алигнить гизмо контейнер объекта, а не габаритный контейнер модификатора? Если есть reset xform, которая сбрасывает его ориентацию, то наверное должна быть возможность располагать его произвольным образом?
     
  4. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Не знаю, но можно создать временный объект и вращать-алигнить его, а потом "украсть" у него контейнер.

    На панели Display нажимаем кнопку Unhide By Name и выбираем shift_plane_igorznag.
    На панели Display нажимаем кнопку Unfreeze By Name и выбираем shift_plane_igorznag.
    Выделяем объект shift_plane_igorznag и создаем копию (Ctrl+V) с названием "temp".
    Конвертируем объект temp в Editable Poly.
    Выделяем все полигоны объекта temp (Ctrl+A) и удаляем их (Delete).
    В свитке Edit Geometry нажимаем кнопку Attach и выбираем нужный объект.
    Выделяем объект temp и добавляем модификатор FFD Box.
     
  5. Сергей Попов 144982

    Сергей Попов 144982 Пользователь сайта

    С нами с:
    27.11.2012
    Сообщения:
    25
    Симпатии:
    0
    Баллы:
    2
    Вы уже написали мне скрипт, который прекрасно работает, и за что отдельное Спасибо. У меня тут идея возникла, а можете написать скрипт, который будет вращать модель по 3 осям, и находить её положение в BB, при котором она занимает в нем наибольший объем, а потом эти углы поворота применять к повороту BB, и модель возвращать в изначальное положение? Тогда, на первый взгляд, BB оптимально будет описывать модель.
     
  6. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Если для вас подходит скрипт minOBB, тогда:
    Выделяем все объекты Editable Poly без модификаторов.
    Запускаем скрипт. В новом окне нажимаем кнопку Apply.
    Создаем копию сцены перед тем, как использовать скрипт.
    Код:
    try(destroydialog igorznag_minOBB)catch()
    rollout igorznag_minOBB "Min OBB"
    (
    --gui
    button btn_apply "Apply"
    --variables
    local obj
    --functons
    -- The Jacobi Method for Finding the Eigenvalue and Eigenvectors
    -- of Symmetric Matrices.
     
     fn Jacobi  n &a &d &v  = 
    ( 
    	local i, j, p, q, rot, sm, g, theta, t, tresh, c, s, tau, h
    	local z=#()
    	local b=#()
    	for i =1 to n do
    	(
    		z[i] =0.0
    		b[i] = a[i][i]
    		d[i] = a[i][i]
    		for j=1 to n do
    		 if (i == j) then v[i][j] = 1.0
    		 	       else v[i][j] = 0.0
    	)
    
    	rot =0
    	for i =1 to 50 do
    	(
    		sm = 0.0
    		for p = 1 to n-1 do
    		 for q=p+1 to n do sm += abs( a[p][q] )
    		 
    		if ( sm == 0 ) then exit()
    		tresh = case ( i<4 ) of
    		(
    			true: 0.2*sm/(n*n)
    			false: 0.0
    		)
    		for p =1 to n-1 do
    		(
    			for q = p+1 to n do 
    			(
    				g = 1e12 * abs ( a[p][q] )
    				if ((i>4) and ( abs(d[p])>g ) and ( abs(d[q])>g )) then (a[p][q] = 0.0)
    				else 
    				if ( abs( a[p][q] ) > tresh ) then
    				(
    					theta = 0.5 * ( d[q] - d[p] ) / a[p][q]
    					t = 1.0 / ( abs(theta) + sqrt(1.0+theta*theta) )
    					if ( theta < 0 ) then t = - t
    					c = 1.0 / sqrt ( 1.0 + t*t )
                        			s = t * c
                        			tau = s / ( 1.0 + c )
                        			h = t * a[p][q]
    					z[p] -= h
    					z[q] += h
    					d[p] -= h
                        			d[q] += h
                        			a[p][q] = 0.0
    					for j=1 to p-1 do   
    					(
    						g = a[j][p]
    						h = a[j][q]
    						a[j][p] = g - s * ( h + g * tau )
    						a[j][q] = h + s * ( g - h * tau )
    					)
    					for j=p+1 to q-1 do
    					(
    						g = a[p][j]
    						h = a[j][q]
    						a[p][j] = g - s * ( h + g * tau )
    						a[j][q] = h + s * ( g - h * tau )
    					)
    					for j=q+1 to n do
    					(
    						g = a[p][j]
    						h = a[q][j]
    						a[p][j] = g - s * ( h + g * tau )
    						a[q][j] = h + s * ( g - h * tau )
    					)
    					for j=1 to n do
    					(
    						g = v[j][p]
    						h = v[j][q]
    						v[j][p] = g - s * ( h + g * tau )
    						v[j][q] = h + s * ( g - h * tau )
    					)
    					rot += 1
    				)				
    			)
    		)
    		for p =1 to n do
    		(
    			b[p] += z[p] 
    			d[p] = b[p]			
    			z[p] = 0.0
    		)
    	)--for i =1 to 50
    	return rot
    )--fn Jacobi
    
    
    fn GetBestFitVectors &v &dir &norm  =
    (
    	local n = v.count
    	if (n<2) then return false
    	local point = v[1]
    	for i = 2 to n do (point += v[i])
    	point /= n
    	local xx, xy, xz, yy, yz, zz
    	xx = xy = xz = yy = yz = zz = 0.0
    	for i = 1 to n do
    	(
    		local u = v[i] - point
    		xx += u.x * u.x
    		xy += u.x * u.y
    		xz += u.x * u.z
    		yy += u.y * u.y
    		yz += u.y * u.z
    		zz += u.z * u.z
    	)
    	
    	--Symmetric Matrix
    	local a = #([ xx, xy, xz ],
    		 	 [ xy, yy, yz ],
    		 	 [ xz, yz, zz ])
    		 
    	--Eigenvalue
    	local d = #(0.0, 0.0, 0.0)
    	
    	--Eigenvectors	 
    	local u = #([ 0, 0, 0 ],
    		 	 [ 0, 0, 0 ],
    		 	 [ 0, 0, 0 ])
    
    	--finding the Eigenvalue and Eigenvectors
    	jacobi  3 &a &d &u
    
    	-- calc direction ray
    	if ( d[1] >= d[2] ) then
    	(
    		if ( d[1] >= d[3] ) then (dir = [ u[1].x, u[2].x, u[3].x ])
            				 	else  (dir = [ u[1].z, u[2].z, u[3].z ])
    	)
    	else
    	(
    		if ( d[2] >= d[3] ) then (dir = [ u[1].y, u[2].y, u[3].y ])
    					 else	 (dir = [ u[1].z, u[2].z, u[3].z ])
    	)
    	-- calc normal fit plane
    	if ( d[1] <= d[2] ) then 
        	(
            		if ( d[1] <= d[3] ) then norm = [ u[1].x, u[2].x, u[3].x ]
            					else  norm = [ u[1].z, u[2].z, u[3].z ]
        	)
        	else
        	(
            		if ( d[2] <= d[3] ) then norm = [ u[1].y, u[2].y, u[3].y ]
            					else  norm = [ u[1].z, u[2].z, u[3].z ]
        	)
    	return true
    )--fn GetBestFitVectors
    
    on btn_apply pressed do
    (
    undo off
    (
    	max modify mode
    	objs=selection as array
    	for i=1 to objs.count do
    	(
    	obj = objs[i]
    	if(classOf(obj)==Editable_Poly)then
    	(
    	-- get cloud points from object
      cloud_points = #()
    		for i=1 to obj.NumVerts do append cloud_points (polyOp.getVert obj i)
    	-- calc fit dir and normal fit plane
    getBestFitVectors &cloud_points &dir &norm
    -- calc and draw box
    arr=#(); join arr cloud_points
    	local upVector = normalize ( cross dir norm )
    	local T = matrix3 upVector norm dir [0,0,0]
    	local iT = inverse T
    	for i=1 to arr.count do arr[i] = arr[i] * iT
    
    	local qmin = copy arr[1]
    	local qmax = copy arr[1]
    	
    	for i in arr do (
    		for j=1 to 3 do (
    			if i[j] < qmin[j] do qmin[j]=i[j]
    			if i[j] > qmax[j] do qmax[j]=i[j]
    		)
    	)
    	
    	local _diag = qmax-qmin
    	local l = abs _diag.x
    	local w = abs _diag.y
    	local h = abs _diag.z
    	local b = box length:w width:l height:h
    	b.pivot = b.center
    	b.transform = T
    	b.pos = (qmax+qmin)/2.0 * T
    	b.wirecolor = obj.wirecolor
    	b.name=obj.name
    	b.parent=obj.parent
    	b.pivot=obj.pos
    	for obj_child in obj.children do append b.children obj_child
    	b=converttopoly b
    	polyOp.deleteFaces b #{1..(polyop.getNumFaces b)}
    	polyOp.attach b obj
    	selectmore b
    	)--if(classOf(obj)==Editable_Poly)then
    )--for i=1 to selection.count do
    )--undo off
    redrawViews()
    )--on btn_apply pressed do
    ); createdialog igorznag_minOBB 100 30
     
  7. Сергей Попов 144982

    Сергей Попов 144982 Пользователь сайта

    С нами с:
    27.11.2012
    Сообщения:
    25
    Симпатии:
    0
    Баллы:
    2
    Я так понимаю метод Якоби применяется для нахождения собственных векторов и собственных значений матрицы ковариации созданной на основе координат вершин объектов. Вопрос такой, берутся все вершины для анализа, или только вершины выпуклой оболочки объекта?
     
  8. Сергей Попов 144982

    Сергей Попов 144982 Пользователь сайта

    С нами с:
    27.11.2012
    Сообщения:
    25
    Симпатии:
    0
    Баллы:
    2
    Короче проверил скрипт. Оси ищутся для всех точек меша, а это значит, что сгустки точек в каком-то месте меша буду вносить вес в матрицу ковариации и влиять на направления осей. Нужно дополнить скрипт, а именно, перед расчетом матрицы построить выпуклую оболочку. У меня пока что не получилось так сделать...
     
  9. Сергей Попов 144982

    Сергей Попов 144982 Пользователь сайта

    С нами с:
    27.11.2012
    Сообщения:
    25
    Симпатии:
    0
    Баллы:
    2
    Просто если использовать скрипт в таком виде, то происходит такой глюкан из-за неравномерной топологии сетки объекта.
     

    Вложения:

    • 3064982.jpg
      3064982.jpg
      Размер файла:
      133,2 КБ
      Просмотров:
      62
  10. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    У меня тоже не получается.
    Для объекта из сообщения 9 попробуйте этот простой вариант.
    Создаем копию сцены. Выполняются много вычислений.
    Код:
    try(destroydialog igorznag_minOBB)catch()
    rollout igorznag_minOBB "Min OBB"
    (
    button btn_apply "Apply"; 
    fn AlignPivotTo Obj Trgt = 
    ( 
    -- Get matrix from object 
    if classOf Trgt != matrix3 then Trgt = Trgt.transform 
    -- Store child transforms 
    local ChldTms = in coordSys Trgt ( for Chld in Obj.children collect Chld.transform ) 
    -- Current offset transform matrix 
    local TmScale = scaleMatrix Obj.objectOffsetScale 
    local TmRot = Obj.objectOffsetRot as matrix3 
    local TmPos = transMatrix Obj.objectOffsetPos 
    local 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 
    -- Restore child transforms 
    for i = 1 to Obj.children.count do Obj.children[i].transform = ChldTms[i] * inverse Trgt * Obj.transform 
    )
    
    on btn_apply pressed do
    (
    undo off
    (
    with animate off
    (
    objs=selection as array;
    m=undefined; diag=undefined; vol=1e9
    b_min=[1e9,1e9,1e9];b_max=[-1e9,-1e9,-1e9];
    for i=1 to objs.count do
    (
    obj = objs[i]
    if(classOf(obj)==Editable_Poly)then
    (
    for i=1 to (polyop.getNumFaces obj) do
    (
    ef_a=polyop.getFaceEdges obj i
    face_normal=polyop.getFaceNormal obj i
    for j=1 to ef_a.count do
    (
    ve_a=polyop.getEdgeVerts obj ef_a[j]
    v1_coord=polyop.getVert obj ve_a[1]
    v2_coord=polyop.getVert obj ve_a[2]
    v2v1=normalize(v2_coord-v1_coord)
    v3=normalize (cross v2v1 face_normal)
    m_temp=matrix3 v2v1 face_normal v3 v1_coord
    in coordsys m_temp
    (
    b_min_temp=[1e9,1e9,1e9];b_max_temp=[-1e9,-1e9,-1e9]
    for k=1 to (polyop.getnumverts obj) do
    (
    vert_temp=polyop.getVert obj k
    for t=1 to 3 do
    (
    if vert_temp[t]<b_min_temp[t] then b_min_temp[t]=vert_temp[t]
    if vert_temp[t]>b_max_temp[t] then b_max_temp[t]=vert_temp[t]
    )--for t=1 to 3 do
    )--for k=1 to (polyop.getnumverts obj) do
    diag_temp=b_max_temp-b_min_temp
    vol_temp=diag_temp.x*diag_temp.y*diag_temp.z
    if(vol_temp<vol)then (
    diag=diag_temp;vol=vol_temp;b_min=b_min_temp;b_max=b_max_temp;m=m_temp
    )
    )--in coordsys m
    )--for j=1 to ef_a.count do
    )--for i=1 to (polyop.getNumFaces obj) do
    
    if(m!=undefined)then
    (
    b=box length:diag.y width:diag.x height:diag.z
    b.pivot=b.center
    b.transform=m
    in coordsys m b.pos = (b_max+b_min)/2.0
    AlignPivotTo b (transMatrix obj.pos)
    ----
    b.wirecolor = obj.wirecolor
    b.name=obj.name
    b.parent=obj.parent
    for obj_child in obj.children do append b.children obj_child
    b=converttopoly b
    polyOp.deleteFaces b #{1..(polyop.getNumFaces b)}
    polyOp.attach b obj
    selectmore b
    )--if(m!=undefined)then
    )--if(classOf(obj)==Editable_Poly)then
    )--for i=1 to objs.count do
    )--with animate off
    )--undo off
    redrawViews()
    )--on btn_apply pressed do
    ); createdialog igorznag_minOBB 100 30
    
     
Модераторы: He77ga, Артер

Поделиться этой страницей