Have a look into the Operator Mesh Add template that comes with Blender.
First of all, you would have to figure out how to create a mesh which is nicely explained in create mesh then add vertices to it in python, then declare an Operator ideally along with a FloatVectorProperty
for the actual location and add that code from before to its execute
method.
The following code is based on Operator Mesh Add template, adds a menu entry to the Mesh menu (ShiftA) as this is the prefered way of adding a new object to the scene. If bl_options
are set to 'UNDO'
the properties of the operator will be displayed in the bottom left of the 3d Viewport (location
in this case) which allows the user to set the parameter interactively while adding the vertex:

import bpy
import bmesh
class MESH_OT_addVertex(bpy.types.Operator):
"""Add a simple vertex object"""
bl_idname = "mesh.primitive_vertex_add"
bl_label = "Add Vertex"
bl_options = {'REGISTER', 'UNDO'}
location: bpy.props.FloatVectorProperty(
name="Location",
default = (0,0,1))
def execute(self, context):
# Create a new mesh based on the given location
# https://blender.stackexchange.com/a/61893/
# https://blender.stackexchange.com/a/23088/
mesh = bpy.data.meshes.new("Vertex")
bm = bmesh.new()
bm.verts.new(self.location)
bm.to_mesh(mesh)
mesh.update()
# Create new object and link object to the active collection
# https://blender.stackexchange.com/a/145715/
obj = bpy.data.objects.new("MyVetexObject", mesh)
context.collection.objects.link(obj)
# Make the object the active one and select it
# https://blender.stackexchange.com/a/126581/
context.view_layer.objects.active = obj
obj.select_set(True)
return {'FINISHED'}
def menu_func(self, context):
self.layout.separator()
self.layout.operator(MESH_OT_addVertex.bl_idname, icon='DOT')
def register():
bpy.utils.register_class(MESH_OT_addVertex)
bpy.types.VIEW3D_MT_mesh_add.append(menu_func)
def unregister():
bpy.utils.unregister_class(MESH_OT_addVertex)
bpy.types.VIEW3D_MT_mesh_add.remove(menu_func)
if __name__ == "__main__":
register()
# test call
#bpy.ops.mesh.primitive_vertex_add()
If you would like to place the operator onto a panel, register your panel, add the Layout.operator()
call to the draw()
method of the panel class and pass its bl_idname
:

def draw (self, context):
layout = self.layout
row = layout.row()
row.operator(MESH_OT_addVertex.bl_idname)
...
In case there is a serious reason to display the coords on your panel as well, I'd suggest register a new FloatVectorProperty
property per scene (bpy.types.Scene
) and pass the values to the Operator within the draw
method of the panel class:
def register():
bpy.utils.register_class(MESH_OT_addVertex)
...
bpy.types.Scene.mytool_location = bpy.props.FloatVectorProperty(
name="Location",
default = (0,0,0)
)
def unregister():
bpy.utils.unregister_class(OBJECT_PT_CustomPanel)
...
del bpy.types.Scene.mytool_location

def draw(self, context):
layout = self.layout
scene = context.scene
layout.prop(scene, "mytool_location")
op = layout.operator(MESH_OT_addVertex.bl_idname)
op.location = scene.mytool_location
...
Further reading