/* CMD: ½ModifyObject                                                   */
/* By Brett Evan Hester      13032 Copenhill Rd. Dallas, Tx. 75240-5302 */
	MacrosName = "ModifyObject"
/* Macro Type:                                                          */
/* MODIFIES    * OBJECTS   * BKG NEEDED   * SELECTED     * REMEMBERS    */
/* Description:                                                         */

Info1A = "!Modify Object ©               Information 1 of 6"
Info1B = ""
Info1C = "@This macro will modify the currently selected,  "
Info1D = "@given formulas for the position of each point.  "
Info1E = ""
Info1F = "@þ Variables based on each pnts coords.:         "
Info1G = "          X              Y                Z     "
Info1H = "@þ Variables based on current layer:             "
Info1I = "LeftEdge  or X1  CenterX or CX  RightEdge or X2 "
Info1J = "LowerEdge or Y1  CenterY or CY  UpperEdge or Y2 "
Info1K = "FrontEdge or Z1  CenterZ or CZ  BackEdge  or Z2 "
Info1L = "Width     or TX  Height  or TY  Depth     or TZ "
Info1M = "DiffX     or DX  DiffY   or DY  DiffZ     or DZ "
Info1N = "@More INFORMATION and VARIABLES on follow...     "

Info2A = "!Modify Object ©               Information 2 of 6"
Info2B = ""
Info2C = "@þ Variables based on current background layer:  "
Info2D = "BKGLeft  / BX1  BKGCenterX / BCX  BKGRight / BX2"
Info2E = "BKGLower / BY1  BKGCenterY / BCY  BKGUpper / BY2"
Info2F = "BKGFront / BZ1  BKGCenterZ / BCZ  BKGBack  / BZ2"
Info2G = "BKGWidth / BTX  BKGHeight  / BTY  BKGDepth / BTZ"
Info2H = "BKGDiffX / BDX  BKGDiffY   / BDY  BKGDiffZ / BDZ"
Info2I = '@Note:"Diff" stands for the difference between   '
Info2J = "@      the coord. and the layer's center.        "
Info2K = ""
Info2L = "@½ Any variable can be used in any equation. ¼"
Info2M = ""
Info2N = "@More INFORMATION and VARIABLES on follow...     "

Info3A = "!Modify Object ©               Information 3 of 6"
Info3B = ""
Info3C = "@þ Constants:                                    "
Info3D = '  Type "PI" to get 3.141592653589793238462643   '
Info3E = '  Type "Eunit" for 2.718281828459045235360287   '
Info3F = ""
Info3G = "@¤ Constants for conversion purposes:            "
Info3H = "þ 8 length constants are included, multiply by -"
Info3I = "  MtToFt, MtToIn, KmToMl, KmToFt, & the reverse "
Info3J = "þ 6 speed constants are included, multiply by - "
Info3K = "  KPHToMPH, KPHToFPS, MPHToFPS, and the reverse "
Info3L = "þ 2 angle constants are included, multiply by - "
Info3M = "  DegToRad or RadToDeg                          "
Info3N = "@Information on commands and usage to follow... "

Info4A = "!Modify Object ©               Information 4 of 6"
Info4B = ""
Info4C = "@þ Commands:                                     "
Info4D = "  SQRT(x) = Square Root  ABS(x)  = Absolute     "
Info4E = "  FACT(x) = Factorial    NINT(x) = Rounds off   "
Info4F = ""
Info4G = "@¤ Commands involving angle calculations:        "
Info4H = "  SIN(x°)    ASIN(x°)    SINH(x°)    ASINH(x°)  "
Info4I = "  COS(x°)    ACOS(x°)    COSH(x°)    ACOSH(x°)  "
Info4J = "  TAN(x°)    ATAN(x°)    TANH(x°)    ATANH(x°)  "
Info4K = ""
Info4L = "@NOTE: The computer calculates angles in radians."
Info4M = "@If you are suppling the angles in degrees, type "
Info4N = "@ALT-W (°) after the angle. This equals DegToRad."

