' Drafting by Michael Isner.
' Gives the ability to switch between interactivly drawing lines
' and entering numerical values.  Allows absolute, relative, and 
' angle/distance.  For now it uses user input similar to AutoCAD.
' Hopefully this can be redone as interactive visual icons in the
' near future.
'
'<<javier@internarte.com modification
'<<until Michael modifies this in interactive visual icons here is
'<<a fix and an improvement
'<<fix: on the relative mode (@ least in my machine) the variables
'<< 		X1,Y1,Z1 got concatenated instead of added
'<<imp: 1.a nice feature of AutoCad is that one can type a curve in\
'<<		without touching the mouse... i fixed the script to do this.
'<< 	 2.	also enabled nurbs and interpolated nurbs drafting
'<<	 3. 	implemented undo point, close curve and xz drafting

dim force_x, force_y, force_z, X1, Y1, Z1, p, oldx, oldy, oldz
dim dist, angle, plane, pointnumber, curvetype, interpolation

p = 0
curvetype = Inputbox("Enter Curve type:"&chr(13)&"  'l' for linear"&chr(13)&"  'n' for nurbs"&chr(13)&"  'i' for interpolating nurbs","CURVETYPE", "l")

'>>>>jmod
	if curvetype = "n" or curvetype = "N" then 
		curvetype = 3
		interpolation = 0
	elseif curvetype = "i" or curvetype = "I" then 
		curvetype = 3
		interpolation = 1
	else 
		curvetype = 1
		interpolation = 1
	end if
'<<<end jmod
set curve = SICreateCurve ("crvlist", curvetype, interpolation)
selectobj curve
	
newpoint


pointnumber = 0 '<jmod
'-----------------------------------------------
sub newpoint
	if pointmechanism = True then newpoint
	end sub
'-----------------------------------------------
function pointmechanism
dim def
	p = p + 1
	pointmechanism = True
	PickPosition "Interactive point", "keyboard entry", X1, Y1, Z1, button_out
	if button_out <> 0 then	
		if button_out = 1 then
			if needpointdata = False then
				addpoint
			end if
		end if
		if button_out = 2 then
		
'>>>>>modified by j
			DO
				if pointnumber = 0 then
					def = "enter first point"
				elseif pointnumber = 1 then
					def = "@"
				elseif Isnumeric(left(raw_entry, 1))then
					def = ""
				else
					def = left(raw_entry, 1)
				end if
				raw_entry = inputbox ("Entry Examples:" & chr(13) & "ABSOLUTE x,y,z:               0,10,4" & chr(13) & "ABSOLUTE x,z:                  0,4" & chr(13) & "RELATIVE x,y,z:                @0,4,0" & chr(13) & "RELATIVE x,z:                   @0,4" & chr(13) & "Dist/Angle/plane               <1,-45,xy" & chr(13) & "Partial                                .x or .xy" & chr(13) & "Delete last point                 U" & chr(13) & "Close curve.                       C","DRAFTING",def,10,10)
			 	if raw_entry = "" then
			
			 EXIT DO
			 	else
					if parse(raw_entry) = True then
						if needpointdata = False then
							addpoint
						end if
					else 
						logmessage "error in cordinate entry - please enter again"
					end if
				end if
			LOOP
'<<<<<end modified by j

		end if 
	else
		pointmechanism = False
	end if
end function
'-----------------------------------------------
function needpointdata()
	' here we check if any of the force_x/y/z variables are
	' filled with "need".  If so we need another point and
	' needpointdata becomes "waiting" until another point is
	' entered. At this point the "waiting" fills force_x/y/z
	' which is kind of like an override.
	
	needpointdata = False
	
	if force_x = "waiting" then
		force_x = X1
		needpointdata = True	
	end if

	if force_y = "waiting" then
		force_y = Y1
		needpointdata = True	
	end if
	
	if force_z = "waiting" then
		force_z = Z1
		needpointdata = True	
	end if
	
	if force_x = "need" then
		force_x = "waiting"
		needpointdata = True	
	end if

	if force_y = "need" then
		force_y = "waiting"
		needpointdata = True	
	end if
	
	if force_z = "need" then
		force_z = "waiting"
		needpointdata = True	
	end if
 

