-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "SZ_MarkPoints"

-- **************************************************
-- General information about this script
-- **************************************************

SZ_MarkPoints = {}

function SZ_MarkPoints:Name()
	return self:Localize('UILabel')
end

function SZ_MarkPoints:Version()
	return '1.2'
end

function SZ_MarkPoints:UILabel()
	return self:Localize('UILabel')
end

function SZ_MarkPoints:Creator()
	return 'Stan'
end

function SZ_MarkPoints:Description()
	return self:Localize('Description')
end

function SZ_MarkPoints:LoadPrefs(prefs)
	self.drawCircle = prefs:GetBool("SZ_MarkPoints.drawCircle", true)
	self.radius = prefs:GetFloat("SZ_MarkPoints.radius", .03)
	self.circleFillColorR = prefs:GetInt("SZ_MarkPoints.circleFillColorR", 0)
	self.circleFillColorG = prefs:GetInt("SZ_MarkPoints.circleFillColorG", 255)
	self.circleFillColorB = prefs:GetInt("SZ_MarkPoints.circleFillColorB", 0)
	self.circleFillColorA = prefs:GetInt("SZ_MarkPoints.circleFillColorA", 180)
	self.drawCross = prefs:GetBool("SZ_MarkPoints.drawCross", true)
	self.crossSpread = prefs:GetFloat("SZ_MarkPoints.crossSpread", .04)
	self.crossWidth = prefs:GetFloat("SZ_MarkPoints.crossWidth", .001)
	self.crossColorR = prefs:GetInt("SZ_MarkPoints.crossColorR", 133)
	self.crossColorG = prefs:GetInt("SZ_MarkPoints.crossColorG", 0)
	self.crossColorB = prefs:GetInt("SZ_MarkPoints.crossColorB", 0)
	self.crossColorA = prefs:GetInt("SZ_MarkPoints.crossColorA", 200)
	self.doNotRender = prefs:GetBool("SZ_MarkPoints.doNotRender", true)
end

function SZ_MarkPoints:SavePrefs(prefs)
	prefs:SetBool("SZ_MarkPoints.drawCircle", self.drawCircle)
	prefs:SetFloat("SZ_MarkPoints.radius", self.radius)
	prefs:SetInt("SZ_MarkPoints.circleFillColorR", self.circleFillColorR)
	prefs:SetInt("SZ_MarkPoints.circleFillColorG", self.circleFillColorG)
	prefs:SetInt("SZ_MarkPoints.circleFillColorB", self.circleFillColorB)
	prefs:SetInt("SZ_MarkPoints.circleFillColorA", self.circleFillColorA)
	prefs:SetBool("SZ_MarkPoints.drawCross", self.drawCross)
	prefs:SetFloat("SZ_MarkPoints.crossSpread", self.crossSpread)
	prefs:SetFloat("SZ_MarkPoints.crossWidth", self.crossWidth)
	prefs:SetInt("SZ_MarkPoints.crossColorR", self.crossColorR)
	prefs:SetInt("SZ_MarkPoints.crossColorG", self.crossColorG)
	prefs:SetInt("SZ_MarkPoints.crossColorB", self.crossColorB)
	prefs:SetInt("SZ_MarkPoints.crossColorA", self.crossColorA)
	prefs:SetBool("SZ_MarkPoints.doNotRender", self.doNotRender)
end

function SZ_MarkPoints:ResetPrefs()
	self.radius = .03
	self.circleFillColorR = 0
	self.circleFillColorG = 255
	self.circleFillColorB = 0
	self.circleFillColorA = 180
	self.drawCross = true
	self.crossSpread = .04
	self.crossWidth = .001
	self.crossColorR = 133
	self.crossColorG = 0
	self.crossColorB = 0
	self.crossColorA = 200
	self.doNotRender = true
end

-- **************************************************
-- Is Relevant / Is Enabled
-- **************************************************