Info5A = "!Modify Object ©               Information 5 of 6"
Info5B = ""
Info5C = "@þ Arithmetic operations and their priority:     "
Info5D = "@Operator           Priority  Example      Result"
Info5E = "+  (prefix conversion) 8     '3.12'       3.12  "
Info5F = '-  (prefix negation)   8     -"3.12"      -3.12 '
Info5G = "** (exponentiation)    7     0.5 ** 3     0.125 "
Info5H = "*  (multiplication)    6     1.5 * 1.50   2.250 "
Info5I = "/  (division)          6     6 / 3        2     "
Info5J = "%  (integer division)  6     -8 % 3       -2    "
Info5K = "// (remainder)         6     5.1 // 0.2   0.1   "
Info5L = "+  (addition)          5     3.1 + 4.05   7.15  "
Info5M = "-  (subtraction)       5     5.55 - 1     4.55  "
Info5N = "@((((( Use Parentheses When Ever Necessary. )))))"

Info6A = "!Modify Object ©               Information 6 of 6"
Info6B = "@               Plug-Ins and Go! ©               "
Info6C = "                           Hester and associates"
Info6D = "                           13032 Copenhill Road "
Info6E = "                           Dallas, Texas 75240  "
Info6F = "@Special Thanks to:                              "
Info6G = "Arnie Cachelin  Henry Ribron    Mark J. Holland "
Info6H = "J. Phil Kelso   Terry Wester    Steven K. Simms "
Info6I = "Kevin DeRita    Greg Glaser     William S. Hawes"
Info6J = "NewTek ©        Commodore ©     INOVAtronics ©  "
Info6K = ""
Info6L = "@This macro represents a lot of time & hard work."
Info6M = "@Encourage people to create new ones and not kill"
Info6N = "@that possibility by stealing those that are out."

/* -------------------------------------------------------------------- */
                                     /* Start Error Detection (See End) */
SIGNAL ON ERROR
SIGNAL ON SYNTAX
                                                   /* Address LightWave */
VT3DLib = ADDLIB("LWModelerARexx.port",0)
ADDRESS "LWModelerARexx.port"
                                                  /* Add Math Functions */
MATHLIB= "rexxmathlib.library"
IF POS(MATHLIB , SHOW('L')) = 0 THEN
    IF ~ADDLIB(MATHLIB , 0 , -30 , 0) THEN DO
    	CALL Notify(1,"!Can't find "MATHLIB)
		IF VT3DLib THEN CALL REMLIB("LWModelerARexx.port")
		EXIT
	END

/* -------------------------------------------------------------------- */
                                                     /* Fixed Variables */
PI = 3.141592653589793238462643
EUnit = 2.718281828459045235360287
                                                    /* Angle Conversion */
RadToDeg = 180 / PI  ; DegToRad = PI / 180
                                                 /* Distance Conversion */
MtToFt = 3.280833    ; FtToMt = 0.3048006
MtToIn = 39.370079   ; InToMt = 0.02540005
KmToMl = 0.621371    ; MlToKm = 1.60935
KmToFt = 3280.839895 ; FtToKm = 0.000305
                                                    /* Speed Conversion */
KPHToMPH = 0.621371  ; MPHToKPH = 1.609344
KPHToFPS = 0.911344  ; FPSToKPH = 1.09728
MPHToFPS = 1.466667  ; FPSToMPH = 0.681818

/* -------------------------------------------------------------------- */
                                               /* Info On Current Layer */
CL = CurLayer()
Box = BoundingBox(CL)
PARSE var Box N X1 X2 Y1 Y2 Z1 Z2

CX = (X1 / 2) + (X2 / 2)
CY = (Y1 / 2) + (Y2 / 2)
CZ = (Z1 / 2) + (Z2 / 2)

LeftEdge = X1  ; CenterX = CX ; RightEdge = X2
LowerEdge = Y1 ; CenterY = CY ; UpperEdge = Y2
FrontEdge = Z1 ; CenterZ = CZ ; BackEdge = Z2

TX = X2 - X1   ; Width = TX
TY = Y2 - Y1   ; Height = TY
TZ = Z2 - Z1   ; Depth = TZ
                                                   /* Info On BKG Layer */
BL = CurBLayer()
Box = BoundingBox(BL)
PARSE var Box N BX1 BX2 BY1 BY2 BZ1 BZ2

BCX = (BX1 / 2) + (BX2 / 2)
BCY = (BY1 / 2) + (BY2 / 2)
BCZ = (BZ1 / 2) + (BZ2 / 2)

