-- A Wk script for maxR8.x
-- Version 1.5
-- released -
-- contact: werwack@yahoo.com
/*
-- Purpose:
---------
This script creates a spoke tape in the scene. It gives the spoke value of circles and arcs and is renderable
-- Use:
----
Go to Create->Geometry->Cotations and clic on WkSpoke
-- Notes:
-------
- support atmosph for lights
- undo works
-- Known troubles:
---------------
-- Todo:
-----
--wip attention les groupehead viennent se mettre ds la selection
-- wip les gpmembers sont vires
-- wip copy, inst etc distrib ne marchent que sur le 1er obj de la sel
-- mettre une progressbar
-- faire une option "link to support"
-- ne marche pas avec des grps ouverts CloneNodes
-- teste si un support xref peut etre utilise
-- faire une option use selected verts
-- faire une option allow grp members
-- faire un alignement en fonction des axes, des reperes
-- released:
-- - shapes now supported for support
-- Version history:
-----------------
-- V1.5: (20/02/06)
- link objects to support faces with attachment controller added
-- V1.0: (10/11/05)
- basic version
*/
------------------------------------------------------------------------------------------
macroScript WkScatter category:"WerwacK s Tools" tooltip: "WkScatter V 1.5" Icon:#("WkScatterIcons",1)
(
--global in the macro :
global WkScatterMainRoll, WkScatterAdvSettingsRoll, WkScatterWin
--local in the macro :
local gmSupportObj = undefined, \
gmSysObj = #world, \
obj_list_array = #(), \
obj_name_array = #(), \
atm_light_list_array = #()
local lbDisplayDebugMes = true
EnableSceneRedraw()
try( DestroyDialog WkScatterMainRoll )
catch()
------------------------------------------------------------------------------------------
-- filter for picked objects
fn SupportFilter pckobj =
(
if( ( superclassof pckobj ) == GeometryClass \
or ( superclassof pckobj ) == Shape )
then return true
else return false
)
------------------------------------------------------------------------------------------
-- get the selected objects and keep it in obj_list_array, keep their name in obj_name_array
fn fill_obj_list_array =
(
ind=1
for i=1 to selection.count do
(
if( ( ( superclassof selection[i] ) == GeometryClass \
or ( superclassof selection[i] ) == helper \
or ( superclassof selection[i] ) == light ) \
and selection[i] != gmSupportObj \
and selection[i] != gmSysObj \
) do
(
-- do we see grouped objects as stand alone objects?
if( WkScatterAdvSettingsRoll.IgnoreGpsChkbx.checked ) then
if( not (isgrouphead selection[i]) ) do
(
obj_list_array[ind] = selection[i]
obj_name_array[ind] = selection[i].name
ind += 1
)
else
(
if( not (isgroupmember selection[i]) or (isgrouphead selection[i]) ) do
(
obj_list_array[ind] = selection[i]
obj_name_array[ind] = selection[i].name
ind += 1
)
)
)
)
WkScatterMainRoll.obj_listbx.items = obj_name_array
)
------------------------------------------------------------------------------------------
-- filter for prs picked object for coodinate system
fn prs_sys_filt pckobj =
(
if( ( (superclassof pckobj) == geometryclass \
or (superclassof pckobj)==helper \
or (superclassof pckobj)==camera ) )
-- and (pckobj != gmSupportObj) )
--wip faire un test pour que piked object n appartienne pas o objets de la liste
then return true
else return false
)
------------------------------------------------------------------------------------------
-- fills atm_light_list_array with all the atmospherics using rLight
fn GetLightAtmospherics rLight =
(
local lIndGizmo
local lGizmo
atm_light_list_array = #()
for i=1 to numAtmospherics do
(
lIndGizmo = 1
lbNomoreGizmos = false
while( not lbNomoreGizmos ) do
(
lAtm = getAtmospheric i
-- some plugins like Scatter_VL doen t implement atm.numgizmo...
-- warning: lGizmo may be undefined!!
try( lGizmo = getgizmo lAtm lIndGizmo )
catch( lbNomoreGizmos = true )
if( not lbNomoreGizmos ) do
(
if( lGizmo != undefiend and lGizmo == rLight ) then
(
append atm_light_list_array lAtm
lbNomoreGizmos = true
)
else lIndGizmo += 1
)
)
)
if( lbDisplayDebugMes ) then
format( "Debug:GetLightAtmospherics:atm_light_list_array %\n" )atm_light_list_array
)
fn AssignAttachmentController rObj rFaceInd =
(
if rFaceInd < gmSupportObj.mesh.numfaces do
(
try
(
lcontro = Attachment()
lcontro.node = gmSupportObj
rObj.pos.controller = lcontro
rObj.pos.controller = lcontro
addNewKey lcontro 0f
theAKey = AttachCtrl.getKey lcontro 1 --get the first key
theAKey.face = rFaceInd--surf.mesh.numfaces - 1
theAKey.coord = [1,0]
)
catch()
)
)
-- rVect is float, point 2 or point3
-- rEpsilon (optional) is the precision
-- returns true if each vector member is inférior to epsilon
fn IsNul rVect rEpsilon: =
(
if unsupplied == rEpsilon do rEpsilon = 1.0e-6
if (classof rVect) == float or (classof rVect) == integer do
if (abs rVect) < rEpsilon do return true
if (classof rVect) == point2 do
if (abs rVect.x) < rEpsilon and (abs rVect.y) < rEpsilon do return true
if (classof rVect) == point3 do
if (abs rVect.x) < rEpsilon and (abs rVect.y) < rEpsilon and (abs rVect.z) < rEpsilon do return true
return false
)
-------------------------------------------------------------------------------
--returns oriented angle in degrees between rVectA and rVectB (teta belongs to [-180,180])
--returns undefined if one of the vectors is nul (or too small) or if 2 vectors are colinear
-- note: in general we would like to have angle according to Z world fist, we will then use (default):
-- refaxisx = point3 1 0 0
-- refaxisy = point3 0 1 0
-- refaxisz = point3 0 0 1
-- GetDirectAngle (p2.pos - p1.pos) (pa.pos - p1.pos) refaxisz refaxisy refaxisx
fn GetDirectAngle rVectA rVectB rRefAxis1: rRefAxis2: rRefAxis3: =
(
if unsupplied == rRefAxis1 do rRefAxis1 = point3 0 0 1 -- world z axis
if unsupplied == rRefAxis2 do rRefAxis2 = point3 0 1 0 -- world y axis
if unsupplied == rRefAxis3 do rRefAxis3 = point3 1 0 0 -- world x axis
local lReturnAngle
if (IsNul rVectA) or (IsNul rVectB) then
(
lReturnAngle = undefined
format "nul vect - lReturnAngle %\n" lReturnAngle
)
else
(
-- val abs of teta
lTeta = acos( (dot rVectA rVectB) / ((length rVectA) * (length rVectB)) )
if not (IsNul lTeta) and not (IsNul (180 - lTeta)) then -- if VectA and VectB are not colinear, we force direct angle
(
normVect = cross rVectA rVectB
-- format "normVect: % \n" normVect
-- val abs of phi
local lCosPhi = ( (dot rRefAxis1 normVect) / ((length rRefAxis1 ) * (length normVect)) )
if not (IsNul lCosPhi) then
if (0.0 > lCosPhi) do lTeta = lTeta
else
(
format "lCosPhi axis 1 is nul!! %\n" lCosPhi
lCosPhi = ( (dot rRefAxis2 normVect) / ((length rRefAxis2 ) * (length normVect)) )
if not (IsNul lCosPhi) then
if 0.0 > lCosPhi do lTeta = lTeta
else
(
format "lCosPhi axis 2 is nul!! %\n" lCosPhi
lCosPhi = ( (dot rRefAxis3 normVect) / ((length rRefAxis3) * (length normVect)) )
if not (IsNul lCosPhi) then
if 0.0 > lCosPhi do lTeta = lTeta
else format "trouble in GetDirectAngle...\n"
)
)
/*
m = matrix3 rVectA rVectB normVect (point3 0 0 0)
format "m.determinantsign: %\n" m.determinantsign
format "m: %\n" m
--
det = m[1][1] * (m[2][2]*m[3][3] - m[3][2]*m[2][3]) - m[1][2] * (m[2][1]*m[3][3] - m[3][1]*m[2][3]) + m[1][3] * (m[2][1]*m[3][2] - m[3][1]*m[2][2])
format "det : %\n" det
if (det < 0) do lTeta = -lTeta
*/
)
else format "lTeta special val: %\n" lTeta
lReturnAngle = lTeta
)
return lReturnAngle
)
fn OrientObjectOnVertexNormal rObj rVertexInd =
(
norm = normalize (getNormal gmSupportObj.mesh rVertexInd)
in coordsys #world --gmSupportObj
(
zaxis = normalize ([0,0,1] * rObj.rotation)
ang = -GetDirectAngle norm zaxis
)
rotaxis = normalize (cross norm zaxis)
in coordsys #world --gmSupportObj
(
rObj.pos = [0,0,0]
rObj.rotation = angleaxis ang rotaxis
)
)
------------------------------------------------------------------------------------------
--wip a recoder avec le systeme de clone
fn DistributeObjects rDistribMod =
(
local lDistribObjectsArray = #()
--DisableSceneRedraw()
with redraw off
(
case rDistribMod of
(
1: (
for i = 1 to obj_list_array.count do
lDistribObjectsArray[i] = obj_list_array[i]
)
2: (
for i = 1 to gmSupportObj.verts.count do
(
col = obj_list_array[1].wirecolor
lDistribObjectsArray[i] = copy obj_list_array[1]
lDistribObjectsArray[i].wirecolor = col
)
-- if light, get atmospherics
if( (superclassof obj_list_array[1]) == light ) do
(
GetLightAtmospherics obj_list_array[1]
-- add new lights to atmospherics
for atmInd = 1 to atm_light_list_array.count do
for j=1 to lDistribObjectsArray.count do
appendgizmo atm_light_list_array[atmInd] lDistribObjectsArray[j]
)
)
3: (
for i = 1 to gmSupportObj.verts.count do
(
col = obj_list_array[1].wirecolor
lDistribObjectsArray[i] = reference obj_list_array[1]
lDistribObjectsArray[i].wirecolor = col
)
-- if light, get atmospherics
if( (superclassof obj_list_array[1]) == light ) do
(
GetLightAtmospherics obj_list_array[1]
-- add new lights to atmospherics
for atmInd = 1 to atm_light_list_array.count do
for j=1 to lDistribObjectsArray.count do
appendgizmo atm_light_list_array[atmInd] lDistribObjectsArray[j]
)
)
4: (
for i = 1 to gmSupportObj.verts.count do
(
col = obj_list_array[1].wirecolor
lDistribObjectsArray[i] = instance obj_list_array[1]
lDistribObjectsArray[i].wirecolor = col
)
-- if light, get atmospherics
if( (superclassof obj_list_array[1]) == light ) do
(
GetLightAtmospherics obj_list_array[1]
-- add new lights to atmospherics
for atmInd = 1 to atm_light_list_array.count do
for j=1 to lDistribObjectsArray.count do
appendgizmo atm_light_list_array[atmInd] lDistribObjectsArray[j]
)
)
)
-- makes the distribution
local lVertInd = 1
local lObjInd = 1
-- DisableSceneRedraw()
if( ( superclassof gmSupportObj ) == GeometryClass ) then -- support is a mesh
(
while( lVertInd <= gmSupportObj.verts.count and lObjInd <= lDistribObjectsArray.count ) do
(
if( WkScatterMainRoll.AttachmentChkbx.checked ) do
(
-- AssignAttachmentController lDistribObjectsArray[lObjInd] lObjInd
OrientObjectOnVertexNormal lDistribObjectsArray[lObjInd] lVertInd
)
in coordsys gmSysObj
(
if( WkScatterAdvSettingsRoll.AlignXChkbx.checked ) do
lDistribObjectsArray[lObjInd].pos.x = gmSupportObj.verts[lVertInd].pos.x
if( WkScatterAdvSettingsRoll.AlignYChkbx.checked ) do
lDistribObjectsArray[lObjInd].pos.y = gmSupportObj.verts[lVertInd].pos.y
if( WkScatterAdvSettingsRoll.AlignZChkbx.checked ) do
lDistribObjectsArray[lObjInd].pos.z = gmSupportObj.verts[lVertInd].pos.z
)
if( WkScatterMainRoll.LinkToSupportChkbx.checked ) do
lDistribObjectsArray[lObjInd].parent = gmSupportObj
lVertInd += 1
lObjInd += 1
)
)
else -- support is a spline (only the first is used)
(
while( lVertInd <= (numKnots gmSupportObj 1) and lObjInd <= lDistribObjectsArray.count ) do
(
in coordsys gmSysObj
(
if( WkScatterAdvSettingsRoll.AlignXChkbx.checked ) do
lDistribObjectsArray[lObjInd].pos.x = (getknotpoint gmSupportObj 1 lVertInd).x
if( WkScatterAdvSettingsRoll.AlignYChkbx.checked ) do
lDistribObjectsArray[lObjInd].pos.y = (getknotpoint gmSupportObj 1 lVertInd).y
if( WkScatterAdvSettingsRoll.AlignZChkbx.checked ) do
lDistribObjectsArray[lObjInd].pos.z = (getknotpoint gmSupportObj 1 lVertInd).z
)
if( WkScatterMainRoll.LinkToSupportChkbx.checked ) do
lDistribObjectsArray[lObjInd].parent = gmSupportObj
lVertInd += 1
lObjInd += 1
)
)
)
--EnableSceneRedraw()
)
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
-- Help on the orientation of the objetcs
Rollout WkScatterMainRoll "Scatter Settings" --height:260 width:173
(
-- buttons
pickbutton Support_pickbut "Support:" message:"Pick a Support" tooltip:"Pick a Support" filter:SupportFilter height:17 width:50 align:#left offset:[-8,0]
edittext Support_txt "" text:"" width:115 offset:[40,-22]
label SupportVertsNumLab "Verts Number:" align:#left offset:[-6,0]
edittext SupportVertsNum_txt "" text:"" width:40 align:#right offset:[8,-20] enabled:false
button fromsel_but "Objects from Selection" width:163 height:17 align:#left offset:[-8,3]
-- button getobj_but "Get Objects to Distribute" width:163 height:17 align:#left offset:[-8,3]
listbox obj_listbx "" items:obj_name_array height:5 width:165 offset:[-9,-3]
label ObjsNumLab "Objects Number:" align:#left offset:[-6,0]
edittext ObjsNum_txt "" text:"" width:40 align:#right offset:[8,-20] enabled:false
group "Distribution "
(
dropdownlist DistribModDrpdwnList "Distribution Type:" Items:#("Even", "Copy", "Reference", "Instance" ) width:159 align:#left offset:[-5,0]
)
checkbox LinkToSupportChkbx "Link to Support" align:#left offset:[-5,-2]
checkbox AttachmentChkbx "Attach To Faces " align:#left offset:[-5,-2]
/*
group "Attachment Controller "
(
)
*/
button apply_but "Apply" width:163 height:20 align:#left offset:[-8,3]
-- events
on Support_pickbut picked obj do
(
local supportOk = true
if( (classof obj) == XRefObject ) then
(
try( obj.verts.count )
catch
(
supportOk = false
messagebox "This XRef Object Cannot Be Used as a Support" Title:"Warning"
)
)
-- else if (( ((classof obj)==classof obj.baseobject) and (classof obj)!=Editable_mesh ) \
else if (( ((classof obj)==classof obj.baseobject) and (classof obj)!=Editable_mesh and (superclassof obj)!=Shape) \
or (classof obj)==PolyMeshObject or (classof obj)==Editable_Poly ) do
(
if (querybox "This Object Needs To Be Converted To An Editable Mesh!!\n Convert It?" Title:"Conversion Required")
then converttomesh obj
else supportOk = false
)
if supportOk then
(
gmSupportObj = obj
Support_txt.text = gmSupportObj.name
if( (superclassof obj) == Shape )
then SupportVertsNum_txt.text = (numKnots gmSupportObj 1) as string
else SupportVertsNum_txt.text = gmSupportObj.verts.count as string
)
else
(
gmSupportObj = undefined
Support_txt.text = ""
SupportVertsNum_txt.text = ""
)
)
-- on getobj_but pressed do
-- max selection floater
on fromsel_but pressed do
(
if selection.count == 0 then
messagebox "Please, Select Some Objects" title:"No Objects Selected"
else
(
obj_list_array = #()
obj_name_array = #()
fill_obj_list_array()
ObjsNum_txt.text = obj_name_array.count as string
)
)
on obj_listbx doubleclicked obj_num do
(
select obj_list_array[obj_num]
)
on LinkToSupportChkbx changed stat do
(
if stat do
AttachmentChkbx.checked = false
)
on AttachmentChkbx changed stat do
(
if stat do
LinkToSupportChkbx.checked = false
)
on apply_but pressed do
(
local lbApplyPossible = true
if( 0 == obj_list_array.count ) do
(
messagebox "No Objects Selected for Scattering" title:"Warning"
lbApplyPossible = false
)
if( lbApplyPossible and "" == Support_txt.text ) do
(
messagebox "No Support Selected for Scattering" title:"Warning"
lbApplyPossible = false
)
if( lbApplyPossible and undefined == gmSysObj ) do
(
messagebox "No Coordinate System Selected for Scattering" title:"Warning"
lbApplyPossible = false
)
if( lbApplyPossible ) do
(
undo on
(
DistributeObjects DistribModDrpdwnList.selection
)
)
)
)
------------------------------------------------------------------------------------------
-- Advanced settings rollout
Rollout WkScatterAdvSettingsRoll "Advanced Settings"
(
-- buttons
group "Align Position "
(
label XLab "X :" align:#left offset:[-4,-5] ---18
checkbox AlignXChkbx "" offset:[13,-18] width:17 checked:true --enabled:false
label YLab "Y :" align:#left offset:[36,-20]
checkbox AlignYChkbx "" offset:[53,-18] width:17 checked:true --enabled:false
label ZLab "Z :" align:#left offset:[77,-20]
checkbox AlignZChkbx "" offset:[94,-18] width:17 checked:true --enabled:false
label CoordSysLab "Coord Sys:" align:#left offset:[-6,0]
dropdownlist CoordSysDrpdwn items:#("World","Support","Other") width:107 offset:[47,-21] --enabled:false "Local", selection:2
pickbutton SysObjPickbut "Pick" message:"Pick an Object for the Coordinate System" tooltip:"Pick an Object for the Coordinate System" filter:prs_sys_filt height:17 width:36 align:#left offset:[-5,0] enabled:false
edittext SysObjEdittxt "" text:"" width:120 align:#left offset:[32,-22] enabled:false
)
group "Groups "
(
checkbox IgnoreGpsChkbx "Ignore Groups" align:#left offset:[-5,-5]
)
-- events
on CoordSysDrpdwn selected sel do
(
case sel of
(
1: ( --World
SysObjPickbut.enabled = false
SysObjEdittxt.enabled = false
SysObjEdittxt.text = ""
gmSysObj = #world
)
2: ( --Support
SysObjPickbut.enabled = false
SysObjEdittxt.enabled = false
SysObjEdittxt.text = ""
if( gmSupportObj != undefined )
then gmSysObj = gmSupportObj
else
(
messagebox "Please Choose a Support First" title:"No Support Defined"
gmSysObj = #world
CoordSysDrpdwn.selection = 1
)
)
3: ( --other
SysObjPickbut.enabled = true
SysObjEdittxt.enabled = true
gmSysObj = undefined
)
)
)
on SysObjPickbut picked obj do
(
gmSysObj = obj
SysObjEdittxt.text = obj.name
)
)
------------------------------------------------------------------------------------------
--creation of the window, called WkScatterWin
If WkScatterWin != undefined do CloseRolloutFloater WkScatterWin
EnableSceneRedraw()
WkScatterWin = NewrolloutFloater "WkScatter - V 1.5" 187 336 0 90
Addrollout WkScatterMainRoll WkScatterWin
Addrollout WkScatterAdvSettingsRoll WkScatterWin rolledup:true
-- DestroyDialog WkScatterMainRoll
-- CreateDialog WkScatterMainRoll style:#( #style_minimizebox, #style_titlebar, #style_sysmenu )
)