function SZ_MarkPoints:IsRelevant(moho)
	if (moho:DisableDrawingTools()) then
		return false
	end
	local mesh = moho:DrawingMesh()
	if (mesh == nil) then
		return false
	end
	if (moho.drawingLayer:CurrentAction() ~= "") then
		return false -- creating new objects in the middle of an action can lead to unexpected results
	end
	return true
end

function SZ_MarkPoints:IsEnabled(moho)
	if (moho:DisableDrawingTools()) then
		return false
	end
	local mesh = moho:DrawingMesh()
	if (mesh == nil) then
		return false
	end
	return true
end

-- **************************************************
-- Recurring Values
-- **************************************************

SZ_MarkPoints.drawCircle = true
SZ_MarkPoints.radius = .03
SZ_MarkPoints.circleFillColorR = 0
SZ_MarkPoints.circleFillColorG = 255
SZ_MarkPoints.circleFillColorB = 0
SZ_MarkPoints.circleFillColorA = 180

SZ_MarkPoints.drawCross = true
SZ_MarkPoints.crossSpread = .04
SZ_MarkPoints.crossWidth = .001
SZ_MarkPoints.crossColorR = 133
SZ_MarkPoints.crossColorG = 0
SZ_MarkPoints.crossColorB = 0
SZ_MarkPoints.crossColorA = 180

SZ_MarkPoints.doNotRender = true


-- **************************************************
-- SZ_MarkPointsDialog
-- **************************************************

local SZ_MarkPointsDialog = {}

SZ_MarkPointsDialog.UPDATE_PREVIEW = MOHO.MSG_BASE

function SZ_MarkPointsDialog:new(moho)
	local d = LM.GUI.SimpleDialog(SZ_MarkPoints:Localize('UILabel') .. " v" .. SZ_MarkPoints:Version(), SZ_MarkPointsDialog)
	local l = d:GetLayout()
	
	d.preview = MOHO.MeshPreview(200, 200)
	l:AddChild(d.preview)
	
	l:PushH()
		l:PushV()
			d.drawCircleCheckbox = LM.GUI.CheckBox(SZ_MarkPoints:Localize('drawCircle'), d.UPDATE_PREVIEW)
			l:AddChild(d.drawCircleCheckbox, LM.GUI.ALIGN_LEFT, 0)
			
			d.radiusTxt = LM.GUI.TextControl(0, '0.0000', d.UPDATE_PREVIEW, LM.GUI.FIELD_UFLOAT, SZ_MarkPoints:Localize('radius'))
			d.radiusTxt:SetWheelInc(0.01)
			d.radiusTxt:SetConstantMessages(true)
			l:AddChild(d.radiusTxt, LM.GUI.ALIGN_LEFT, 0)
			
			d.circleFillColorSwatch = LM.GUI.ColorSwatch(true, d.UPDATE_PREVIEW)
			l:AddChild(d.circleFillColorSwatch)
		l:Pop()
		l:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
		l:PushV()
			d.drawCrossCheckbox = LM.GUI.CheckBox(SZ_MarkPoints:Localize('drawCross'), d.UPDATE_PREVIEW)
			l:AddChild(d.drawCrossCheckbox, LM.GUI.ALIGN_LEFT, 0)
			
			d.crossSpreadTxt = LM.GUI.TextControl(0, '0.0000', d.UPDATE_PREVIEW, LM.GUI.FIELD_UFLOAT, SZ_MarkPoints:Localize('spread'))
			d.crossSpreadTxt:SetWheelInc(0.01)
			d.crossSpreadTxt:SetConstantMessages(true)
			l:AddChild(d.crossSpreadTxt, LM.GUI.ALIGN_LEFT, 0)
			
			d.crossWidthTxt = LM.GUI.TextControl(0, '0.0000', d.UPDATE_PREVIEW, LM.GUI.FIELD_UFLOAT, SZ_MarkPoints:Localize('width'))
			d.crossWidthTxt:SetWheelInc(0.001)
			d.crossWidthTxt:SetConstantMessages(true)
			l:AddChild(d.crossWidthTxt, LM.GUI.ALIGN_LEFT, 0)
			
			d.crossColorSwatch = LM.GUI.ColorSwatch(true, d.UPDATE_PREVIEW)
			l:AddChild(d.crossColorSwatch)
		l:Pop()
	l:Pop()
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	d.doNotRenderCbx = LM.GUI.CheckBox(SZ_MarkPoints:Localize('doNotRender'), 0)
    l:AddChild(d.doNotRenderCbx, LM.GUI.ALIGN_LEFT, 0)
	d.moho = moho
	return d