end function
'-----------------------------------------------
function addpoint

	if force_x  <> "" then X1 = force_x
	if force_y  <> "" then Y1 = force_y
	if force_z  <> "" then Z1 = force_z

	SIAddPointOnCurveAtEnd curve, X1, Y1, Z1, False
	
	oldx = X1
	oldy = Y1
	oldz = Z1
	
	force_x = ""
	force_y = ""
	force_z = ""

	pointnumber = pointnumber + 1 		'<jmod
end function
'-------------------------------------------------
function parse (in_raw)

	parse = False
	in_raw = lcase(in_raw)
	
	'>>>>>>>>>>>>>>>>>>>>>>>>
	' jmod: this allows to Undo points
	'>>>>>>>>>>>>>>>>>>>>>>>>
	
	if in_raw = "u" or in_raw = "U" then
		SIDeletePointOnCurve curve, pointnumber-1
		pointnumber = pointnumber -1
	end if
	
	'>>>>>>>>>>>>>>>>>>>>>>>>
	' jmod: this allows to Close curves points
	'>>>>>>>>>>>>>>>>>>>>>>>>
	
	if in_raw = "c" or in_raw = "C" then
		ApplyTopoOp "CrvOpenClose", curve, 3, siPersistentOperation
	end if


	')))))))))))))))))))))))))
	' this part parses partial
	')))))))))))))))))))))))))
	
	if in_raw = ".x" then
		force_x = "need"
		parse = True
	end if
	
	if in_raw = ".y" then
		force_y = "need"
		parse = True
	end if
	
	if in_raw = ".z" then
		force_z = "need"
		parse = True
	end if
		
	if in_raw = ".xy" or in_raw = ".yx" then
		force_x = "need"
		force_y = "need"
		parse = True
	end if
	
	if in_raw = ".xz" or in_raw = ".zx" then
		force_x = "need"
		force_z = "need"
		parse = True
	end if 
	
	if in_raw = ".yz" or in_raw = ".zy" then
		force_y = "need"
		force_z = "need"
		parse = True
	end if
	
	')))))))))))))))))))))))))
	' this part parses relative
	')))))))))))))))))))))))))
	
	if left(in_raw, 1) = "@" then
		
		Set oRoot = ActiveProject.ActiveScene.Root
		'remove the @ and chop up
		raw2 = right(in_raw, len(in_raw) - 1)
		raw3 = split(raw2, ",", -1, 1)
		'	>jmod draft in xz plame

		if ubound(raw3) = 1 then 		
			valid1 = IsNumeric(raw3(0)) 
			valid2 = IsNumeric(raw3(1))
			Set oNul = oRoot.Addnull
			Translate  oNul, raw3(0), 0,  raw3(1)
			X0 = GetValue(oNul&".kine.global.posx") 
			Z0 = GetValue(oNul&".kine.global.posz") 
			deleteobj oNul
			X1 = oldx + X0
			Y1 = oldy
			Z1 = oldz + Z0
			parse = True
		end if
'	<jmod
		if ubound(raw3) = 2 then
			
			' make sure all three are numbers.
			valid1 = IsNumeric(raw3(0)) 
			valid2 = IsNumeric(raw3(1))
			valid3 = IsNumeric(raw3(2))
	
			if valid1 = True and valid2 = True and valid3 = True then
			
				'>>>jmod: here i fixed a variable definition problem
				'>>> 	i think that doing string ops on the raw() collection
				'>>>	screwed up things making it so that X1 became the concatenation
				'>>>	of oldx and raw(0) instead of the addition : fixed

				
				Set oNul = oRoot.Addnull
				Translate  oNul, raw3(0), raw3(1),  raw3(2)
				X0 = GetValue(oNul&".kine.global.posx")
				Y0 = GetValue(oNul&".kine.global.posy") 
				Z0 = GetValue(oNul&".kine.global.posz")  
				deleteobj oNul
				X1 = oldx + X0
				Y1 = oldy + Y0
				Z1 = oldz + Z0
