### Keep up-to-date with Free tutorials!!

Sign me up to receive third-party emails from 3dtotal's partners, too!

- Latest news
- Exclusive Shop Offers
- Preview early content
- Plus much more

Not Ready to take that step? OK, Why not just Subscribe to the RSS Feed

1 | 2 | 3
Developing a Scripted Utility

By Sathish Shanmugasundaram
| 31844 Views
| 0
Software used:

## Normal

Surface normal or normal is a vector perpendicular to the surface (Fig04).

Fig. 04 - NormalExample1

Utility ObjPlacer "Object Palcer"
(
Local copyState=1,sourceObj,destinationObj

fn Align souCopy desNormal pos =
(
worldUpVector = [0,0,1]

rightVector = normalize (cross worldUpVector desNormal)
upVector = normalize ( cross rightVector desNormal)
theMatrix = matrix3 rightVector upVector desNormal Pos

souCopy.transform = theMatrix

)

fn CopySource numCopies=
(
case copyState of
(
1:
souCpy = for i = 1 to numCopies  collect(copy sourceObj)
2:
souCpy = for i = 1 to numCopies  collect(instance sourceObj)
default:
souCpy = for i = 1 to numCopies  collect(reference sourceObj)
)

return souCpy
)
(
Label lab1 "Object Placer"
Label lab2 "By Sathish"
Label lab3 "Mail:[email protected]"
)
rollout Param "Parameters"
(

pickButton sourcePikBtn "Source" width:75 autoDisplay:true
pickButton destnationPikBtn "Destination" width:75

checkBox vertexChkBox "Vertex" checked:true
checkBox polygonChkBox "Polygon"

group "Copy option"
(

radioButtons copyOption labels:#("Copy", "Instance", "Reference") align:#left default:1
)
on sourcePikBtn picked sObj do
(
if  sObj != undefined then
sourceObj=sObj
)
on destnationPikBtn picked dObj do
(

if(sourceObj != undefined) and (not isDeleted sourceObj) then
(
if(vertexChkBox.state == true or polygonChkBox.state == true) then
(
if dObj!= undefined then
(
destinationObj=dObj
If ((classOf destinationObj) == Editable_poly) then
(

if (polygonChkBox.state == true) then
(
numPolygon = destinationObj.getnumfaces()

Source =CopySource numPolygon

for i = 1 to numPolygon do
(
faceCentre= polyOp.getFaceCenter destinationObj i
faceNormal = polyOp.getFaceNormal destinationObj i

Align source[i] faceNormal faceCentre
)
)
if (vertexChkBox.state == true) then
(
numVertex = destinationObj.getNumVertices()

source =CopySource numVertex
editNormalsModifier=edit_Normals()

destinationVertex = #{}
destinationNormalIds = #{}

for i = 1 to numVertex do
(
select destinationObj
destinationVertex = #{i}

destinationObj.edit_Normals.convertVertexSelection &destinationVertex &destinationNormalIds

normalArray = destinationNormalIds as array

firstNormalValue = destinationObj.edit_Normals.getNormal normalArray[1]
vertexPos= polyOp.getVert destinationObj i

Align source[i]  firstNormalValue vertexPos
)

deleteModifier destinationObj(editNormalsModifier)
)

)
else
messageBox "Select only Editable poly object" title:"Error"
)
)
else
messageBox "Select Vertex or/and Polygon" title:"Error"
)
else
messageBox "Select Source Object" title:"Error"
)
on copyOption changed State do
(
copyState=State
)

)
on ObjPlacer open do
(
)
on ObjPlacer  close do
(
removeRollout Abt
removeRollout Param
)
)

## Script Explanation

utility ObjPlacer "Object Placer"

A Utility is created using a constructor utility with name ObjPlacer and caption Object Placer.

Local copyState=1,sourceObj,destinationObj

Local variables are alive untill we close the utility is closed.

NOTE: Align and CopyOption functions are explained below.

A rollout named Abt with caption "About" is defined.

Label lab1 "Object Placer"
Label lab2 "By Sathish"
Label lab3 "Mail:[email protected]"

Labels are used to display information and it could not be altered. (If u need syntax details refer MaxScript reference).

## Parameter rollout

pickButton sourcePikBtn "Source" width:75 autoDisplay:true
pickButton destnationPikBtn "Destination" width:75

Two pick buttons with caption Source and Destination is created with width =75. In Source pick button autoDisplay is enabled to display selected objects name as button caption.

checkBox vertexChkBox "Vertex" checked:true
checkBox polygonChkBox "Polygon"

Two checkboxes for Vertex and Polygon is created. Initially Vertex check box is enabled.