end

function SZ_MarkPointsDialog:UpdateWidgets(moho)
	self.drawCircleCheckbox:SetValue(SZ_MarkPoints.drawCircle)
	self.radiusTxt:SetValue(SZ_MarkPoints.radius)
	local circleFillColor = LM.rgb_color:new_local()
	circleFillColor.r = SZ_MarkPoints.circleFillColorR
	circleFillColor.g = SZ_MarkPoints.circleFillColorG
	circleFillColor.b = SZ_MarkPoints.circleFillColorB
	circleFillColor.a = SZ_MarkPoints.circleFillColorA
	self.circleFillColorSwatch:SetValue(circleFillColor)
	
	self.drawCrossCheckbox:SetValue(SZ_MarkPoints.drawCross)
	self.crossSpreadTxt:SetValue(SZ_MarkPoints.crossSpread)
	self.crossWidthTxt:SetValue(SZ_MarkPoints.crossWidth)
	local crossColor = LM.rgb_color:new_local()
	crossColor.r = SZ_MarkPoints.crossColorR
	crossColor.g = SZ_MarkPoints.crossColorG
	crossColor.b = SZ_MarkPoints.crossColorB
	crossColor.a = SZ_MarkPoints.crossColorA
	self.crossColorSwatch:SetValue(crossColor)
	
	self.doNotRenderCbx:SetValue(SZ_MarkPoints.doNotRender)
	
	self:DrawMarkInPreview()
end

function SZ_MarkPointsDialog:OnOK(moho)
	SZ_MarkPoints.drawCircle = self.drawCircleCheckbox:Value()
	SZ_MarkPoints.radius = self.radiusTxt:FloatValue()
	local circleFillSwatchValue = self.circleFillColorSwatch:Value()
	SZ_MarkPoints.circleFillColorR = circleFillSwatchValue.r
	SZ_MarkPoints.circleFillColorG = circleFillSwatchValue.g
	SZ_MarkPoints.circleFillColorB = circleFillSwatchValue.b
	SZ_MarkPoints.circleFillColorA = circleFillSwatchValue.a
	
	SZ_MarkPoints.drawCross = self.drawCrossCheckbox:Value()
	SZ_MarkPoints.crossSpread = self.crossSpreadTxt:FloatValue()
	SZ_MarkPoints.crossWidth = self.crossWidthTxt:FloatValue()
	local crossColorSwatchValue = self.crossColorSwatch:Value()
	SZ_MarkPoints.crossColorR = crossColorSwatchValue.r
	SZ_MarkPoints.crossColorG = crossColorSwatchValue.g
	SZ_MarkPoints.crossColorB = crossColorSwatchValue.b
	SZ_MarkPoints.crossColorA = crossColorSwatchValue.a
	
	SZ_MarkPoints.doNotRender = self.doNotRenderCbx:Value()
end

function SZ_MarkPointsDialog:HandleMessage(msg)
    if msg == self.UPDATE_PREVIEW then
        self:DrawMarkInPreview()
    else
        
    end
end

