HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //opt/resolve/Developer/Fusion Fuse/Arrow.fuse
-- Cut From Here
--[[--
Arrow.Fuse 
Draws an Arrow between 2 points.

--]]--

FuRegisterClass("Arrow", CT_Tool, { --Minimal Fu Registry class definition  
	REGS_Category = "Fuses\\Examples",
	REGS_OpIconString = "Arw",
	REGS_OpDescription = "Arrow Shape Tool",
	})

function Create()
		-- Point controls are 2D used for on screen  manipulation returning 2 values X and Y
		InHead = self:AddInput("Head", "Head", { --UI Label, Internal Ref
			LINKID_DataType      = "Point", -- Retrurns 2 values X and Y
			INPID_InputControl   = "OffsetControl", -- Type of Control
			INPID_PreviewControl = "CrosshairControl",  -- Display Control Type
			INP_DefaultX         = 0.5,
			INP_DefaultY         = 0.5,
			})
			
		InTail = self:AddInput("Tail", "Tail", { --UI Label, Internal Ref
			LINKID_DataType = "Point",
			INPID_InputControl = "OffsetControl", -- Type of Control
			INPID_PreviewControl = "CrosshairControl",
--			CHC_Style = "DiagonalCross", -- Change the Crosshair to a X diagonal cross
			PC_GrabPriority = -1, -- When multiple crosshair are togther in the view, Grab Priority is used to choose which gets picked. The higher the priority is picked first
			INP_DefaultX         = 0.75,
			INP_DefaultY         = 0.75,
			})

		InHPosition = self:AddInput( "Head Position", "HPos", {
			LINKID_DataType = "Number",
			INPID_InputControl = "SliderControl",
			INP_MaxAllowed = 1.0, -- Sets the default Maximum scale of the slider
			INP_MinAllowed = 0.0, --Sets the default Minimum  scale for the slider
			INP_Default = 1.0, -- Sets default value for the slider
			INP_MinScale        = 0.2,
			})
	self:BeginControlNest("Shading", "ShadingNest", true); -- Control Nests group controls with a togglable collapse/expand function

		InR = self:AddInput("Arrow Red", "Red", { --UI Label, Internal Ref
			ICS_Name            = "Arrow Color",
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 1.0,
			INP_MaxScale        = 1.0,
			CLRC_ShowWheel      = false,
			IC_ControlGroup     = 2, --Groups Controls together. Make Group number it 2
			IC_ControlID        = 0,
			})
		InG = self:AddInput("Arrow Green", "Green", { --UI Label, Internal Ref
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 0.9,
			IC_ControlGroup     = 2, -- Put this into a Group and number it 2
			IC_ControlID        = 1,
			})
		InB = self:AddInput("Arrow Blue", "Blue", {--UI Label, Internal Ref
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 0.6,
			IC_ControlGroup     = 2, -- Put this into a Group and number it 2
			IC_ControlID        = 2,
			})
		-- Notify change is a seperate class function that will be called  when controls are changed, see below for the Notify change function.
		InNotifyOutline = self:AddInput("Outline On", "NotifyO", {
			LINKID_DataType = "Number",
			INPID_InputControl = "CheckboxControl",
			INP_Integer = true,
			INP_Default = 1.0,
			INP_DoNotifyChanged = true, -- We want to hear about changes on this control
			})
		
		InRo = self:AddInput("Outline Red", "Redout", { --UI Label, Internal Ref
			ICS_Name            = "Outline Color",
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 1.0,
			INP_MaxScale        = 1.0,
			CLRC_ShowWheel      = false,
			IC_ControlGroup     = 3, --Groups Controls together. Make Group number it 2
			IC_ControlID        = 0,
			})
		InGo = self:AddInput("Outline Green", "Greenout", { --UI Label, Internal Ref
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 1.0,
			IC_ControlGroup     = 3, -- Put this into a Group and number it 2
			IC_ControlID        = 1,
			})
		InBo = self:AddInput("Outline Blue", "Blueout", {--UI Label, Internal Ref
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 1.0,
			IC_ControlGroup     = 3, -- Put this into a Group and number it 2
			IC_ControlID        = 2,
			})
			
		InNotifyShadow = self:AddInput("Shadow On", "NotifyS", {
			LINKID_DataType = "Number",
			INPID_InputControl = "CheckboxControl",
			INP_Integer = true,
			INP_Default = 1.0,
			INP_DoNotifyChanged = true, -- We want to hear about changes on this control
			})
		
		InRs = self:AddInput("Shadow Red", "Reds", { --UI Label, Internal Ref
			ICS_Name            = "Shadow Color",
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 0.0,
			INP_MaxScale        = 1.0,
			CLRC_ShowWheel      = false,
			IC_ControlGroup     = 4, --Groups Controls together. Make Group number it 2
			IC_ControlID        = 0,
			})
		InGs = self:AddInput("Shadow Green", "Greens", { --UI Label, Internal Ref
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 0.0,
			IC_ControlGroup     = 4, -- Put this into a Group and number it 2
			IC_ControlID        = 1,
			})
		InBs = self:AddInput("Shadow Blue", "Blues", {--UI Label, Internal Ref
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 0.0,
			IC_ControlGroup     = 4, -- Put this into a Group and number it 2
			IC_ControlID        = 2,
			})
		InAs = self:AddInput("Shadow Alpha", "Alphas", {--UI Label, Internal Ref
			LINKID_DataType     = "Number",
			INPID_InputControl  = "ColorControl", -- Type of Control
			INP_Default         = 0.5,
			IC_ControlGroup     = 4, -- Put this into a Group and number it 2
			IC_ControlID        = 3,
			})
	self:EndControlNest()

	self:AddControlPage("Arrow") -- Name the new Tab Control page
	
		self:BeginControlNest("Arrow Shape", "ArrowShape", true); -- Control Nests group controls with a togglable collapse/expand function

		InArrowWidth = self:AddInput( "Arrow Width", "ArrowWidth", {
			LINKID_DataType = "Number",
			INPID_InputControl = "SliderControl",
			INP_MaxAllowed = 1.0, -- Sets the default Maximum scale of the slider
			INP_MinAllowed = 0.0, --Sets the default Minimum  scale for the slider
			INP_MaxScale        = 0.02,
			INP_Default = 0.01, -- Sets default value for the slider
			})
		InArrowHeight = self:AddInput( "Arrow Height", "ArrowHeight", {
			LINKID_DataType = "Number",
			INPID_InputControl = "SliderControl",
			INP_MaxAllowed = 1.0, -- Sets the default Maximum scale of the slider
			INP_MinAllowed = 0.0, --Sets the default Minimum  scale for the slider
			INP_MaxScale        = 0.1,
			INP_Default = 0.04, -- Sets default value for the slider
			})
		InShaftWidth = self:AddInput( "Shaft Width", "ShaftWidth", {
			LINKID_DataType = "Number",
			INPID_InputControl = "SliderControl",
			INP_MaxAllowed = 1.0, -- Sets the default Maximum scale of the slider
			INP_MinAllowed = 0.0, --Sets the default Minimum  scale for the slider
			INP_MaxScale        = 0.01,
			INP_Default = 0.005, -- Sets default value for the slider
			})
	self:EndControlNest()	

	self:BeginControlNest("Outline Settings", "Outlinesettings", true); -- Control Nests group controls with a togglable collapse/expand function

		InThickness = self:AddInput("Outline Thickness", "Thickness", {
			LINKID_DataType = "Number",
			INPID_InputControl = "SliderControl",
			INP_MaxAllowed = 0.1, -- Sets the default Maximum scale of the slider
			INP_MinAllowed = 0.0, --Sets the default Minimum  scale for the slider
			INP_MaxScale        = 0.004,
			INP_Default = 0.002, -- Sets default value for the slider
			})
		-- Notify change is a seperate class function that will be called  when controls are changed, see below for the Notify change function.
		InNotifyOutline2 = self:AddInput("Outline Solid", "NotifyO2", {
			LINKID_DataType = "Number",
			INPID_InputControl = "CheckboxControl",
			INP_Integer = true,
			INP_Default = 1.0,
			INP_DoNotifyChanged = true, -- We want to hear about changes on this control
			})
			
			
	self:EndControlNest()	

	self:BeginControlNest("Shadow Settings", "ShadowSettings", true); -- Control Nests group controls with a togglable collapse/expand function

		InShadowOff = self:AddInput("Shadow Offset", "ShadowOff", {
			LINKID_DataType = "Number",
			INPID_InputControl = "SliderControl",
			INP_MaxAllowed = 0.1, -- Sets the default Maximum scale of the slider
			INP_MinAllowed = 0.0, --Sets the default Minimum  scale for the slider
			INP_MaxScale        = 0.02,
			INP_Default = 0.01, -- Sets default value for the slider
			})
		InShadowTilt = self:AddInput("Shadow Tilt", "ShadowTilt", {
			LINKID_DataType = "Number",
			INPID_InputControl = "SliderControl",
			INP_MaxAllowed = 90, -- Sets the default Maximum scale of the slider
			INP_MinAllowed = 0.0, --Sets the default Minimum  scale for the slider
			INP_MaxScale        = 45,
			INP_Default = 0.0, -- Sets default value for the slider
			})
	self:EndControlNest()
			
	InImage = self:AddInput("Input", "Input", {
		LINKID_DataType = "Image",
		LINK_Main = 1,
		})

	OutImage = self:AddOutput("Output", "Output", {
		LINKID_DataType = "Image",
		LINK_Main = 1,
		})				