BKGLeft = BX1   ; BKGCenterX = BCX ; BKGRight = BX2
BKGLower = BY1  ; BKGCenterY = BCY ; BKGUpper = BY2
BKGFront = BZ1  ; BKGCenterZ = BCZ ; BKGBack = BZ2

BTX = BX2 - BX1 ; BKGWidth = BTX
BTY = BY2 - BY1 ; BKGHeight = BTY
BTZ = BZ2 - BZ1 ; BKGDepth = BTZ

/* -------------------------------------------------------------------- */
                                    /* Reading Global Macro Preferences */
BEHDefaultFilePath = "Sys:"
BEHSettingsSavedTo = "T:"
BEHSpeechAndSound = "1"

IF (EXISTS("S:PlugInPrefs")) THEN DO
	IF (~OPEN(PlugInPrefs, "S:PlugInPrefs", 'R')) THEN BREAK
	IF (READLN(PlugInPrefs) ~= "PlugInPrefs") THEN BREAK
	BEHDefaultFilePath = READLN(PlugInPrefs)
	BEHSettingsSavedTo = READLN(PlugInPrefs)
	BEHSpeechAndSound = READLN(PlugInPrefs)
	CALL CLOSE PlugInPrefs
END

/* -------------------------------------------------------------------- */
                                            /* Recalling Macro Settings */
ReqX = "X"
ReqY = "Y"
ReqZ = "Z"

PrefsFileName = BEHSettingsSavedTo||MacrosName||".PLUG"

IF (EXISTS(PrefsFileName)) THEN DO
	IF (~OPEN(PrefsFile, PrefsFileName, 'R')) THEN BREAK
	IF (READLN(PrefsFile) ~= MacrosName) THEN BREAK

	ReqX = READLN(PrefsFile)
	ReqY = READLN(PrefsFile)
	ReqZ = READLN(PrefsFile)

	CALL CLOSE PrefsFile
END

/* ******************************************************************** */
                                                   /* Main Body Of Code */
MainBodyOfCode:

	CALL MenuRequester
	CALL SaveSettings
	CALL TransformObject
	CALL Exiting

RETURN

/* ******************************************************************** */
                                                      /* User Interface */
MenuRequester:

	CALL Req_Begin"Modify Object ©                   by Brett Hester"

	ReqA = Req_AddControl("Position X (X)",'S',33)
	ReqB = Req_AddControl("Position X (Y)",'S',33)
	ReqC = Req_AddControl("Position X (Z)",'S',33)
	ReqD = Req_AddControl("",'CH',"Information")

	CALL Req_SetVal(ReqA, ReqX)
	CALL Req_SetVal(ReqB, ReqY)
	CALL Req_SetVal(ReqC, ReqZ)
	CALL Req_SetVal(ReqD, 0)

	OKorCancel = Req_Post() ; IF OKorCancel = 0 THEN CALL Exiting

	ReqX = Req_GetVal(ReqA)
	ReqY = Req_GetVal(ReqB)
	ReqZ = Req_GetVal(ReqC)
	BEHInfo = Req_GetVal(ReqD)

	CALL Req_End()

	IF BEHInfo = 1 THEN CALL InformationWindows

RETURN

/* -------------------------------------------------------------------- */
                                                 /* Transforming Object */
TransformObject:

	N = XFrm_Begin()
	CALL Meter_Begin N, "Transforming Object..."
	DO i = 1 to N
		PARSE value XFrm_GetPos(i) with X Y Z .

		DX = X - CX    ; DY = Y - CY    ; DZ = Z - CZ
		BDX = X - BCX  ; BDY = Y - BCY  ; BDZ = Z - BCZ
		DiffX = DX     ; DiffY = DY     ; DiffZ = DZ
		BKGDiffX = BDX ; BKGDiffY = BDY ; BKGDiffZ = BDZ
		CNT = i

		CALL UsingDegrees(ReqX) ; INTERPRET "X = "||Formula
		CALL UsingDegrees(ReqY) ; INTERPRET "Y = "||Formula
		CALL UsingDegrees(ReqZ) ; INTERPRET "Z = "||Formula

		CALL XFrm_SetPos i, X Y Z
		CALL Meter_Step
	END
	CALL Meter_End
	CALL XFrm_End

RETURN

/* -------------------------------------------------------------------- */
                           /* Structuring Formulas with Degree symbols  */
