utility ObjPlacer "Object Palcer"        		--  Utility constructor is defined
 (
	local copyState=1,sourceObj,destinationObj	-- local variables declaration(these varaibles are available till closing the utility)
   
   	-- function Align with a source object copy, face or vertex normal and position in Desination object 
fn Align souCopy desNormal pos =	
(											-- FOR MORE DETAILS ABOUT THESE FUNCTION SEE THEOY SECTION   	

   worldUpVector = [0,0,1]					-- the default value of World up vector 
											
   rightVector = normalize (cross worldUpVector desNormal) 	-- calculate right vector from worldup vector and Normal
   
   upVector = normalize ( cross rightVector desNormal) 		-- calculate local up vector from right vector and Normal

   theMatrix = matrix3 rightVector upVector desNormal Pos 	-- store rightVector upVector desNormal Pos as matrix3  
 
   souCopy.transform = theMatrix 						   	-- set source copy transformation=theMatrix
  
)	-- end of Align function 
  


fn CopySource numCopies=						-- function CopySource with numCopies(Number of copies) 
    (
	  case copyState of 						-- case state of copy option radio buttons   
	   ( 
	    1:								-- if copy is selected 
	   		    souCpy = for i = 1 to numCopies  collect(copy sourceObj) 		--store  num copies to souCopy array 
 	    2:								--if instance is selected 
	   	        souCpy = for i = 1 to numCopies  collect(instance sourceObj)	--store  num Instances to souCopy array
 	    default:						--if references is selected 
	            souCpy = for i = 1 to numCopies  collect(reference sourceObj) 	--store  num references to souCopy array
	   )
	 return souCpy	-- return array of source object copy
	)	--end of CopySource function 


  rollout Abt "About"       		-- create rollout "About"
  (
    Label lab1 "Object Placer"   	-- add labels to the rollout   
    Label lab2 "By Sathish"    
    Label lab3 "Mail:Sathish101@gmail.com"
  )									


  rollout Param "Parameters"									-- create rollout "Parameters"
  (
    				-- add  pick button with caption "Source" and width 75. Autodisplay is to diplay picked object's name as button caption. 
	pickButton sourcePikBtn "Source" width:75 autoDisplay:true  
    pickButton destnationPikBtn "Destination" width:75			-- add another pick button "Destination"
    
	checkBox vertexChkBox "Vertex" checked:true					-- add check box for Vertex and initially checked            
    checkBox polygonChkBox "Polygon" 							-- add another check box for Polygon
    
	group "Copy option"											-- create a group with caption "Copy Option"
      (
									-- add 3 radio buttons for copy options Copy, Instace or Reference and Copy is initialy selected	
	  radioButtons copyOption labels:#("Copy", "Instance", "Reference") align:#left default:1 	
	  )
 

   on sourcePikBtn picked sObj do	-- called when "Source" pick button Picked
    ( 
      if  sObj != undefined then	-- if object picked
	 	  sourceObj=sObj			-- assigns Selected object to anoter variable sourceObj 
	)


  on destnationPikBtn picked dObj do      									-- called when "Destination" pick button Picked
    (
 	
	  if(sourceObj != undefined) and (not isDeleted sourceObj) then 		-- if Source object already selected and not deleted 
	  (
	  if(vertexChkBox.state == true or polygonChkBox.state == true) then	--if vertex and/or Polygon checked
	  (	 
	  if dObj!= undefined then 	-- if destination object picked
       (
		 destinationObj=dObj	-- assign destination object to another variable destinationObj
		 If ((classOf destinationObj) == Editable_poly) then  	--if selected object is editable poly
			(
			 
  			 if (polygonChkBox.state == true) then 				-- if Polygon checkbox checked
			   (
			    numPolygon = destinationObj.getnumfaces()  		-- get number of polygos in destination object
				
							-- call function CopySource by passing number of copies needed  and collect copies the in an array.				
				Source =CopySource numPolygon					
	       	    
				for i = 1 to numPolygon do						-- iterate from 1 to number of Polygons	
			 	  (
		 		  faceCentre= polyOp.getFaceCenter destinationObj i		-- get ith polygon center in destination object 
				  faceNormal = polyOp.getFaceNormal destinationObj i 	-- get ith polygon normal in destination object  

				  			-- call function Align by passing ith Source object,ith Normal and polygon Center of destination object
				  Align source[i] faceNormal faceCentre  
				  )	-- end of for loop
				) 	-- end of If Polygon checkbox checked		 	

		    if (vertexChkBox.state == true) then 			 	-- if vetex check box checked
			   (
			    numVertex = destinationObj.getNumVertices() 	-- get number of vertices in destination object

										-- call function CopySource by passing number of copies needed  and collect copies the in an array. 	
				source =CopySource numVertex 
	            editNormalsModifier=edit_Normals()		 		-- assign edit_Normals modifier to a variable	       
			
			     addModifier destinationObj editNormalsModifier --add edit_Normals modifier to the destination object 
							
						-- set Modifier panel to be the active panel (Because the normal value can be get only when modifier panel is active)  
      			 setCommandPanelTaskMode #modify  
		 		 destinationVertex = #{}		  -- declare bit array for vertex 
				 destinationNormalIds = #{}		  -- declare another bitarray  to get normals of vertex
				 
				 for i = 1 to numVertex do		  -- itrate 1 to number of vertices(in destination object)
			 	  (
					select destinationObj		  -- select destination object 
					destinationVertex = #{i}	  -- make bit array to represents vertex i 
						
												  -- obtain normals Id's availabel at vertex i(contains one or more normals)  
  					destinationObj.edit_Normals.convertVertexSelection &destinationVertex &destinationNormalIds	
												  
												  -- store bit array into an array (In order to get first normal value) 
  				    normalArray = destinationNormalIds as array 
												  
												  -- get normalvalue(normalId(normalArray[1]))) 	
					firstNormalValue = destinationObj.edit_Normals.getNormal normalArray[1]
					vertexPos= polyOp.getVert destinationObj i	-- get position of the vertex i
		
						/* call function Align by passing ith source object copy,normal value and position of  
						   ith vertex in destination object */			 	
					Align source[i]  firstNormalValue vertexPos	
		     	  ) -- end of for loop
				  
				deleteModifier destinationObj(editNormalsModifier) 	--delete already added edit_Normals modifier 
				) 	-- end of If vetex checkbox checked
   	       	
      		 ) -- end of if destinationObj=editable_poly
			 else
	   			messageBox "Select only Editable poly object" title:"Error"
		) 	-- end of if dObj!= undefined 
         )  -- end of if sourceObj != undefined and (not isDeleted sourceObj)
		 else
				messageBox "Select Vertex or/and Polygon" title:"Error"
	    )	-- end of Vertex And/or Polygon checked
		 else
				messageBox "Select Source Object" title:"Error"   	

	) -- end of  destnation pick button picked function


on copyOption changed State do 	-- on copyOption(Copy option radiobuttons) changed
  (
   copyState=State		  	   	-- store current state to copyState variable 
  )
  
 )	--end of "Parameter" rollout


on ObjPlacer open do     -- on ObjectPlacer Utility opened 
(
 addRollout Abt			 -- add rollout "About"
 addRollout Param 		 -- add rollout "Parametrer"
 ) 


 on ObjPlacer  close do	  -- on ObjectPlacer Utiity closed 
 (
  removeRollout Abt		  -- remove rollout "About"
  removeRollout Param	  -- remove rollout "Parameter"
 )

)	-- end of Utility 	  