'<<<jmod: end
				parse = True
			end if
			
		end if
	end if
	
		
	')))))))))))))))))))))))))
	' this part parses angle, distance, plane
	')))))))))))))))))))))))))
	
	'Dist/angle/plane ->  <1,-45,xy
	
	if left(in_raw, 1) = "<" then
	
		'remove the "<" and chop up
		raw2 = right(in_raw, len(in_raw) - 1)
		raw3 = split(raw2, ",", -1, 1)


		
		'check the first two pieces are numeric
		valid1 = IsNumeric(raw3(0)) 
		valid2 = IsNumeric(raw3(1))
	
		if valid1 = True and valid2 = True then
			'now check for plane
			plane = raw3(2)
			if plane = "xy" or plane = "yx" or plane = "xz" or plane = "xz" or plane = "yz" or plane = "zy" then
			
				dist = raw3(0)
				angle = raw3(1)
 				
				'latley I just do this kind of stuff with temp geometry instead of 
				'math because it's so fast to rough out and check for errors.
				
				set pnull = GetPrim ("Null")
				set cnull = GetPrim ("Null")
				parentObj pnull, cnull
				    
				'Translate pnull & "+", oldx, oldy, oldz, siGlobal, siLocal, siObj, siXYZ
				
				SetValue(pnull & ".kine.global.posx"), oldx
				SetValue(pnull & ".kine.global.posy"), oldy
				SetValue(pnull & ".kine.global.posz"), oldz
				
				if plane = "xy" or plane = "yx" then						
					'rotate on the z, translate locally on the x
					SetValue pnull & ".kine.local.rotz", angle
					SetValue cnull & ".kine.local.posx", dist
					X1 = GetValue(cnull & ".kine.global.posx")
					Y1 = GetValue(cnull & ".kine.global.posy")
					Z1 = GetValue(cnull & ".kine.global.posz")
				end if

				if plane = "xz" or plane = "zx" then						
					'rotate on the y, translate locally on the x
					SetValue pnull & ".kine.local.roty", angle
					SetValue cnull & ".kine.local.posx", dist
					X1 = GetValue(cnull & ".kine.global.posx")
					Y1 = GetValue(cnull & ".kine.global.posy")
					Z1 = GetValue(cnull & ".kine.global.posz")
				end if

				if plane = "yz" or plane = "zy" then						
					'rotate on the x, translate locally on the -z
					SetValue pnull & ".kine.local.rotx", angle
					SetValue cnull & ".kine.local.posz", dist * -1
					X1 = GetValue(cnull & ".kine.global.posx") 
					Y1 = GetValue(cnull & ".kine.global.posy") 
					Z1 = GetValue(cnull & ".kine.global.posz") 					
				end if
						
				DeleteObj cnull
				DeleteObj pnull
				SelectObj curve '<jmod
				parse = True
				
			end if			
		end if
	end if
	
	
	')))))))))))))))))))))))))
	' this part parses absolute
	')))))))))))))))))))))))))
	
	raw3 = split(in_raw, ",", -1, 1)
	
	
	if ubound(raw3) = 1 then
		
		' make sure all three are numbers.
		valid1 = IsNumeric(raw3(0)) 
		valid2 = IsNumeric(raw3(1))
		
	
		if valid1 = True and valid2 = True then
			X1 = raw3(0)
			Y1 = oldy
			Z1 = raw3(1)
			parse = True
		end if
			
	end if

		
	if ubound(raw3) = 2 then
		
		' make sure all three are numbers.
		valid1 = IsNumeric(raw3(0)) 
		valid2 = IsNumeric(raw3(1))
		valid3 = IsNumeric(raw3(2))
	
		if valid1 = True and valid2 = True and valid3 = True then
			X1 = raw3(0)
			Y1 = raw3(1)
			Z1 = raw3(2)
			parse = True
		end if
			
	end if
		
end function
'-------------------------------------------------