end

-- Notify Changed is used to Hide or Show controls when options are selected in the Tool's control  inspector 

function NotifyChanged(inp, param, time)
	if inp == InNotifyOutline then   -- If Notify Change check box is changed, then rename the Control names and Un/Hide sliders
		local locked = (param.Value > 0.5)
		
		if locked then
			InRo:SetAttrs({ IC_Visible = true })
			InGo:SetAttrs({ IC_Visible = true })
			InBo:SetAttrs({ IC_Visible = true })
			InNotifyOutline:SetAttrs({ LINKS_Name = "Outline On" })
		else
			InRo:SetAttrs({ IC_Visible = false })
			InGo:SetAttrs({ IC_Visible = false })
			InBo:SetAttrs({ IC_Visible = false })
			InNotifyOutline:SetAttrs({ LINKS_Name = "Outline Off" })
		end
	end
	if inp == InNotifyShadow then   -- If Notify Change check box is changed, then rename the Control names and Un/Hide sliders
		local locked = (param.Value > 0.5)
		
		if locked then
			InRs:SetAttrs({ IC_Visible = true })
			InGs:SetAttrs({ IC_Visible = true })
			InBs:SetAttrs({ IC_Visible = true })
			InAs:SetAttrs({ IC_Visible = true })
			InNotifyShadow:SetAttrs({ LINKS_Name = "Shadow On" })
		else
			InRs:SetAttrs({ IC_Visible = false })
			InGs:SetAttrs({ IC_Visible = false })
			InBs:SetAttrs({ IC_Visible = false })
			InAs:SetAttrs({ IC_Visible = false })
			InNotifyShadow:SetAttrs({ LINKS_Name = "Shadow Off" })
		end
	end
	if inp == InNotifyOutline2 then   -- If Notify Change check box is changed, then rename the Control names and Un/Hide sliders
		local locked = (param.Value > 0.5)
		
		if locked then
			InNotifyOutline2:SetAttrs({ LINKS_Name = "Outline Solid" })
		else
			InNotifyOutline2:SetAttrs({ LINKS_Name = "Outline Dotted" })
		end
	end