function SZ_MarkPointsDialog:DrawMarkInPreview()
	local magnification = self.moho.document:Height()/200
	local destMesh = self.preview:Mesh()
	destMesh:Clear()
	local drawCircle = self.drawCircleCheckbox:Value()
	local drawCross = self.drawCrossCheckbox:Value()
	
	if drawCircle then
		local vec = LM.Vector2:new_local()
		SZ_MarkPoints:DrawCircle(destMesh, vec, self.radiusTxt:FloatValue() * magnification)
		self.preview:CreateShape(true)
		local circleShapeId = destMesh:CountShapes()-1
		local circleShape = destMesh:Shape(circleShapeId)
		circleShape.fHasOutline = false
		local circleFillColor = self.circleFillColorSwatch:Value()
		circleShape.fMyStyle.fFillCol:SetValue(0, circleFillColor)
	end
	
	if drawCross then
		local vec2 = LM.Vector2:new_local()
		SZ_MarkPoints:DrawCross(destMesh, vec2, self.crossSpreadTxt:FloatValue() * magnification)
		self.preview:CreateShape(false)
		local crossShapeId = destMesh:CountShapes()-1
		local crossShape = destMesh:Shape(crossShapeId)
		local crossColor = self.crossColorSwatch:Value()
		crossShape.fMyStyle.fLineCol:SetValue(0, crossColor)
		crossShape.fMyStyle.fLineWidth = self.crossWidthTxt:FloatValue() * magnification
	end	
	
	self.preview:Refresh()
end

-- **************************************************
-- The guts of this script
-- **************************************************

function SZ_MarkPoints:Run(moho)
	local dlog = SZ_MarkPointsDialog:new(moho)
	if (dlog:DoModal() == LM.GUI.MSG_CANCEL) then
		return
	end
	
	moho.document:SetDirty()
	moho.document:PrepUndo(nil)
	
	local function round(x, n)
		n = math.pow(10, n or 3)
		x = x * n
		if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end
		return x / n
	end
	
	local sourceMesh = moho:Mesh()
	local sourceName = moho.layer:Name()
	local destLayer = moho:CreateNewLayer(MOHO.LT_VECTOR)
	destLayer:SetName(sourceName .. self:Localize("pointMarks") .. round(self.radius))
	destLayer:SetMaskingMode(MOHO.MM_NOTMASKED)
	if self.doNotRender then
		destLayer:SetEditOnly(true)
	end
	-- local destMesh = moho:Mesh()
	
	local circleFillColor = LM.rgb_color:new_local()
	circleFillColor.r = self.circleFillColorR
	circleFillColor.g = self.circleFillColorG
	circleFillColor.b = self.circleFillColorB
	circleFillColor.a = self.circleFillColorA
	
	local crossColor = LM.rgb_color:new_local()
	crossColor.r = self.crossColorR
	crossColor.g = self.crossColorG
	crossColor.b = self.crossColorB
	crossColor.a = self.crossColorA
	
	for i=0, sourceMesh:CountPoints()-1 do
		local point = sourceMesh:Point(i)
		local vec = LM.Vector2:new_local()
		vec:Set(point.fPos)
		self:DrawMarkInMoho(moho, vec, self.radius, circleFillColor, self.crossSpread, self.crossWidth, crossColor)
	end
	
end

function SZ_MarkPoints:DrawMarkInMoho(moho, vec, radius, circleFillColor, crossSpread, crossWidth, crossColor)
	local destMesh = moho:Mesh()
	local circleVec = LM.Vector2:new_local()
	circleVec:Set(vec)
	local crossVec = LM.Vector2:new_local()
	crossVec:Set(vec)
	
	if self.drawCircle then
		self:DrawCircle(destMesh, circleVec, radius)
		local shapeId = moho:CreateShape(true)
		if shapeId >=0 then
			local shape = destMesh:Shape(shapeId)
			shape.fHasOutline = false
			shape.fMyStyle.fFillCol:SetValue(0, circleFillColor)
		end	
	end
	
	if self.drawCross then
		self:DrawCross(destMesh, crossVec, crossSpread)
		local crossShapeId = moho:CreateShape(false)
		local crossShape = destMesh:Shape(crossShapeId)
		crossShape.fMyStyle.fLineCol:SetValue(0, crossColor)
		crossShape.fMyStyle.fLineWidth = crossWidth
	end
	
	destMesh:SelectNone()
