解剖一只MZP
2019-12-10 本文已影响0人
锦囊喵
首先准备一个MZP
使用7Zip或者其他工具解压

可以看到整个mzp由三个文件(mzp.run、message.ms、views_zoom.ms)构成,其实这也是mzp的基本构成;
- 使用文本编辑器打开mzp.run:
drop message.ms
run message.ms
treeCopy Scripts to $max
以上mzp.run是整个mzp的引导文件,指示mzp在拖入max界面后的动作:
0.mzp解压缩
1.拖入message.ms到Max
2.运行message.ms
3.将mzp中的整个Scripts文件夹复制到Max安装目录下
通过mzp.run这几步动作,将mzp内的文件及文件夹安装到指定位置,即已经安装完成;
- 接着使用文本编辑器打开message.ms
messagebox "Actions are stored in Category: \"Views+zoom\""
messagebox "Restart 3dsMax"
可以看到,这个文件里面写的是安装完毕,在max界面的提示信息


- 然后我们进入到 \Scripts\Startup,找到 Views_zoom.ms,使用文本编辑器打开
/*
Author: Nikolay Litvinov
Script: Views+zoom Created in the 3dsMax 2012
Now is not necessary to press the Zoom Extents Selected,
when switching of view
Tip: Assign these scripts to buttons of num-pad.
*/
macroScript vz_F category:"Views+zoom" tooltip: "Front"
(
max vpt front
max zoomext sel
try(unhide $F)catch()
try(hide $T) catch()
try(hide $B) catch()
try(hide $L) catch()
)
macroScript vz_B category:"Views+zoom" tooltip: "Back"
(
max vpt back
max zoomext sel
try(unhide $B)catch()
try(hide $T) catch()
try(hide $F) catch()
try(hide $L) catch()
)
macroScript vz_Bot category:"Views+zoom" tooltip: "Bottom"
(
max vpt bottom
max zoomext sel
)
macroScript vz_T category:"Views+zoom" tooltip: "Top"
(
max vpt top
max zoomext sel
try(unhide $T)catch()
try(hide $B) catch()
try(hide $F) catch()
try(hide $L) catch()
)
macroScript vz_L category:"Views+zoom" tooltip: "Left"
(
max vpt left
max zoomext sel
try(unhide $L)catch()
try(hide $T) catch()
try(hide $F) catch()
try(hide $B) catch()
)
macroScript vz_R category:"Views+zoom" tooltip: "Right"
(
max vpt right
max zoomext sel
try(unhide $L)catch()
try(hide $T) catch()
try(hide $F) catch()
try(hide $B) catch()
)
macroScript vz_PerspOrthViSw Category:"Views+zoom" Tooltip:"Perspective-Orthographic View Switcher" icon:#("ViewportNavigationControls",26)
(
on ischecked return gw.isPerspectiveView()
on Execute do
if gw.isPerspectiveView()==on
then
if ViewCubeOps.Visibility==on
then (ViewCubeOps.Orthographic(); max zoomext sel
actionMan.executeAction 0 "550" -- Views: Viewport Visual Style Shaded
try(hide $L)catch()
try(hide $T)catch()
try(hide $F)catch()
try(hide $B)catch()
)
else (ViewCubeOps.Orthographic(); max zoomext sel; ViewCubeOps.Visibility=off
actionMan.executeAction 0 "550" -- Views: Viewport Visual Style Shaded
try(hide $L)catch()
try(hide $T)catch()
try(hide $F)catch()
try(hide $B)catch()
)
else
if ViewCubeOps.Visibility==on
then (ViewCubeOps.Perspective(); max zoomext sel
actionMan.executeAction 0 "550" -- Views: Viewport Visual Style Shaded
ViewCubeOps.GoHome()
try(hide $L)catch()
try(hide $T)catch()
try(hide $F)catch()
try(hide $B)catch()
)
else (ViewCubeOps.Perspective(); max zoomext sel; ViewCubeOps.Visibility=off
actionMan.executeAction 0 "550" -- Views: Viewport Visual Style Shaded
try(hide $L)catch()
try(hide $T)catch()
try(hide $F)catch()
try(hide $B)catch()
)
Completeredraw()
)
fn WorldToScreenPos p =
(
local screen_width = RenderWidth
local screen_height = RenderHeight
local thePos = p * viewport.getTM()
local screen_origin = mapScreenToView [0,0] (thePos.z) [screen_width,screen_height]
local end_screen = mapScreenToView [screen_width,screen_height] (thePos.z) [screen_width,screen_height]
local world_size = screen_origin-end_screen
local x_aspect = screen_width/(abs world_size.x)
local y_aspect = screen_height/(abs world_size.y)
local screen_coords = point2 (x_aspect*(thePos.x-screen_origin.x)) (-(y_aspect*(thePos.y-screen_origin.y)))
return screen_coords
)
fn GetKnot_Pos_fn=
(
global PointPos=#()
for spl=1 to numSplines $ do
for k=1 to (getKnotSelection $ spl).count
do append PointPos (getKnotPoint $ spl ((getKnotSelection $ spl)[k]))
)
fn FN_Seg_2_Knot_Ctrl_1 =
(
arSegKnots=for spl=1 to numSplines $ collect getSegSelection $ spl
for i=1 to arSegKnots.count where arSegKnots[i].count!=0 do
for j=1 to arSegKnots[i].count do appendIfUnique arSegKnots[i] (arSegKnots[i][j]+1)
for i=1 to arSegKnots.count do if arSegKnots[i].count>numKnots $ i do deleteItem arSegKnots[i] arSegKnots[i].count
for spl=1 to arSegKnots.count do
setKnotSelection $ spl arSegKnots[spl]
--subObjectLevel=1
)
fn Normal_fromBorder_fn=(macros.run "Editable Polygon Object" "EPoly_Cap"
with undo off gco.ConvertSelection #Border #Face requireAll:on
local n=polyOp.getFaceNormal selection[1].baseobject (gco.getselection #face as array)[1]
max undo; n)
macroScript vz_X_Align_Viewport_subobject category:"Views+zoom" icon: #("Maintoolbar",37) tooltip: "X Align Viewport by subobject"
(
global s1=selection[1]
global PointPos=#()
global Normal_Face
fn Align_U012_fn=(-- HorizontView_Edge_or_2Vert
if selection.count==1 do
(
global gco=modPanel.getCurrentObject()
if classof $==SplineShape or classof $==line
then case subobjectlevel of
(
default: if numKnots $==2 do PointPos=#(getKnotPoint $ 1 1, getKnotPoint $ 1 2)
1: GetKnot_Pos_fn()
2: (FN_Seg_2_Knot_Ctrl_1(); GetKnot_Pos_fn())
)
else PointPos = case subobjectlevel of
(
1: try (vert=getVertSelection selection[1].mesh as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1] vert[i])
catch (vert=getVertSelection selection[1].baseobject.mesh as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1].baseobject vert[i])
2: try (vert=(PolyOp.GetVertsUsingEdge selection[1] (gco.getSelection #Edge)) as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1] vert[i])
catch (vert=(PolyOp.GetVertsUsingEdge selection[1].baseobject (gco.getSelection #Edge)) as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1].baseobject vert[i])
)
)
fn ViewTransformTM=(
p1 = WorldToScreenPos PointPos[2]
p2 = WorldToScreenPos PointPos[1]
vec = normalize (p1 - p2)
horizont = [1,0,0]
ang = acos (dot [vec.x,vec.y,0] horizont)
if p1.y <= p2.y then ang *= (-1)
if ang < -135 do ang=180+ang
if ang > 135 do ang=ang-180
viewport.SetTM ((viewport.GetTM()) * RotateZMatrix ang)
--vectViewport = (inverse(getViewTM())).row3
--rotate s1 (angleaxis ang vectViewport)
)
viewport.setType #view_iso_user; ViewTransformTM()
)
fn Align_byFace_fn=
(
WorldUpVector = [0,0,1]
Tangent_Face = normalize (cross WorldUpVector Normal_Face)
tempcam = freecamera pos:Tangent_Face
global dirCam_bool
if dirCam_bool==undefined do dirCam_bool=on
case dirCam_bool of
(
true: (tempcam.dir=Tangent_Face; dirCam_bool=off)
false: (tempcam.dir=Tangent_Face*(-1); dirCam_bool=on)
)
MatrixView=inverse tempcam.transform
viewport.setTM MatrixView
delete tempcam
select s1
max zoomext sel
)
case subobjectlevel of
(
default: Align_U012_fn()
1: Align_U012_fn()
2: Align_U012_fn()
3: (Normal_Face = Normal_fromBorder_fn(); Align_byFace_fn())
4: (Normal_Face = polyOp.getFaceNormal selection[1].baseobject (gco.getselection #face as array)[1]; Align_byFace_fn())
)
Completeredraw()
)
macroScript vz_Y_Align_Viewport_subobject category:"Views+zoom" icon: #("Maintoolbar",39) tooltip: "Y Align Viewport by subobject"
(
global s1=selection[1]
global PointPos=#()
global Normal_Face
fn Align_U012_fn=
(-- HorizontView_Edge_or_2Vert
if selection.count==1 do
(
global gco=modPanel.getCurrentObject()
if classof $==SplineShape or classof $==line
then case subobjectlevel of
(
default: if numKnots $==2 do PointPos=#(getKnotPoint $ 1 1, getKnotPoint $ 1 2)
1: GetKnot_Pos_fn()
2: (FN_Seg_2_Knot_Ctrl_1(); GetKnot_Pos_fn())
)
else PointPos = case subobjectlevel of
(
1: try (vert=getVertSelection selection[1].mesh as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1] vert[i])
catch (vert=getVertSelection selection[1].baseobject.mesh as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1].baseobject vert[i])
2: try (vert=(PolyOp.GetVertsUsingEdge selection[1] (gco.getSelection #Edge)) as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1] vert[i])
catch (vert=(PolyOp.GetVertsUsingEdge selection[1].baseobject (gco.getSelection #Edge)) as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1].baseobject vert[i])
)
)
fn ViewTransformTM=(
p1 = WorldToScreenPos PointPos[2]
p2 = WorldToScreenPos PointPos[1]
vec = normalize (p1 - p2)
horizont = [1,0,0]
ang = acos (dot [vec.x,vec.y,0] horizont)
if p1.y <= p2.y then ang *= (-1); ang-=270
viewport.SetTM ((viewport.GetTM()) * RotateZMatrix ang)
--vectViewport = (inverse(getViewTM())).row3
--rotate s1 (angleaxis ang vectViewport)
)
viewport.setType #view_iso_user; ViewTransformTM()
)
fn Align_byFace_fn=(
WorldUpVector = [0,0,1]
Tangent_Face = normalize (cross WorldUpVector Normal_Face)
Binormal_Face = normalize (cross Tangent_Face Normal_Face)
tempcam = freecamera pos: Binormal_Face
global dirCam_bool
if dirCam_bool==undefined do dirCam_bool=on
case dirCam_bool of
(
true: (tempcam.dir=Binormal_Face; dirCam_bool=off)
false: (tempcam.dir=Binormal_Face*(-1); dirCam_bool=on)
)
MatrixView=inverse tempcam.transform
viewport.setTM MatrixView
delete tempcam
select s1
max zoomext sel
)
case subobjectlevel of
(
default: Align_U012_fn()
1: Align_U012_fn()
2: Align_U012_fn()
3: (Normal_Face = Normal_fromBorder_fn(); Align_byFace_fn())
4: (Normal_Face = polyOp.getFaceNormal selection[1].baseobject (gco.getselection #face as array)[1]; Align_byFace_fn())
)
Completeredraw()
)
macroScript vz_Z_Align_Viewport_subobject category:"Views+zoom" icon: #("Maintoolbar",41) tooltip: "Z Align Viewport by subobject"
(
global PointPos=#()
if selection.count==1 do
(
global gco=modPanel.getCurrentObject()
if classof $==SplineShape or classof $==line
then case subobjectlevel of
(
default: if numKnots $==2 do PointPos=#(getKnotPoint $ 1 1, getKnotPoint $ 1 2)
1: GetKnot_Pos_fn()
2: (FN_Seg_2_Knot_Ctrl_1(); GetKnot_Pos_fn())
)
else PointPos = case subobjectlevel of
(
1: try (vert=getVertSelection selection[1].mesh as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1] vert[i])
catch (vert=getVertSelection selection[1].baseobject.mesh as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1].baseobject vert[i])
2: try (vert=(PolyOp.GetVertsUsingEdge selection[1] (gco.getSelection #Edge)) as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1] vert[i])
catch (vert=(PolyOp.GetVertsUsingEdge selection[1].baseobject (gco.getSelection #Edge)) as array; if vert.count>0 do for i=1 to 2 collect getPointPos selection[1].baseobject vert[i])
)
)
Normal_Face=case subobjectLevel of
(
undefined: try selection[1].baseobject.transform.row3 catch selection[1].transform.row3
0: try selection[1].baseobject.transform.row3 catch selection[1].transform.row3
1: normalize (PointPos[2] - PointPos[1])
2: normalize (PointPos[2] - PointPos[1])
3: Normal_fromBorder_fn()
4: try (polyOp.getFaceNormal selection[1] (gco.getselection #face as array)[1])
catch
(
arrFaces=for i in selection collect gco.getSelection #face node: i
numSel=for i=1 to arrFaces.count where arrFaces[i].numberset>0 do exit with i
(arrFaces[numSel]as array)[1]
polyOp.getFaceNormal selection[numSel] (arrFaces[numSel]as array)[1]
)
)
tempcam = freecamera pos: Normal_Face
global dirCam_bool
if dirCam_bool==undefined do dirCam_bool=on
case dirCam_bool of
(
true: (tempcam.dir=Normal_Face; dirCam_bool=off)
false: (tempcam.dir=Normal_Face*(-1); dirCam_bool=on)
)
MatrixView=inverse tempcam.transform
viewport.setTM MatrixView
delete tempcam
max zoomext sel
Completeredraw()
)
以上为MZP实际运行部分,这个mzp直接打包ms其实也可以打包mse,运行效果一样。
综上所述,一般来说一个mzp总共包含以下几个部分
1.mzp.run:告诉mzp拖入max后进行的安装动作
2.message.ms:用于提示用户
3.执行部分(可以是ms,也可以msr,mse)
以上,就是一个MZP插件的基本构成!