end





function Process(req) 
	local img = InImage:GetValue(req)
	local out = img:CopyOf()
	
	local thickness = InThickness:GetValue(req).Value
	local shadow = InShadowOff:GetValue(req).Value
	local headoffset  = InHPosition:GetValue(req).Value
	local shadowtilt = InShadowTilt:GetValue(req).Value

	local r         = InR:GetValue(req).Value
	local g         = InG:GetValue(req).Value
	local b         = InB:GetValue(req).Value

	local ro         = InRo:GetValue(req).Value
	local go         = InGo:GetValue(req).Value
	local bo         = InBo:GetValue(req).Value
	
	local rs         = InRs:GetValue(req).Value
	local gs         = InGs:GetValue(req).Value
	local bs        = InBs:GetValue(req).Value
	local as         = InAs:GetValue(req).Value
	
	local notifyo         = InNotifyOutline:GetValue(req).Value
	local notifyo2         = InNotifyOutline2:GetValue(req).Value
	local notifys         = InNotifyShadow:GetValue(req).Value

	local ic = ImageChannel(out, 8) -- Image Channel
	local fs = FillStyle() -- Fill Style Object
	local cs = ChannelStyle() -- Channel Style
	local mat = Matrix4() -- Matrix to transform the shapes
	
	local csrect=cs -- copy of the basic ChannelStyle
	local fsrect=fs -- copy of the basic FillStyle
	local icrect = ic 
		
	local head = InHead:GetValue(req) -- This has 2 Outputs X & Y
	local tail = InTail:GetValue(req) -- This has 2 Outputs X & Y
	
--Calculate Image aspect ratio to apply to coordinates
	local hx=head.X 
	local tx=tail.X
	local hy=head.Y 
	local ty=tail.Y
	local aspect = img.Height / img.Width
	hy = hy * aspect
	ty = ty * aspect
	
	
-- Calculate Vector length and Angle
	local length = math.sqrt(((hx-tx) ^2)+ ((hy-ty) ^2))