group "Copy option"
(
radioButtons copyOption labels:#("Copy", "Instance", "Reference") align:#left default:1
)

A group with three radio buttons for selecting copy type such as Copy, References or Instance is created. Radio buttons are aligned left in group box and Copy is set as default.

on sourcePikBtn picked sObj do
(
if sObj != undefined then
sourceObj=sObj
)

This function will be called when source pick button picked. It checks whether object selected or the operation cancelled, after clicking pick button.

If selected then assign it to a global variable.

on destnationPikBtn picked dObj do
(
if(sourceObj != undefined) and (not isDeleted sourceObj) then
(
if(vertexChkBox.state == true or polygonChkBox.state == true) then
(
if dObj!= undefined then
(
destinationObj=dObj
If ((classOf destinationObj) == Editable_poly) then
(
..............................
..............................
..............................
)
else
messageBox "Select only Editable poly object" title:"Error"
)
)
else
messageBox "Select Vertex or/and Polygon" title:"Error"
)
else messageBox "Select Source Object" title:"Error"

Following operation will took place when destination pick button is picked.

Check whether Source object already selected and not deleted else display message " Select Source Object".

Check whether vertex and/or polygon checkbox checked else display message "Select Vertex or/and Polygon"

Check whether destination object is picked after clicking destination button or the operation is cancelled.

Check whether selected object is Editable poly, else displays message "Select only Editable Poly object".

If polygon checkbox is checked then following operation will took place.

numPolygon = destinationObj.getnumfaces()
Source =CopySource numPolygon

Get number polygons in destination object.

Get copies of source object according to number of polygons in destination object and store it into an array.

for i = 1 to numPolygon do
(
faceCentre= polyOp.getFaceCenter destinationObj i
faceNormal = polyOp.getFaceNormal destinationObj i
Align source[i] faceNormal faceCentre
)

Iterate from 1 to numPolygon.

Get face centre and face normal of i th polygon in destination object.

Call Align function by passing i th copy of source object, face center and face normal of i th polygon in destination object.

End of iteration.

The following operation will took place when vertex check box checked

numVertex = destinationObj.getNumVertices()
source =CopySource numVertex
editNormalsModifier=edit_Normals()
destinationVertex = #{}
destinationNormalIds = #{}

For getting normal of vertex, we need to do some more work

Get number of vertices in destination object.

Make copies of source object equal to number of vertices, by calling CopySource function.

Add Edit Normals modifier to Destination object.

Set modify panel to be the active panel in the view port. We can get normal value only when modify panel is active and destination object is selected.

Declare two bit array for representing destination vertex and its normals.

for i = 1 to numVertex do
(
select destinationObj
destinationVertex = #{i}
destinationObj.edit_Normals.convertVertexSelection &destinationVertex &destinationNormalIds
normalArray = destinationNormalIds as array
firstNormalValue = destinationObj.edit_Normals.getNormal normalArray[1]
vertexPos= polyOp.getVert destinationObj i
Align source[i] firstNormalValue vertexPos
)

Iterate from 1 to number of vertex

Select destination object. As I said already we can get normal value only when modify panel is active and destination object is selected.

Make the vertex bit array to represent i th vertex.

Get normas(normal Id's) available in vertex i. Single vertex may contain more than one normal See fig below (vertex 7 contains 3 normals with Id 8, 19, 24.)

Store array of destinationNormals to normalArray, because destinationNormals is bit array. In bit array the corresponding bit value is set to true and all other values are set to false, but in this case we need normal Id. For example consider figure below, for 7 th vertex the bit values 8 ,18, 24 are set to true. If we convert bit array to an array we can get Id value 8 at normalArray[1].

firstNorml retrieves actual vector value of the first normal in the vertex. In below fig firstNormal =[0,0,1] for normal 8.

Get Position of i th vertex.

Call function Align by passing i th copy of Source object, normal and position of destination objects i th vertex (Fig05).

Fig. 05 - NormalExample2

## < previous page continued on next page >

1 | 2 | 3
Related Tutorials

Tutorial

Making of Post Apocalyptic Zombie Hunter

Keywords: Humam Munir, 3ds Max, ZBrush, vehicle, making of

(14)
2 12544

Tutorial

Learn how to shoot your Clone Trooper

Keywords: Nicolas Brunet, clone, star wars, 3ds Max, making of

0 11549

Tutorial

Concept design workflow

Keywords: Efflam Mercier, 3ds Max, Photoshop, making of

0 18721

Tutorial

The making of 'Furiosa'

Keywords: Fellipe Beckman, 3ds Max, ZBrush, making of

0 13859