XML PolygonEditor für pb 4.60
Verfasst: 18.09.2011 22:50
Hi Leute,
hier kommt ein einfacher Polygoneditor um Umrisse von Grafiken zu erzeugen. Ich benötige Ihn um 2d Physik Objekte aus Grafiken erstellen zu können. Die Vorlage kam von STARGÅTE und ich habe für meien Zwecke erweitert. Zukünftig soll noch eine automatische Polygonerkennung eingebaut werden, aber die derzeitige Löung ist schon funktionell.
Gruß Michael
hier kommt ein einfacher Polygoneditor um Umrisse von Grafiken zu erzeugen. Ich benötige Ihn um 2d Physik Objekte aus Grafiken erstellen zu können. Die Vorlage kam von STARGÅTE und ich habe für meien Zwecke erweitert. Zukünftig soll noch eine automatische Polygonerkennung eingebaut werden, aber die derzeitige Löung ist schon funktionell.
Gruß Michael
Code: Alles auswählen
;////////////////////////////////////////////////////////////////
;//
;// Project Title: MP 2D PolygonEditor
;// Dateiname: MP_2D_PolygonEditor.pb
;// Erstellt am: 18.09.2011
;// Update am :
;// Author: STARGÅTE, Erweiterungen Michael Paulwitz
;// PB Version ab 4.60
;//
;// Info:
;// Create a XML Polygon from a grafic file
;// Erzeugt ein XML Polygon von einer Grafikdatei
;//
;// CodeExample from STARGÅTE, many thanks to him
;//
;////////////////////////////////////////////////////////////////
;- ProgrammStart
Enumeration
#Window
#Menu
#Image
#CanvasGadget
#MenuItem_LoadImage
#MenuItem_SavePolygon
#MenuItem_LoadPolygon
#MenuItem_FreePolygon
#MenuItem_Kreis
#MenuItem_Viereck
#MenuItem_Polygon
#MenuItem_Help
#XML
EndEnumeration
Structure Integer2D
X.i
Y.i
EndStructure
Procedure.s GetNamePart(FullPathName.s)
If GetExtensionPart(FullPathName)
ProcedureReturn Left(GetFilePart(FullPathName), Len(GetFilePart(FullPathName))-Len(GetExtensionPart(FullPathName))-1)
Else
ProcedureReturn GetFilePart(FullPathName)
EndIf
EndProcedure
UsePNGImageDecoder()
UseJPEGImageDecoder()
OpenWindow(#Window, 0, 0, 400, 300, "PolygonCreator", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
CreateMenu(#Menu, WindowID(#Window))
MenuTitle("Datei")
MenuItem(#MenuItem_LoadImage, "Bild laden...")
MenuBar()
MenuItem(#MenuItem_LoadPolygon, "Polygon laden...")
MenuItem(#MenuItem_SavePolygon, "Polygon speichern...")
MenuTitle("Art")
MenuItem(#MenuItem_FreePolygon, "Polygon löschen")
MenuBar()
MenuItem(#MenuItem_Polygon, "Polygon")
SetMenuItemState(#Menu,#MenuItem_Polygon,1)
MenuItem(#MenuItem_Kreis, "Kreis")
MenuItem(#MenuItem_Viereck, "Viereck")
MenuTitle("Help")
MenuItem(#MenuItem_Help, "Help")
CanvasGadget(#CanvasGadget, 0, 0, 0, 0)
SetGadgetAttribute(#CanvasGadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
Global NewList Corner.Integer2D()
Global *SelectedCorner.Integer2D
Global EditModus = 1
Procedure UpdateCanvasGadget()
Protected *PreviousCorner.Integer2D
If StartDrawing(CanvasOutput(#CanvasGadget))
Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF)
If IsImage(#Image)
DrawAlphaImage(ImageID(#Image), 0, 0, 128)
EndIf
If LastElement(Corner())
*PreviousCorner.Integer2D = @Corner()
EndIf
If EditModus = 2
If ListSize (Corner()) = 2
SelectElement(Corner(), 0)
X1 = Corner()\X
Y1 = Corner()\y
SelectElement(Corner(), 1)
X2 = Corner()\X
Y2 = Corner()\y
sx = x2-x1
sy = y2-y1
Radius = Sqr(sx*sx + sy*sy) -1
For a.l = 0 To 2 * #PI * Radius ;Step 2
x.f = Cos(a / Radius) * Radius + X1
y.f = Sin(a / Radius) * Radius + Y1
If x > 0 And x < ImageWidth(#Image) -1
If y > 0 And y < ImageHeight(#Image) -1
Plot(x, y,RGB(255,0,0))
EndIf
EndIf
Next
EndIf
EndIf
ForEach Corner()
LineXY(*PreviousCorner\X, *PreviousCorner\Y, Corner()\X, Corner()\Y, $000000)
Circle(Corner()\X, Corner()\Y, 4, $0000FF)
*PreviousCorner = @Corner()
Next
If *SelectedCorner
Circle(*SelectedCorner\X, *SelectedCorner\Y, 4, $00FF00)
EndIf
StopDrawing()
EndIf
EndProcedure
Define ImageFileName.s, XMLFileName.s
Define Mouse.Integer2D
Define MoveCorner.i
Define *MainNode, *Node
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
Select EventGadget()
Case #CanvasGadget
Mouse\X = GetGadgetAttribute(#CanvasGadget, #PB_Canvas_MouseX)
Mouse\Y = GetGadgetAttribute(#CanvasGadget, #PB_Canvas_MouseY)
Select EventType()
Case #PB_EventType_LeftButtonDown
If EditModus = 1
Repeat
ForEach Corner()
If Pow(Corner()\X-Mouse\X,2)+Pow(Corner()\Y-Mouse\Y,2) < 8*8
*SelectedCorner = @Corner()
Break 2
EndIf
Next
If *SelectedCorner
ChangeCurrentElement(Corner(), *SelectedCorner)
EndIf
*SelectedCorner = AddElement(Corner())
Corner() = Mouse
Until #True
UpdateCanvasGadget()
ElseIf EditModus = 2
ElseIf EditModus = 3
EndIf
Case #PB_EventType_RightButtonDown
If EditModus = 1
ForEach Corner()
If Pow(Corner()\X-Mouse\X,2)+Pow(Corner()\Y-Mouse\Y,2) < 8*8
*SelectedCorner = @Corner()
EndIf
Next
MoveCorner = #True
UpdateCanvasGadget()
ElseIf EditModus = 2
ForEach Corner()
If Pow(Corner()\X-Mouse\X,2)+Pow(Corner()\Y-Mouse\Y,2) < 8*8
*SelectedCorner = @Corner()
EndIf
Next
MoveCorner = #True
UpdateCanvasGadget()
ElseIf EditModus = 3
Zahl = 0
ForEach Corner()
If Pow(Corner()\X-Mouse\X,2)+Pow(Corner()\Y-Mouse\Y,2) < 8*8
*SelectedCorner = @Corner()
Break
EndIf
Zahl + 1
Next
MoveCorner = #True
UpdateCanvasGadget()
EndIf
Case #PB_EventType_MouseMove
If EditModus = 1
If MoveCorner And *SelectedCorner
CopyStructure(@Mouse, *SelectedCorner, Integer2D)
UpdateCanvasGadget()
EndIf
ElseIf EditModus = 2
If MoveCorner
CopyStructure(@Mouse, *SelectedCorner, Integer2D)
UpdateCanvasGadget()
EndIf
ElseIf EditModus = 3
If MoveCorner
CopyStructure(@Mouse, *SelectedCorner, Integer2D)
UpdateCanvasGadget()
If Zahl = 0
SelectElement(Corner(), 1)
Corner()\y = *SelectedCorner\y
SelectElement(Corner(), 3)
Corner()\x = *SelectedCorner\x
ElseIf Zahl = 1
SelectElement(Corner(), 0)
Corner()\y = *SelectedCorner\y
SelectElement(Corner(), 2)
Corner()\x = *SelectedCorner\x
ElseIf Zahl = 2
SelectElement(Corner(), 1)
Corner()\x = *SelectedCorner\x
SelectElement(Corner(), 3)
Corner()\y = *SelectedCorner\y
ElseIf Zahl = 3
SelectElement(Corner(), 2)
Corner()\y = *SelectedCorner\y
SelectElement(Corner(), 0)
Corner()\x = *SelectedCorner\x
EndIf
EndIf
EndIf
Case #PB_EventType_RightButtonUp
If EditModus = 1
MoveCorner = #False
UpdateCanvasGadget()
ElseIf EditModus = 2
MoveCorner = #False
UpdateCanvasGadget()
ElseIf EditModus = 3
MoveCorner = #False
UpdateCanvasGadget()
EndIf
Case #PB_EventType_MiddleButtonDown
If EditModus = 1
ForEach Corner()
If Pow(Corner()\X-Mouse\X,2)+Pow(Corner()\Y-Mouse\Y,2) < 8*8
DeleteElement(Corner())
UpdateCanvasGadget()
Break
EndIf
Next
If ListIndex(Corner()) > -1
*SelectedCorner = @Corner()
EndIf
ElseIf EditModus = 2
ElseIf EditModus = 3
EndIf
EndSelect
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case #MenuItem_LoadImage
ImageFileName = OpenFileRequester("Bild laden...", "", "Bilddateien|*.png;*.bmp;*.jpg", 0)
If ImageFileName And LoadImage(#Image, ImageFileName)
ResizeWindow(#Window, #PB_Ignore, #PB_Ignore, ImageWidth(#Image), ImageHeight(#Image)+MenuHeight())
ResizeGadget(#CanvasGadget, 0, 0, ImageWidth(#Image), ImageHeight(#Image))
UpdateCanvasGadget()
EndIf
Case #MenuItem_LoadPolygon
XMLFileName = OpenFileRequester("Bild laden...", "", "XML|*.xml", 0)
If XMLFileName And LoadXML(#XML, XMLFileName)
ClearList(Corner())
*MainNode = MainXMLNode(#XML)
If GetXMLNodeName(*MainNode) = "Polygon"
EditModus = 1
ElseIf GetXMLNodeName(*MainNode) = "Rectangle"
EditModus = 2
ElseIf GetXMLNodeName(*MainNode) = "Circle"
EditModus = 3
EndIf
ImageFileName = GetXMLAttribute(*MainNode, "Image")
If LoadImage(#Image, ImageFileName)
ResizeWindow(#Window, #PB_Ignore, #PB_Ignore, ImageWidth(#Image), ImageHeight(#Image)+MenuHeight())
ResizeGadget(#CanvasGadget, 0, 0, ImageWidth(#Image), ImageHeight(#Image))
EndIf
*Node = ChildXMLNode(*MainNode)
While *Node
AddElement(Corner())
Corner()\X = Val(GetXMLAttribute(*Node, "X"))
Corner()\Y = Val(GetXMLAttribute(*Node, "Y"))
*Node = NextXMLNode(*Node)
Wend
UpdateCanvasGadget()
EndIf
Case #MenuItem_SavePolygon
XMLFileName = SaveFileRequester("Polygon speichern...", GetNamePart(ImageFileName)+".xml", "XML|*.xml", 0)
If XMLFileName And CreateXML(#XML)
*MainNode = CreateXMLNode(RootXMLNode(#XML))
If EditModus = 1
SetXMLNodeName(*MainNode, "Polygon")
ElseIf EditModus = 2
SetXMLNodeName(*MainNode, "Rectangle")
ElseIf EditModus = 3
SetXMLNodeName(*MainNode, "Circle")
EndIf
SetXMLAttribute(*MainNode, "Image", ImageFileName)
ForEach Corner()
*Node = CreateXMLNode(*MainNode)
SetXMLNodeName(*Node, "Corner")
SetXMLAttribute(*Node, "X", Str(Corner()\X))
SetXMLAttribute(*Node, "Y", Str(Corner()\Y))
Next
FormatXML(#XML, #PB_XML_ReFormat)
SaveXML(#XML, XMLFileName)
EndIf
Case #MenuItem_FreePolygon
ClearList(Corner())
*SelectedCorner = 0
MoveCorner = #False
UpdateCanvasGadget()
EditModus = 1
SetMenuItemState(#Menu,#MenuItem_Polygon,1)
SetMenuItemState(#Menu,#MenuItem_Kreis,0)
SetMenuItemState(#Menu,#MenuItem_Viereck,0)
Case #MenuItem_Polygon
SetMenuItemState(#Menu,#MenuItem_Polygon,1)
SetMenuItemState(#Menu,#MenuItem_Kreis,0)
SetMenuItemState(#Menu,#MenuItem_Viereck,0)
EditModus = 1
ClearList(Corner())
*SelectedCorner = 0
UpdateCanvasGadget()
Case #MenuItem_Kreis
SetMenuItemState(#Menu,#MenuItem_Polygon,0)
SetMenuItemState(#Menu,#MenuItem_Kreis,1)
SetMenuItemState(#Menu,#MenuItem_Viereck,0)
EditModus = 2
ClearList(Corner())
*SelectedCorner = 0
If IsImage(#Image)
AddElement(Corner())
Corner()\X = ImageWidth(#Image)/2
Corner()\Y = ImageHeight(#Image)/2
AddElement(Corner())
If ImageHeight(#Image) > ImageWidth(#Image)
Corner()\X = ImageWidth(#Image)
Corner()\Y = ImageHeight(#Image)/2
Else
Corner()\X = ImageWidth(#Image)/2
Corner()\Y = ImageHeight(#Image)
EndIf
EndIf
UpdateCanvasGadget()
Case #MenuItem_Viereck
SetMenuItemState(#Menu,#MenuItem_Polygon,0)
SetMenuItemState(#Menu,#MenuItem_Kreis,0)
SetMenuItemState(#Menu,#MenuItem_Viereck,1)
EditModus = 3
ClearList(Corner())
*SelectedCorner = 0
If IsImage(#Image)
AddElement(Corner())
Corner()\X = 0
Corner()\Y = 0
AddElement(Corner())
Corner()\X = ImageWidth(#Image)
Corner()\Y = 0
AddElement(Corner())
Corner()\X = ImageWidth(#Image)
Corner()\Y = ImageHeight(#Image)
AddElement(Corner())
Corner()\X = 0
Corner()\Y = ImageHeight(#Image)
EndIf
UpdateCanvasGadget()
Case #MenuItem_Help
a$ = "Hilfetext" + Chr(13)+ Chr(13)
a$ + "Nur Polygon, Linke Maustaste addiert Eckpunkt" + Chr(13)
a$ + "Nur Polygon, Mittlere Maustaste löscht Eckpunkt" + Chr(13)
a$ + "Alle , rechte Maustaste verschiebt Eckpunkt" + Chr(13)+ Chr(13)
MessageRequester("Hilfe", a$, #PB_MessageRequester_Ok)
EndSelect
EndSelect
ForEver