--	local angle = math.atan((hx-tx) / (hy-ty)) * -57.2957795 -- 360/ 2 Pi
	local angle = (math.atan2((hy-ty),(hx-tx)) * 57.2957795) + 90-- 360/ 2 Pi
	

--Get Arrow measurements
	local AW         = InArrowWidth:GetValue(req).Value
	local AH         = InArrowHeight:GetValue(req).Value
	local SW         = InShaftWidth:GetValue(req).Value
	local HO = (1.0 - headoffset) * length
	
--   Shape made of a group of line segments
	local sh = Shape()
	sh:MoveTo(0.0, HO)
	sh:LineTo(AW,  AH+HO)
	sh:LineTo(SW,  AH+HO)
	sh:LineTo(SW,  length)
	sh:LineTo(-SW,  length)
	sh:LineTo(-SW,  AH+HO)
	sh:LineTo(-AW,  AH+HO)
	sh:LineTo(0.0,  HO)
	sh:Close() -- Close shape to the origin point
-- end shape
	
	local sh2 = sh 
	local sh3 = sh -- make copies of the shape
	
--Drop Shadow Render
	if notifys > 0 then
		mat:Identity() -- Set the matrix to zero
		mat:Scale(1.0, 1.0, 1.0) --Scale 
		mat:RotZ(angle) -- Rotate, Note the order of Matrix operations, Move has been applied before Rotation
		mat:RotX(shadowtilt)
		mat:Move(hx+shadow, hy-shadow, 0.0) -- Translate the Shape
		
		cs.Color = Pixel{R=rs , G=gs , B=bs, A = as} -- Set the Color	
		cs.BlurType = "BT_Bartlett" -- BT_Box, BT_Bartlett, BT_MultiBox, BT_Gaussian
		cs.SoftnessX = 1000.0 * shadow
		cs.SoftnessY = 1000.0 * shadow
		ic:SetStyleFill(fs) -- Set the Drawing application styles.
		sh2 = sh2:TransformOfShape(mat) -- Transform Shape using the Matrix
		ic:ShapeFill(sh2) -- 
		ic:PutToImage("CM_Merge", cs)
	end
	
--Main Arrow Render 
	mat:Identity() -- Set the matrix to zero
	mat:Scale(1.0, 1.0, 1.0) --Scale 
	mat:RotZ(angle) -- Rotate, Note the order of Matrix operations, Move has been applied before Rotation
	mat:Move(hx, hy, 0.0) -- Translate the Shape

	cs.Color = Pixel{R=r , G=g , B=b, A = 1} -- Set the Color
	cs.BlurType = "BT_Box" -- BT_Box, BT_Bartlett, BT_MultiBox, BT_Gaussian
	cs.SoftnessX = 0.0
	cs.SoftnessY = 0.0
	ic:SetStyleFill(fs) -- Set the Drawing application styles.
	sh = sh:TransformOfShape(mat) -- Transform Shape using the Matrix
	ic:ShapeFill(sh) -- 
	ic:PutToImage("CM_Merge", cs)
	
	
--Outline Render
	if notifyo >0 then
		if notifyo2 >0 then
			sh3 = sh3:OutlineOfShape(thickness, "OLT_Solid", "OJT_Round", 8, "SWM_Normal", 8) -- Make the shape an outline
			cs.Color = Pixel{R=ro , G=go , B=bo, A = 1} -- Set the Color
			cs.BlurType = "BT_Box" -- BT_Box, BT_Bartlett, BT_MultiBox, BT_Gaussian
			cs.SoftnessX = 0.0
			cs.SoftnessY = 0.0
		else
			sh3 = sh3:OutlineOfShape(thickness, "OLT_Dot", "OJT_Round", 8, "SWM_Normal", 8) -- Make the shape an outline
			cs.Color = Pixel{R=ro , G=go , B=bo, A = 1} -- Set the Color
			cs.BlurType = "BT_Bartlett" -- BT_Box, BT_Bartlett, BT_MultiBox, BT_Gaussian
			cs.SoftnessX = 0.0
			cs.SoftnessY = 0.0
--			cs.SoftnessGlow = 0.95
--			cs.SoftnessBlend = 0.3
		end
		
		ic:SetStyleFill(fs) -- Set the Drawing application styles.
		sh3 = sh3:TransformOfShape(mat) -- Transform Shape using the Matrix
		ic:ShapeFill(sh3) -- 
		ic:PutToImage("CM_Merge", cs)
	end

	
	OutImage:Set(req, out)
end

--End Cut
--
--