end

function SZ_MarkPoints:DrawCircle(destMesh, vec, radius)
	
	local n = destMesh:CountPoints()		
	
	vec.x = vec.x - radius
	destMesh:AddLonePoint(vec, 0)
	
	vec.x = vec.x + radius
	vec.y = vec.y - radius
	destMesh:AppendPoint(vec, 0)
	
	vec.x = vec.x + radius
	vec.y = vec.y + radius
	destMesh:AppendPoint(vec, 0)
	
	vec.x = vec.x - radius
	vec.y = vec.y + radius
	destMesh:AppendPoint(vec, 0)
	
	vec.x = vec.x - radius
	vec.y = vec.y - radius
	destMesh:AppendPoint(vec, 0)

	destMesh:WeldPoints(n + 4, n, 0)

	-- set all their curvatures appropriately (0.391379 is the magic number for a circle)
	destMesh:Point(n):SetCurvature(0.391379, 0)
	destMesh:Point(n + 1):SetCurvature(0.391379, 0)
	destMesh:Point(n + 2):SetCurvature(0.391379, 0)
	destMesh:Point(n + 3):SetCurvature(0.391379, 0)

	destMesh:SelectConnected()
end

function SZ_MarkPoints:DrawCross(destMesh, vec, crossSpread)
	
	local n = destMesh:CountPoints()
	
	vec.x = vec.x - (crossSpread/2)
	destMesh:AddLonePoint(vec, 0)
	
	vec.x = vec.x + crossSpread
	destMesh:AppendPoint(vec, 0)
	
	vec.x = vec.x - (crossSpread/2)
	vec.y = vec.y - (crossSpread/2)
	destMesh:AddLonePoint(vec, 0)
	
	vec.y = vec.y + crossSpread
	destMesh:AppendPoint(vec, 0)
	
	destMesh:SelectNone()
	destMesh:Point(n).fSelected = true
	destMesh:Point(n + 1).fSelected = true
	destMesh:Point(n + 2).fSelected = true
	destMesh:Point(n + 3).fSelected = true

end

-- **************************************************
-- Localization
-- **************************************************

function SZ_MarkPoints:Localize(text)
	local phrase = {}

	phrase['Description'] = 'Creates a new layer where shapes will mark the locations of the current layer\'s points'
	phrase['UILabel'] = 'Mark Points'
	phrase['doNotRender'] = 'Do not render'
	phrase['drawCircle'] = 'Circle'
	phrase['drawCross'] = 'Crosshair'

	phrase['radius'] = 'Radius:'
	phrase['spread'] = 'Spread:'
	phrase['width'] = 'Width:'
	phrase['pointMarks'] = ' Point Marks '

	local fileWord = MOHO.Localize("/Menus/File/File=File")
	if fileWord == "Файл" then
		phrase['Description'] = 'Создает новый слой, в котором отмечает местонахождение точек текущего слоя'
		phrase['UILabel'] = 'Отметить точки'
		phrase['doNotRender'] = 'Не рендерить'
		phrase['drawCircle'] = 'Круг'
		phrase['drawCross'] = 'Перекрестие'

		phrase['radius'] = 'Радиус:'
		phrase['spread'] = 'Ширина:'
		phrase['width'] = 'Толщина:'
		phrase['pointMarks'] = ' отметка точек '
	end

	return phrase[text]
end

Icon
Mark Points
Listed

Author: Stan View Script
Script type: Button/Menu

Uploaded: Jan 03 2021, 12:38

Marks the locations of all points in the current vector layer.
Image

Installation Options:

This script, and all other scripts on this site are distributed as free software under the GNU General Public License 3.0 or later.
Downloads count: 144