UsingDegrees:

	PARSE arg Formula

	QAAngle = 1
	DO UNTIL QAAngle = 0
		QAAngle = POS("°", Formula)
		IF QAAngle ~= 0 THEN DO
			FormulaLength = LENGTH(Formula)
			PartA = LEFT(Formula, QAAngle - 1)
			PartB = RIGHT(Formula, FormulaLength - QAAngle)
			Formula = PartA||" * "||DegToRad||PartB
		END
	END

RETURN

/* -------------------------------------------------------------------- */
                                                       /* Save Settings */
SaveSettings:

	IF (OPEN(PrefsFile, PrefsFileName, 'W')) THEN DO
		CALL WRITELN(PrefsFile, MacrosName)

		CALL WRITELN(PrefsFile, ReqX)
		CALL WRITELN(PrefsFile, ReqY)
		CALL WRITELN(PrefsFile, ReqZ)

		CALL CLOSE PrefsFile
	END

RETURN

/* -------------------------------------------------------------------- */
                                                              /* Ending */
Exiting:

	IF (VT3DLib) THEN CALL REMLIB("LWModelerARexx.port")
	EXIT

RETURN

/* -------------------------------------------------------------------- */
                                                 /* Information Windows */
InformationWindows:

	OKorCancel = Notify(2, Info1A, Info1B, Info1C, Info1D, Info1E, Info1F, Info1G, Info1H, Info1I, Info1J, Info1K, Info1L, Info1M, Info1N)
	IF OKorCancel = 1 THEN OKorCancel = Notify(2, Info2A, Info2B, Info2C, Info2D, Info2E, Info2F, Info2G, Info2H, Info2I, Info2J, Info2K, Info2L, Info2M, Info2N)
	IF OKorCancel = 1 THEN OKorCancel = Notify(2, Info3A, Info3B, Info3C, Info3D, Info3E, Info3F, Info3G, Info3H, Info3I, Info3J, Info3K, Info3L, Info3M, Info3N)
	IF OKorCancel = 1 THEN OKorCancel = Notify(2, Info4A, Info4B, Info4C, Info4D, Info4E, Info4F, Info4G, Info4H, Info4I, Info4J, Info4K, Info4L, Info4M, Info4N)
	IF OKorCancel = 1 THEN OKorCancel = Notify(2, Info5A, Info5B, Info5C, Info5D, Info5E, Info5F, Info5G, Info5H, Info5I, Info5J, Info5K, Info5L, Info5M, Info5N)
	IF OKorCancel = 1 THEN CALL Notify(1, Info6A, Info6B, Info6C, Info6D, Info6E, Info6F, Info6G, Info6H, Info6I, Info6J, Info6K, Info6L, Info6M, Info6N)
	CALL MenuRequester

RETURN

/* -------------------------------------------------------------------- */
                                                      /* Error Handling */
SYNTAX:
ERROR:

	ErrCode = RC
	ErrLine = SIGL
	ErrInfo = ERRORTEXT(ErrCode)

	Err1 = "!Sorry!"
	Err2 = "An Error has been detected"
	Err3 = "@þ Macro -            "
	Err4 = "@þ Line Number -      "
	Err5 = "@þ Error Code -       "
	Err6 = "@þ Error Description -"
	Err7 = "@¤ Please Inform -    "
	Err8 = '  "Error Notice"     '
	Err9 = "  13032 Copenhill Rd."
	Err10 = "  Dallas, TX. 75240  "

	Call Notify(1,Err1,Err2,Err3,MacrosName,Err4,ErrLine,Err5,ErrCode,Err6,ErrInfo,Err7,Err8,Err9,Err10)

/* -------------------------------------------------------------------- */
                                             /* Advanced Error Handling */
	CALL SETCLIP("ErrorMacro",MacrosName)
	CALL SETCLIP("ErrorLine",ErrLine)
	CALL SETCLIP("ErrorCode",ErrCode)
	CALL SETCLIP("ErrorDesc",ErrInfo)

	PARSE SOURCE TempA TempB ErrFile TempC TempD TempE

	CALL SETCLIP("ErrorFile",ErrFile)

/* -------------------------------------------------------------------- */

	SIGNAL ON ERROR
	SIGNAL ON SYNTAX
	SIGNAL MainBodyOfCode
