-- ************************************************** -- Provide Moho with the name of this script object -- ************************************************** ScriptName = "MS_AddLine" -- ************************************************** -- General information about this script -- ************************************************** MS_AddLine = {} function MS_AddLine:Name() return "Add Line" end function MS_AddLine:Version() return "5.0" end function MS_AddLine:Description() return "Add a line ( = weld, = no auto-weld) - minor variation of Lost Marble's Add Point tool" -- most of the work done by Lost Marble, slightly modified to produce peaked points instead of smooth ones end function MS_AddLine:Creator() return "Lost Marble, modified by Myles Strous" end function MS_AddLine:UILabel() return("Add Line") end -- ************************************************** -- Recurring values -- ************************************************** MS_AddLine.numSel = 0 MS_AddLine.selID = 0 -- ************************************************** -- The guts of this script -- ************************************************** function MS_AddLine:IsEnabled(moho) local mesh = moho:Mesh() if (mesh == nil) then return false end if (moho.layer:CurrentAction() ~= "") then return false -- creating new objects in the middle of an action can lead to unexpected results end return true end function MS_AddLine:OnMouseDown(moho, mouseEvent) local mesh = moho:Mesh() if (mesh == nil) then return end moho.document:PrepUndo(moho.layer) moho.document:SetDirty() local closestID = -1 local closest = 1e6 local curveID = -1 local segID = -1 local n = mesh:CountPoints() mesh:SelectNone() if (not(mouseEvent.altKey)) then -- find the closest point for auto-elding the freehand curve to local testVec1 = LM.Vector2:new_local() testVec1:Set(mouseEvent.vec) closestID = mesh:ClosestPoint(testVec1) if (closestID >= 0) then local testVec2 = LM.Vector2:new_local() testVec2:Set(mesh:Point(closestID).fPos) -- convert the two chosen points to pixel coordinates -- this is to make sure that they are actually close enough in screen space local p1 = LM.Point:new_local() local p2 = LM.Point:new_local() local m = LM.Matrix:new_local() moho.layer:GetFullTransform(moho.frame, m, moho.document) m:Transform(testVec1) m:Transform(testVec2) mouseEvent.view:Graphics():WorldToScreen(testVec1, p1) mouseEvent.view:Graphics():WorldToScreen(testVec2, p2) p1.x = p1.x - p2.x p1.y = p1.y - p2.y closest = (p1.x * p1.x) + (p1.y * p1.y) end end if (closest < 100 and not(mouseEvent.altKey)) then -- add as an extension to an existing point if (mesh:Point(closestID):IsEndpoint()) then -- extend this curve mesh:AddPoint(mouseEvent.vec, closestID, moho.frame) mesh:Point(n):SetCurvature(MOHO.PEAKED, moho.frame) n = n + 1 else -- start a new curve that is connected to this point mesh:AddPoint(mouseEvent.vec, -1, moho.frame) mesh:Point(n):SetCurvature(MOHO.PEAKED, moho.frame) n = n + 1 mesh:WeldPoints(mesh:CountPoints() - 2, closestID, moho.frame) end else local curveID = -1 local segID = -1 if (not mouseEvent.altKey) then curveID, segID = mouseEvent.view:PickEdge(mouseEvent.pt, curveID, segID) end if (curveID >= 0) then -- add a point in the middle of some curve if (moho.gridOn) then moho:SnapToGrid(mouseEvent.vec) end mesh:AddPoint(mouseEvent.vec, curveID, segID, moho.frame) mesh:Point(n):SetCurvature(MOHO.PEAKED, moho.frame) n = n + 1 else -- add a new curve segment if (moho.gridOn) then moho:SnapToGrid(mouseEvent.vec) end mesh:AddPoint(mouseEvent.vec, -1, moho.frame) mesh:Point(n):SetCurvature(MOHO.PEAKED, moho.frame) n = n + 1 mesh:Point(n):SetCurvature(MOHO.PEAKED, moho.frame) n = n + 1 end end LM_TranslatePoints.selID = mesh:CountPoints() - 1 LM_TranslatePoints:OnMouseDown(moho, mouseEvent) mouseEvent.view:DrawMe() end function MS_AddLine:OnMouseMoved(moho, mouseEvent) LM_TranslatePoints:OnMouseMoved(moho, mouseEvent) end function MS_AddLine:OnMouseUp(moho, mouseEvent) LM_TranslatePoints:OnMouseUp(moho, mouseEvent) end function MS_AddLine:OnKeyDown(moho, keyEvent) LM_TranslatePoints:OnKeyDown(moho, keyEvent) end -- ************************************************** -- Tool options - create and respond to tool's UI -- ************************************************** MS_AddLine.DUMMY = MOHO.MSG_BASE MS_AddLine.AUTOWELD = MOHO.MSG_BASE + 1 MS_AddLine.SELECTITEM = MOHO.MSG_BASE + 2 function MS_AddLine:DoLayout(moho, layout) self.menu = LM.GUI.Menu("Select Group") self.popup = LM.GUI.PopupMenu(128, false) self.popup:SetMenu(self.menu) layout:AddChild(self.popup) self.autoWeldCheck = LM.GUI.CheckBox("Auto-weld", self.AUTOWELD) layout:AddChild(self.autoWeldCheck) end function MS_AddLine:UpdateWidgets(moho) local mesh = moho:Mesh() if (mesh == nil) then return end MOHO.BuildGroupMenu(self.menu, mesh, self.SELECTITEM, self.DUMMY) self.autoWeldCheck:SetValue(LM_TranslatePoints.autoWeld) end function MS_AddLine:HandleMessage(moho, view, msg) local mesh = moho:Mesh() if (mesh == nil) then return end if (msg == self.AUTOWELD) then LM_TranslatePoints.autoWeld = self.autoWeldCheck:Value() elseif (msg >= self.SELECTITEM) then mesh:SelectNone() local i = msg - self.SELECTITEM local name = mesh:Group(i):Name() mesh:SelectGroup(name) moho:UpdateUI() end end