Browse Source

Major changes in plotting structure. Added scroll wheel zoom support. Minor fix in Gerber parser. Updated docs.

Juan Pablo Caram 12 năm trước cách đây
mục cha
commit
66e72221ac

+ 238 - 220
FlatCAM.py

@@ -176,13 +176,24 @@ class FlatCAMObj:
             return
         print "Unknown kind of form item:", fkind
 
-    def plot(self, figure):
-        """
-        Extend this method! Sets up axes if needed and
-        clears them. Descendants must do the actual plotting.
-        """
-        # Creates the axes if necessary and sets them up.
-        self.setup_axes(figure)
+    # def plot(self, figure):
+    #     """
+    #     Extend this method! Sets up axes if needed and
+    #     clears them. Descendants must do the actual plotting.
+    #     """
+    #     # Creates the axes if necessary and sets them up.
+    #     self.setup_axes(figure)
+
+    def plot(self):
+        if self.axes is None or self.axes not in self.app.plotcanvas.figure.axes:
+            self.axes = self.app.plotcanvas.new_axes(self.options['name'])
+
+        if not self.options["plot"]:
+            self.axes.cla()
+            self.app.plotcanvas.auto_adjust_axes()
+            return False
+
+        return True
 
     def serialize(self):
         """
@@ -273,16 +284,11 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
         self.options['noncoppermargin'] *= factor
         self.options['bboxmargin'] *= factor
 
-    def plot(self, figure):
-        """
-        Plots the object on to the specified figure.
-
-        :param figure: Matplotlib figure on which to plot.
-        """
-
-        FlatCAMObj.plot(self, figure)
+    def plot(self):
 
-        if not self.options["plot"]:
+        # Does all the required setup and returns False
+        # if the 'ptint' option is set to False.
+        if not FlatCAMObj.plot(self):
             return
 
         if self.options["mergepolys"]:
@@ -314,7 +320,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
                     x, y = ints.coords.xy
                     self.axes.plot(x, y, linespec)
 
-        self.app.canvas.queue_draw()
+        self.app.plotcanvas.auto_adjust_axes()
 
     def serialize(self):
         return {
@@ -369,10 +375,11 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         self.options['travelz'] *= factor
         self.options['feedrate'] *= factor
 
-    def plot(self, figure):
-        FlatCAMObj.plot(self, figure)
+    def plot(self):
 
-        if not self.options["plot"]:
+        # Does all the required setup and returns False
+        # if the 'ptint' option is set to False.
+        if not FlatCAMObj.plot(self):
             return
 
         try:
@@ -388,8 +395,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
                 x, y = ints.coords.xy
                 self.axes.plot(x, y, 'g-')
 
-        self.app.on_zoom_fit(None)
-        self.app.canvas.queue_draw()
+        self.app.plotcanvas.auto_adjust_axes()
 
     def show_tool_chooser(self):
         win = Gtk.Window()
@@ -444,15 +450,15 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
         # from predecessors.
         self.ser_attrs += ['options', 'kind']
 
-    def plot(self, figure):
-        FlatCAMObj.plot(self, figure)  # Only sets up axes
+    def plot(self):
 
-        if not self.options["plot"]:
+        # Does all the required setup and returns False
+        # if the 'ptint' option is set to False.
+        if not FlatCAMObj.plot(self):
             return
 
         self.plot2(self.axes, tooldia=self.options["tooldia"])
-        self.app.on_zoom_fit(None)
-        self.app.canvas.queue_draw()
+        self.app.plotcanvas.auto_adjust_axes()
 
     def convert_units(self, units):
         factor = CNCjob.convert_units(self, units)
@@ -550,21 +556,17 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
 
         return factor
 
-    def plot(self, figure):
+    def plot(self):
         """
-        Plots the object onto the give figure. Updates the canvas
-        when done.
+        Plots the object into its axes. If None, of if the axes
+        are not part of the app's figure, it fetches new ones.
 
-        :param figure: Matplotlib figure on which to plot.
-        :type figure: Matplotlib.Figure
         :return: None
         """
-        # Sets up and clears self.axes.
-        # Attaches axes to the figure... Maybe we want to do that
-        # when plotting is complete?
-        FlatCAMObj.plot(self, figure)
 
-        if not self.options["plot"]:
+        # Does all the required setup and returns False
+        # if the 'ptint' option is set to False.
+        if not FlatCAMObj.plot(self):
             return
 
         # Make sure solid_geometry is iterable.
@@ -599,8 +601,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
 
             print "WARNING: Did not plot:", str(type(geo))
 
-        self.app.on_zoom_fit(None)
-        self.app.canvas.queue_draw()
+        self.app.plotcanvas.auto_adjust_axes()
 
 
 ########################################
@@ -653,10 +654,18 @@ class App:
         self.builder.connect_signals(self)
 
         #### Make plot area ####
-        self.figure = None
-        self.axes = None
-        self.canvas = None
-        self.setup_plot()
+        # self.figure = None
+        # self.axes = None
+        # self.canvas = None
+        # self.setup_plot()
+        self.plotcanvas = PlotCanvas(self.grid)
+        self.plotcanvas.mpl_connect('button_press_event', self.on_click_over_plot)
+        self.plotcanvas.mpl_connect('motion_notify_event', self.on_mouse_move_over_plot)
+        self.plotcanvas.mpl_connect('key_press_event', self.on_key_over_plot)
+
+        self.axes = self.plotcanvas.axes  # TODO: Just for testing
+        self.figure = self.plotcanvas.figure  # TODO: Just for testing
+        self.canvas = self.plotcanvas.canvas  # TODO: Just for testing
 
         self.setup_tooltips()
 
@@ -788,40 +797,6 @@ class App:
         delete.set_tooltip_markup("Delete selected\nobject.")
         toolbar.insert(delete, -1)
 
-    def setup_plot(self):
-        """
-        Sets up the main plotting area by creating a Matplotlib
-        figure in self.canvas, adding axes and configuring them.
-        These axes should not be ploted on and are just there to
-        display the axes ticks and grid.
-
-        :return: None
-        :rtype: None
-        """
-
-        self.figure = Figure(dpi=50)
-        self.axes = self.figure.add_axes([0.05, 0.05, 0.9, 0.9], label="base", alpha=0.0)
-        self.axes.set_aspect(1)
-        #t = arange(0.0,5.0,0.01)
-        #s = sin(2*pi*t)
-        #self.axes.plot(t,s)
-        self.axes.grid(True)
-        self.figure.patch.set_visible(False)
-
-        self.canvas = FigureCanvas(self.figure)  # a Gtk.DrawingArea
-        self.canvas.set_hexpand(1)
-        self.canvas.set_vexpand(1)
-
-        # Events
-        self.canvas.mpl_connect('button_press_event', self.on_click_over_plot)
-        self.canvas.mpl_connect('motion_notify_event', self.on_mouse_move_over_plot)
-        self.canvas.set_can_focus(True)  # For key press
-        self.canvas.mpl_connect('key_press_event', self.on_key_over_plot)
-        #self.canvas.mpl_connect('scroll_event', self.on_scroll_over_plot)
-        self.canvas.connect("configure-event", self.on_canvas_configure)
-
-        self.grid.attach(self.canvas, 0, 0, 600, 400)
-
     def setup_obj_classes(self):
         """
         Sets up application specifics on the FlatCAMObj class.
@@ -883,44 +858,44 @@ class App:
         """
         self.info_label.set_text(text)
 
-    def zoom(self, factor, center=None):
-        """
-        Zooms the plot by factor around a given
-        center point. Takes care of re-drawing.
-
-        :param factor: Number by which to scale the plot.
-        :type factor: float
-        :param center: Coordinates [x, y] of the point around which to scale the plot.
-        :type center: list
-        :return: None
-        """
-        xmin, xmax = self.axes.get_xlim()
-        ymin, ymax = self.axes.get_ylim()
-        width = xmax - xmin
-        height = ymax - ymin
-
-        if center is None:
-            center = [(xmin + xmax) / 2.0, (ymin + ymax) / 2.0]
-
-        # For keeping the point at the pointer location
-        relx = (xmax - center[0]) / width
-        rely = (ymax - center[1]) / height
-
-        new_width = width / factor
-        new_height = height / factor
-
-        xmin = center[0] - new_width * (1 - relx)
-        xmax = center[0] + new_width * relx
-        ymin = center[1] - new_height * (1 - rely)
-        ymax = center[1] + new_height * rely
-
-        for name in self.stuff:
-            self.stuff[name].axes.set_xlim((xmin, xmax))
-            self.stuff[name].axes.set_ylim((ymin, ymax))
-        self.axes.set_xlim((xmin, xmax))
-        self.axes.set_ylim((ymin, ymax))
-
-        self.canvas.queue_draw()
+    # def zoom(self, factor, center=None):
+    #     """
+    #     Zooms the plot by factor around a given
+    #     center point. Takes care of re-drawing.
+    #
+    #     :param factor: Number by which to scale the plot.
+    #     :type factor: float
+    #     :param center: Coordinates [x, y] of the point around which to scale the plot.
+    #     :type center: list
+    #     :return: None
+    #     """
+    #     xmin, xmax = self.axes.get_xlim()
+    #     ymin, ymax = self.axes.get_ylim()
+    #     width = xmax - xmin
+    #     height = ymax - ymin
+    #
+    #     if center is None:
+    #         center = [(xmin + xmax) / 2.0, (ymin + ymax) / 2.0]
+    #
+    #     # For keeping the point at the pointer location
+    #     relx = (xmax - center[0]) / width
+    #     rely = (ymax - center[1]) / height
+    #
+    #     new_width = width / factor
+    #     new_height = height / factor
+    #
+    #     xmin = center[0] - new_width * (1 - relx)
+    #     xmax = center[0] + new_width * relx
+    #     ymin = center[1] - new_height * (1 - rely)
+    #     ymax = center[1] + new_height * rely
+    #
+    #     for name in self.stuff:
+    #         self.stuff[name].axes.set_xlim((xmin, xmax))
+    #         self.stuff[name].axes.set_ylim((ymin, ymax))
+    #     self.axes.set_xlim((xmin, xmax))
+    #     self.axes.set_ylim((ymin, ymax))
+    #
+    #     self.canvas.queue_draw()
 
     def build_list(self):
         """
@@ -958,7 +933,7 @@ class App:
 
         :return: None
         """
-        self.clear_plots()
+        self.plotcanvas.clear()
         self.set_progress_bar(0.1, "Re-plotting...")
 
         def thread_func(app_obj):
@@ -969,34 +944,18 @@ class App:
                 GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, ""))
                 return
             for i in self.stuff:
-                self.stuff[i].plot(self.figure)
+                self.stuff[i].plot()
                 percentage += delta
                 GLib.idle_add(lambda: app_obj.set_progress_bar(percentage, "Re-plotting..."))
 
+            app_obj.plotcanvas.auto_adjust_axes()
             self.on_zoom_fit(None)
-            self.axes.grid(True)
-            self.canvas.queue_draw()
             GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, ""))
 
         t = threading.Thread(target=thread_func, args=(self,))
         t.daemon = True
         t.start()
 
-    def clear_plots(self):
-        """
-        Clears self.axes and self.figure.
-
-        :return: None
-        """
-
-        # TODO: Create a setup_axes method that gets called here and in setup_plot?
-        self.axes.cla()
-        self.figure.clf()
-        self.figure.add_axes(self.axes)
-        self.axes.set_aspect(1)
-        self.axes.grid(True)
-        self.canvas.queue_draw()
-
     def get_eval(self, widget_name):
         """
         Runs eval() on the on the text entry of name 'widget_name'
@@ -1107,8 +1066,7 @@ class App:
 
         # Plot
         # TODO: (Thread-safe?)
-        obj.plot(self.figure)
-        obj.axes.set_alpha(0.0)
+        obj.plot()
         self.on_zoom_fit(None)
 
         return obj
@@ -1144,60 +1102,60 @@ class App:
         except:
             return None
 
-    def adjust_axes(self, xmin, ymin, xmax, ymax):
-        """
-        Adjusts axes of all plots while maintaining the use of the whole canvas
-        and an aspect ratio to 1:1 between x and y axes. The parameters are an original
-        request that will be modified to fit these restrictions.
-
-        :param xmin: Requested minimum value for the X axis.
-        :type xmin: float
-        :param ymin: Requested minimum value for the Y axis.
-        :type ymin: float
-        :param xmax: Requested maximum value for the X axis.
-        :type xmax: float
-        :param ymax: Requested maximum value for the Y axis.
-        :type ymax: float
-        :return: None
-        """
-        m_x = 15  # pixels
-        m_y = 25  # pixels
-        width = xmax - xmin
-        height = ymax - ymin
-        try:
-            r = width / height
-        except:
-            print "ERROR: Height is", height
-            return
-        Fw, Fh = self.canvas.get_width_height()
-        Fr = float(Fw) / Fh
-        x_ratio = float(m_x) / Fw
-        y_ratio = float(m_y) / Fh
-
-        if r > Fr:
-            ycenter = (ymin + ymax) / 2.0
-            newheight = height * r / Fr
-            ymin = ycenter - newheight / 2.0
-            ymax = ycenter + newheight / 2.0
-        else:
-            xcenter = (xmax + ymin) / 2.0
-            newwidth = width * Fr / r
-            xmin = xcenter - newwidth / 2.0
-            xmax = xcenter + newwidth / 2.0
-
-        for name in self.stuff:
-            if self.stuff[name].axes is None:
-                continue
-            self.stuff[name].axes.set_xlim((xmin, xmax))
-            self.stuff[name].axes.set_ylim((ymin, ymax))
-            self.stuff[name].axes.set_position([x_ratio, y_ratio,
-                                                1 - 2 * x_ratio, 1 - 2 * y_ratio])
-        self.axes.set_xlim((xmin, xmax))
-        self.axes.set_ylim((ymin, ymax))
-        self.axes.set_position([x_ratio, y_ratio,
-                                1 - 2 * x_ratio, 1 - 2 * y_ratio])
-
-        self.canvas.queue_draw()
+    # def adjust_axes(self, xmin, ymin, xmax, ymax):
+    #     """
+    #     Adjusts axes of all plots while maintaining the use of the whole canvas
+    #     and an aspect ratio to 1:1 between x and y axes. The parameters are an original
+    #     request that will be modified to fit these restrictions.
+    #
+    #     :param xmin: Requested minimum value for the X axis.
+    #     :type xmin: float
+    #     :param ymin: Requested minimum value for the Y axis.
+    #     :type ymin: float
+    #     :param xmax: Requested maximum value for the X axis.
+    #     :type xmax: float
+    #     :param ymax: Requested maximum value for the Y axis.
+    #     :type ymax: float
+    #     :return: None
+    #     """
+    #     m_x = 15  # pixels
+    #     m_y = 25  # pixels
+    #     width = xmax - xmin
+    #     height = ymax - ymin
+    #     try:
+    #         r = width / height
+    #     except:
+    #         print "ERROR: Height is", height
+    #         return
+    #     Fw, Fh = self.canvas.get_width_height()
+    #     Fr = float(Fw) / Fh
+    #     x_ratio = float(m_x) / Fw
+    #     y_ratio = float(m_y) / Fh
+    #
+    #     if r > Fr:
+    #         ycenter = (ymin + ymax) / 2.0
+    #         newheight = height * r / Fr
+    #         ymin = ycenter - newheight / 2.0
+    #         ymax = ycenter + newheight / 2.0
+    #     else:
+    #         xcenter = (xmax + ymin) / 2.0
+    #         newwidth = width * Fr / r
+    #         xmin = xcenter - newwidth / 2.0
+    #         xmax = xcenter + newwidth / 2.0
+    #
+    #     for name in self.stuff:
+    #         if self.stuff[name].axes is None:
+    #             continue
+    #         self.stuff[name].axes.set_xlim((xmin, xmax))
+    #         self.stuff[name].axes.set_ylim((ymin, ymax))
+    #         self.stuff[name].axes.set_position([x_ratio, y_ratio,
+    #                                             1 - 2 * x_ratio, 1 - 2 * y_ratio])
+    #     self.axes.set_xlim((xmin, xmax))
+    #     self.axes.set_ylim((ymin, ymax))
+    #     self.axes.set_position([x_ratio, y_ratio,
+    #                             1 - 2 * x_ratio, 1 - 2 * y_ratio])
+    #
+    #     self.canvas.queue_draw()
 
     def load_defaults(self):
         """
@@ -1495,8 +1453,7 @@ class App:
             return
         assert isinstance(obj, Geometry)
         obj.offset(vect)
-        obj.plot(self.figure)
-        self.on_zoom_fit(None)  # TODO: Change this. Just done to aline all axes.
+        obj.plot()
         return
 
     def on_cb_plot_toggled(self, widget):
@@ -1508,8 +1465,7 @@ class App:
         """
 
         self.get_current().read_form()
-        self.get_current().plot(self.figure)
-        self.on_zoom_fit(None)  # TODO: Does not update correctly otherwise.
+        self.get_current().plot()
 
     def on_about(self, widget):
         """
@@ -2026,9 +1982,10 @@ class App:
         :return: None
         """
 
-        xmin, xmax = self.axes.get_xlim()
-        ymin, ymax = self.axes.get_ylim()
-        self.adjust_axes(xmin, ymin, xmax, ymax)
+        # xmin, xmax = self.axes.get_xlim()
+        # ymin, ymax = self.axes.get_ylim()
+        # self.adjust_axes(xmin, ymin, xmax, ymax)
+        self.plotcanvas.auto_adjust_axes()
 
     def on_row_activated(self, widget, path, col):
         """
@@ -2085,7 +2042,7 @@ class App:
             assert isinstance(app_obj, App)
             #GLib.idle_add(lambda: app_obj.set_progress_bar(0.5, "Plotting..."))
             #GLib.idle_add(lambda: app_obj.get_current().plot(app_obj.figure))
-            obj.plot(app_obj.figure)
+            obj.plot()
             GLib.idle_add(lambda: app_obj.on_zoom_fit(None))
             GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, "Idle"))
 
@@ -2389,8 +2346,8 @@ class App:
         name = copy.copy(self.selected_item_name)
 
         # Remove plot
-        self.figure.delaxes(self.get_current().axes)
-        self.canvas.queue_draw()
+        self.plotcanvas.figure.delaxes(self.get_current().axes)
+        self.plotcanvas.auto_adjust_axes()
 
         # Remove from dictionary
         self.stuff.pop(self.selected_item_name)
@@ -2419,7 +2376,7 @@ class App:
         :param widget: The widget from which this was called.
         :return: None
         """
-        self.clear_plots()
+        self.plotcanvas.clear()
 
     def on_activate_name(self, entry):
         """
@@ -2484,7 +2441,7 @@ class App:
         """
         # Remove everythong from memory
         # Clear plot
-        self.clear_plots()
+        self.plotcanvas.clear()
 
         # Clear object editor
         #self.setup_component_editor()
@@ -2746,7 +2703,7 @@ class App:
         :param event: Ignored.
         :return: None
         """
-        self.zoom(1.5)
+        self.plotcanvas.zoom(1.5)
         return
 
     def on_zoom_out(self, event):
@@ -2757,7 +2714,7 @@ class App:
         :param event: Ignored.
         :return: None
         """
-        self.zoom(1 / 1.5)
+        self.plotcanvas.zoom(1 / 1.5)
 
     def on_zoom_fit(self, event):
         """
@@ -2775,18 +2732,7 @@ class App:
         xmax += 0.05 * width
         ymin -= 0.05 * height
         ymax += 0.05 * height
-        self.adjust_axes(xmin, ymin, xmax, ymax)
-
-    # def on_scroll_over_plot(self, event):
-    #     print "Scroll"
-    #     center = [event.xdata, event.ydata]
-    #     if sign(event.step):
-    #         self.zoom(1.5, center=center)
-    #     else:
-    #         self.zoom(1/1.5, center=center)
-    #
-    # def on_window_scroll(self, event):
-    #     print "Scroll"
+        self.plotcanvas.adjust_axes(xmin, ymin, xmax, ymax)
 
     def on_key_over_plot(self, event):
         """
@@ -2811,11 +2757,11 @@ class App:
             return
 
         if event.key == '2':  # 2
-            self.zoom(1 / 1.5, self.mouse)
+            self.plotcanvas.zoom(1 / 1.5, self.mouse)
             return
 
         if event.key == '3':  # 3
-            self.zoom(1.5, self.mouse)
+            self.plotcanvas.zoom(1.5, self.mouse)
             return
 
         if event.key == 'm':
@@ -2884,6 +2830,14 @@ class PlotCanvas:
     """
 
     def __init__(self, container):
+        """
+        The constructor configures the Matplotlib figure that
+        will contain all plots, creates the base axes and connects
+        events to the plotting area.
+
+        :param container: The parent container in which to draw plots.
+        :rtype: PlotCanvas
+        """
         # Options
         self.x_margin = 15  # pixels
         self.y_margin = 25  # Pixels
@@ -2910,6 +2864,14 @@ class PlotCanvas:
         # Attach to parent
         self.container.attach(self.canvas, 0, 0, 600, 400)
 
+        # Events
+        self.canvas.mpl_connect('motion_notify_event', self.on_mouse_move)
+        self.canvas.connect('configure-event', self.auto_adjust_axes)
+        self.canvas.add_events(Gdk.EventMask.SMOOTH_SCROLL_MASK)
+        self.canvas.connect("scroll-event", self.on_scroll)
+
+        self.mouse = [0,0]
+
     def mpl_connect(self, event_name, callback):
         """
         Attach an event handler to the canvas through the Matplotlib interface.
@@ -2955,7 +2917,7 @@ class PlotCanvas:
 
     def adjust_axes(self, xmin, ymin, xmax, ymax):
         """
-        Adjusts axes of all plots while maintaining the use of the whole canvas
+        Adjusts all axes while maintaining the use of the whole canvas
         and an aspect ratio to 1:1 between x and y axes. The parameters are an original
         request that will be modified to fit these restrictions.
 
@@ -2995,6 +2957,12 @@ class PlotCanvas:
 
         # Adjust axes
         for ax in self.figure.get_axes():
+            if ax._label != 'base':
+                ax.set_frame_on(False)  # No frame
+                ax.set_xticks([])  # No tick
+                ax.set_yticks([])  # No ticks
+                ax.patch.set_visible(False)  # No background
+                ax.set_aspect(1)
             ax.set_xlim((xmin, xmax))
             ax.set_ylim((ymin, ymax))
             ax.set_position([x_ratio, y_ratio, 1 - 2 * x_ratio, 1 - 2 * y_ratio])
@@ -3002,10 +2970,11 @@ class PlotCanvas:
         # Re-draw
         self.canvas.queue_draw()
 
-    def auto_adjust_axes(self):
+    def auto_adjust_axes(self, *args):
         """
         Calls ``adjust_axes()`` using the extents of the base axes.
 
+        :rtype : None
         :return: None
         """
 
@@ -3053,5 +3022,54 @@ class PlotCanvas:
         # Re-draw
         self.canvas.queue_draw()
 
+    def new_axes(self, name):
+        """
+        Creates and returns an Axes object attached to this object's Figure.
+
+        :param name: Unique label for the axes.
+        :return: Axes attached to the figure.
+        :rtype: Axes
+        """
+
+        return self.figure.add_axes([0.05, 0.05, 0.9, 0.9], label=name)
+
+    # def plot_axes(self, axes):
+    #
+    #     if axes not in self.figure.axes:
+    #         self.figure.add_axes(axes)
+    #
+    #     # Basic configuration
+    #     axes.set_frame_on(False)  # No frame
+    #     axes.set_xticks([])  # No tick
+    #     axes.set_yticks([])  # No ticks
+    #     axes.patch.set_visible(False)  # No background
+    #     axes.set_aspect(1)
+    #
+    #     # Adjust limits
+    #     self.auto_adjust_axes()
+
+    def on_scroll(self, canvas, event):
+        """
+        Scroll event handler.
+
+        :param canvas: The widget generating the event. Ignored.
+        :param event: Event object containing the event information.
+        :return: None
+        """
+        z, direction = event.get_scroll_direction()
+        if direction is Gdk.ScrollDirection.UP:
+            self.zoom(1.5, self.mouse)
+        else:
+            self.zoom(1/1.5, self.mouse)
+
+    def on_mouse_move(self, event):
+        """
+        Mouse movement event hadler.
+
+        :param event: Contains information about the event.
+        :return: None
+        """
+        self.mouse = [event.xdata, event.ydata]
+
 app = App()
 Gtk.main()

+ 3 - 0
FlatCAM.ui

@@ -4565,6 +4565,8 @@ polygons defined in Gerber.</property>
                                       <object class="GtkAlignment" id="alignment5">
                                         <property name="visible">True</property>
                                         <property name="can_focus">False</property>
+                                        <property name="top_padding">6</property>
+                                        <property name="bottom_padding">6</property>
                                         <property name="left_padding">12</property>
                                         <property name="right_padding">6</property>
                                         <child>
@@ -4734,6 +4736,7 @@ defaults.</property>
               <object class="GtkGrid" id="grid1">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK | GDK_TOUCH_MASK | GDK_SMOOTH_SCROLL_MASK</property>
                 <child>
                   <object class="GtkScrollbar" id="scrollbar1">
                     <property name="height_request">25</property>

+ 12 - 2
camlib.py

@@ -762,11 +762,18 @@ class Gerber (Geometry):
 
         self.flash_geometry = []
         for flash in self.flashes:
-            aperture = self.apertures[flash['aperture']]
+
+            try:
+                aperture = self.apertures[flash['aperture']]
+            except KeyError:
+                print "ERROR: Trying to flash with unknown aperture: ", flash['aperture']
+                continue
+
             if aperture['type'] == 'C':  # Circles
                 circle = Point(flash['loc']).buffer(aperture['size']/2)
                 self.flash_geometry.append(circle)
                 continue
+
             if aperture['type'] == 'R':  # Rectangles
                 loc = flash['loc']
                 width = aperture['width']
@@ -778,6 +785,7 @@ class Gerber (Geometry):
                 rectangle = shply_box(minx, miny, maxx, maxy)
                 self.flash_geometry.append(rectangle)
                 continue
+
             if aperture['type'] == 'O':  # Obround
                 loc = flash['loc']
                 width = aperture['width']
@@ -795,6 +803,7 @@ class Gerber (Geometry):
                 obround = cascaded_union([c1, c2]).convex_hull
                 self.flash_geometry.append(obround)
                 continue
+
             print "WARNING: Aperture type %s not implemented" % (aperture['type'])
     
     def create_geometry(self):
@@ -1022,6 +1031,7 @@ class Excellon(Geometry):
 
                     try:
                         y = float(match.group(2))
+                        current_y = y
                     except TypeError:
                         y = current_y
 
@@ -1637,7 +1647,7 @@ def get_bounds(geometry_set):
     xmax = -Inf
     ymax = -Inf
 
-    print "Getting bounds of:", str(geometry_set)
+    #print "Getting bounds of:", str(geometry_set)
     for gs in geometry_set:
         try:
             gxmin, gymin, gxmax, gymax = geometry_set[gs].bounds()

BIN
doc/build/.doctrees/camlib.doctree


BIN
doc/build/.doctrees/environment.pickle


BIN
doc/build/.doctrees/index.doctree


+ 15 - 3
doc/build/_sources/camlib.txt

@@ -1,4 +1,16 @@
-This is the main file for camlib
-=================================
+Camlib
+======
 
-Some text.
+.. automodule:: camlib
+
+.. autoclass:: Geometry
+    :members:
+
+.. autoclass:: Gerber(Geometry)
+    :members:
+
+.. autoclass:: Excellon
+    :members:
+
+.. autoclass:: CNCjob
+    :members:

+ 3 - 30
doc/build/_sources/index.txt

@@ -13,37 +13,10 @@ Contents:
 .. toctree::
    :maxdepth: 2
 
-.. automodule:: FlatCAM
+   camlib
+   flatcamobj
+   app
 
-.. autoclass:: App
-    :members:
-
-.. autoclass:: Geometry
-    :members:
-
-.. autoclass:: Gerber(Geometry)
-    :members:
-
-.. autoclass:: Excellon
-    :members:
-
-.. autoclass:: CNCjob
-    :members:
-
-.. autoclass:: FlatCAMObj
-    :members:
-
-.. autoclass:: FlatCAMGerber
-    :members:
-
-.. autoclass:: FlatCAMExcellon
-    :members:
-
-.. autoclass:: FlatCAMCNCjob
-    :members:
-
-.. autoclass:: FlatCAMGeometry
-    :members:
 
 
 Indices and tables

BIN
doc/build/_static/contents.png


+ 0 - 256
doc/build/_static/default.css

@@ -1,256 +0,0 @@
-/*
- * default.css_t
- * ~~~~~~~~~~~~~
- *
- * Sphinx stylesheet -- default theme.
- *
- * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-@import url("basic.css");
-
-/* -- page layout ----------------------------------------------------------- */
-
-body {
-    font-family: sans-serif;
-    font-size: 100%;
-    background-color: #11303d;
-    color: #000;
-    margin: 0;
-    padding: 0;
-}
-
-div.document {
-    background-color: #1c4e63;
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 0 0 0 230px;
-}
-
-div.body {
-    background-color: #ffffff;
-    color: #000000;
-    padding: 0 20px 30px 20px;
-}
-
-div.footer {
-    color: #ffffff;
-    width: 100%;
-    padding: 9px 0 9px 0;
-    text-align: center;
-    font-size: 75%;
-}
-
-div.footer a {
-    color: #ffffff;
-    text-decoration: underline;
-}
-
-div.related {
-    background-color: #133f52;
-    line-height: 30px;
-    color: #ffffff;
-}
-
-div.related a {
-    color: #ffffff;
-}
-
-div.sphinxsidebar {
-}
-
-div.sphinxsidebar h3 {
-    font-family: 'Trebuchet MS', sans-serif;
-    color: #ffffff;
-    font-size: 1.4em;
-    font-weight: normal;
-    margin: 0;
-    padding: 0;
-}
-
-div.sphinxsidebar h3 a {
-    color: #ffffff;
-}
-
-div.sphinxsidebar h4 {
-    font-family: 'Trebuchet MS', sans-serif;
-    color: #ffffff;
-    font-size: 1.3em;
-    font-weight: normal;
-    margin: 5px 0 0 0;
-    padding: 0;
-}
-
-div.sphinxsidebar p {
-    color: #ffffff;
-}
-
-div.sphinxsidebar p.topless {
-    margin: 5px 10px 10px 10px;
-}
-
-div.sphinxsidebar ul {
-    margin: 10px;
-    padding: 0;
-    color: #ffffff;
-}
-
-div.sphinxsidebar a {
-    color: #98dbcc;
-}
-
-div.sphinxsidebar input {
-    border: 1px solid #98dbcc;
-    font-family: sans-serif;
-    font-size: 1em;
-}
-
-
-
-/* -- hyperlink styles ------------------------------------------------------ */
-
-a {
-    color: #355f7c;
-    text-decoration: none;
-}
-
-a:visited {
-    color: #355f7c;
-    text-decoration: none;
-}
-
-a:hover {
-    text-decoration: underline;
-}
-
-
-
-/* -- body styles ----------------------------------------------------------- */
-
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: 'Trebuchet MS', sans-serif;
-    background-color: #f2f2f2;
-    font-weight: normal;
-    color: #20435c;
-    border-bottom: 1px solid #ccc;
-    margin: 20px -20px 10px -20px;
-    padding: 3px 0 3px 10px;
-}
-
-div.body h1 { margin-top: 0; font-size: 200%; }
-div.body h2 { font-size: 160%; }
-div.body h3 { font-size: 140%; }
-div.body h4 { font-size: 120%; }
-div.body h5 { font-size: 110%; }
-div.body h6 { font-size: 100%; }
-
-a.headerlink {
-    color: #c60f0f;
-    font-size: 0.8em;
-    padding: 0 4px 0 4px;
-    text-decoration: none;
-}
-
-a.headerlink:hover {
-    background-color: #c60f0f;
-    color: white;
-}
-
-div.body p, div.body dd, div.body li {
-    text-align: justify;
-    line-height: 130%;
-}
-
-div.admonition p.admonition-title + p {
-    display: inline;
-}
-
-div.admonition p {
-    margin-bottom: 5px;
-}
-
-div.admonition pre {
-    margin-bottom: 5px;
-}
-
-div.admonition ul, div.admonition ol {
-    margin-bottom: 5px;
-}
-
-div.note {
-    background-color: #eee;
-    border: 1px solid #ccc;
-}
-
-div.seealso {
-    background-color: #ffc;
-    border: 1px solid #ff6;
-}
-
-div.topic {
-    background-color: #eee;
-}
-
-div.warning {
-    background-color: #ffe4e4;
-    border: 1px solid #f66;
-}
-
-p.admonition-title {
-    display: inline;
-}
-
-p.admonition-title:after {
-    content: ":";
-}
-
-pre {
-    padding: 5px;
-    background-color: #eeffcc;
-    color: #333333;
-    line-height: 120%;
-    border: 1px solid #ac9;
-    border-left: none;
-    border-right: none;
-}
-
-tt {
-    background-color: #ecf0f3;
-    padding: 0 1px 0 1px;
-    font-size: 0.95em;
-}
-
-th {
-    background-color: #ede;
-}
-
-.warning tt {
-    background: #efc2c2;
-}
-
-.note tt {
-    background: #d6d6d6;
-}
-
-.viewcode-back {
-    font-family: sans-serif;
-}
-
-div.viewcode-block:target {
-    background-color: #f4debf;
-    border-top: 1px solid #ac9;
-    border-bottom: 1px solid #ac9;
-}

BIN
doc/build/_static/dialog-note.png


BIN
doc/build/_static/dialog-seealso.png


BIN
doc/build/_static/dialog-todo.png


BIN
doc/build/_static/dialog-topic.png


BIN
doc/build/_static/dialog-warning.png


+ 0 - 310
doc/build/_static/epub.css

@@ -1,310 +0,0 @@
-/*
- * default.css_t
- * ~~~~~~~~~~~~~
- *
- * Sphinx stylesheet -- default theme.
- *
- * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-@import url("basic.css");
-
-/* -- page layout ----------------------------------------------------------- */
-
-body {
-    font-family: {{ theme_bodyfont }};
-    font-size: 100%;
-    background-color: {{ theme_footerbgcolor }};
-    color: #000;
-    margin: 0;
-    padding: 0;
-}
-
-div.document {
-    background-color: {{ theme_sidebarbgcolor }};
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 0 0 0 230px;
-}
-
-div.body {
-    background-color: {{ theme_bgcolor }};
-    color: {{ theme_textcolor }};
-    padding: 0 20px 30px 20px;
-}
-
-{%- if theme_rightsidebar|tobool %}
-div.bodywrapper {
-    margin: 0 230px 0 0;
-}
-{%- endif %}
-
-div.footer {
-    color: {{ theme_footertextcolor }};
-    width: 100%;
-    padding: 9px 0 9px 0;
-    text-align: center;
-    font-size: 75%;
-}
-
-div.footer a {
-    color: {{ theme_footertextcolor }};
-    text-decoration: underline;
-}
-
-div.related {
-    background-color: {{ theme_relbarbgcolor }};
-    line-height: 30px;
-    color: {{ theme_relbartextcolor }};
-}
-
-div.related a {
-    color: {{ theme_relbarlinkcolor }};
-}
-
-div.sphinxsidebar {
-    {%- if theme_stickysidebar|tobool %}
-    top: 30px;
-    bottom: 0;
-    margin: 0;
-    position: fixed;
-    overflow: auto;
-    height: auto;
-    {%- endif %}
-    {%- if theme_rightsidebar|tobool %}
-    float: right;
-    {%- if theme_stickysidebar|tobool %}
-    right: 0;
-    {%- endif %}
-    {%- endif %}
-}
-
-{%- if theme_stickysidebar|tobool %}
-/* this is nice, but it it leads to hidden headings when jumping
-   to an anchor */
-/*
-div.related {
-    position: fixed;
-}
-
-div.documentwrapper {
-    margin-top: 30px;
-}
-*/
-{%- endif %}
-
-div.sphinxsidebar h3 {
-    font-family: {{ theme_headfont }};
-    color: {{ theme_sidebartextcolor }};
-    font-size: 1.4em;
-    font-weight: normal;
-    margin: 0;
-    padding: 0;
-}
-
-div.sphinxsidebar h3 a {
-    color: {{ theme_sidebartextcolor }};
-}
-
-div.sphinxsidebar h4 {
-    font-family: {{ theme_headfont }};
-    color: {{ theme_sidebartextcolor }};
-    font-size: 1.3em;
-    font-weight: normal;
-    margin: 5px 0 0 0;
-    padding: 0;
-}
-
-div.sphinxsidebar p {
-    color: {{ theme_sidebartextcolor }};
-}
-
-div.sphinxsidebar p.topless {
-    margin: 5px 10px 10px 10px;
-}
-
-div.sphinxsidebar ul {
-    margin: 10px;
-    padding: 0;
-    color: {{ theme_sidebartextcolor }};
-}
-
-div.sphinxsidebar a {
-    color: {{ theme_sidebarlinkcolor }};
-}
-
-div.sphinxsidebar input {
-    border: 1px solid {{ theme_sidebarlinkcolor }};
-    font-family: sans-serif;
-    font-size: 1em;
-}
-
-{% if theme_collapsiblesidebar|tobool %}
-/* for collapsible sidebar */
-div#sidebarbutton {
-    background-color: {{ theme_sidebarbtncolor }};
-}
-{% endif %}
-
-/* -- hyperlink styles ------------------------------------------------------ */
-
-a {
-    color: {{ theme_linkcolor }};
-    text-decoration: none;
-}
-
-a:visited {
-    color: {{ theme_visitedlinkcolor }};
-    text-decoration: none;
-}
-
-a:hover {
-    text-decoration: underline;
-}
-
-{% if theme_externalrefs|tobool %}
-a.external {
-   text-decoration: none;
-   border-bottom: 1px dashed {{ theme_linkcolor }};
-}
-
-a.external:hover {
-   text-decoration: none;
-   border-bottom: none;
-}
-
-a.external:visited {
-    text-decoration: none;
-    border-bottom: 1px dashed {{ theme_visitedlinkcolor }};
-}
-{% endif %}
-
-/* -- body styles ----------------------------------------------------------- */
-
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: {{ theme_headfont }};
-    background-color: {{ theme_headbgcolor }};
-    font-weight: normal;
-    color: {{ theme_headtextcolor }};
-    border-bottom: 1px solid #ccc;
-    margin: 20px -20px 10px -20px;
-    padding: 3px 0 3px 10px;
-}
-
-div.body h1 { margin-top: 0; font-size: 200%; }
-div.body h2 { font-size: 160%; }
-div.body h3 { font-size: 140%; }
-div.body h4 { font-size: 120%; }
-div.body h5 { font-size: 110%; }
-div.body h6 { font-size: 100%; }
-
-a.headerlink {
-    color: {{ theme_headlinkcolor }};
-    font-size: 0.8em;
-    padding: 0 4px 0 4px;
-    text-decoration: none;
-}
-
-a.headerlink:hover {
-    background-color: {{ theme_headlinkcolor }};
-    color: white;
-}
-
-div.body p, div.body dd, div.body li {
-    text-align: justify;
-    line-height: 130%;
-}
-
-div.admonition p.admonition-title + p {
-    display: inline;
-}
-
-div.admonition p {
-    margin-bottom: 5px;
-}
-
-div.admonition pre {
-    margin-bottom: 5px;
-}
-
-div.admonition ul, div.admonition ol {
-    margin-bottom: 5px;
-}
-
-div.note {
-    background-color: #eee;
-    border: 1px solid #ccc;
-}
-
-div.seealso {
-    background-color: #ffc;
-    border: 1px solid #ff6;
-}
-
-div.topic {
-    background-color: #eee;
-}
-
-div.warning {
-    background-color: #ffe4e4;
-    border: 1px solid #f66;
-}
-
-p.admonition-title {
-    display: inline;
-}
-
-p.admonition-title:after {
-    content: ":";
-}
-
-pre {
-    padding: 5px;
-    background-color: {{ theme_codebgcolor }};
-    color: {{ theme_codetextcolor }};
-    line-height: 120%;
-    border: 1px solid #ac9;
-    border-left: none;
-    border-right: none;
-}
-
-tt {
-    background-color: #ecf0f3;
-    padding: 0 1px 0 1px;
-    font-size: 0.95em;
-}
-
-th {
-    background-color: #ede;
-}
-
-.warning tt {
-    background: #efc2c2;
-}
-
-.note tt {
-    background: #d6d6d6;
-}
-
-.viewcode-back {
-    font-family: {{ theme_bodyfont }};
-}
-
-div.viewcode-block:target {
-    background-color: #f4debf;
-    border-top: 1px solid #ac9;
-    border-bottom: 1px solid #ac9;
-}

BIN
doc/build/_static/footerbg.png


BIN
doc/build/_static/headerbg.png


+ 0 - 7
doc/build/_static/ie6.css

@@ -1,7 +0,0 @@
-* html img,
-* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none",
-this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')",
-this.src = "_static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''),
-this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')",
-this.runtimeStyle.backgroundImage = "none")),this.pngSet=true)
-);}

BIN
doc/build/_static/middlebg.png


BIN
doc/build/_static/navigation.png


+ 0 - 342
doc/build/_static/pyramid.css

@@ -1,342 +0,0 @@
-/*
- * pyramid.css_t
- * ~~~~~~~~~~~~
- *
- * Sphinx stylesheet -- pylons theme.
- *
- * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
- 
-@import url("basic.css");
- 
-/* -- page layout ----------------------------------------------------------- */
- 
-body {
-    font-family: "Nobile", sans-serif;
-    font-size: 100%;
-    background-color: #393939;
-    color: #ffffff;
-    margin: 0;
-    padding: 0;
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 0 0 0 230px;
-}
-
-hr {
-    border: 1px solid #B1B4B6;
-}
- 
-div.document {
-    background-color: #eee;
-}
-
-div.header {
-    width:100%;
-    background: #f4ad32 url(headerbg.png) repeat-x 0 top;
-    border-bottom: 2px solid #ffffff;
-}
-
-div.logo {
-    text-align: center;
-    padding-top: 10px;
-}
-
-div.body {
-    background-color: #ffffff;
-    color: #3E4349;
-    padding: 0 30px 30px 30px;
-    font-size: 1em;
-    border: 2px solid #ddd;
-    border-right-style: none;
-    overflow: auto;
-}
- 
-div.footer {
-    color: #ffffff;
-    width: 100%;
-    padding: 13px 0;
-    text-align: center;
-    font-size: 75%;
-    background: transparent;
-    clear:both;
-}
- 
-div.footer a {
-    color: #ffffff;
-    text-decoration: none;
-}
-
-div.footer a:hover {
-    color: #e88f00;
-    text-decoration: underline;
-}
- 
-div.related {
-    line-height: 30px;
-    color: #373839;
-    font-size: 0.8em;
-    background-color: #eee;
-}
- 
-div.related a {
-    color: #1b61d6;
-}
-
-div.related ul {
-    padding-left: 240px;
-}
- 
-div.sphinxsidebar {
-    font-size: 0.75em;
-    line-height: 1.5em;
-}
-
-div.sphinxsidebarwrapper{
-    padding: 10px 0;
-}
- 
-div.sphinxsidebar h3,
-div.sphinxsidebar h4 {
-    font-family: "Neuton", sans-serif;
-    color: #373839;
-    font-size: 1.4em;
-    font-weight: normal;
-    margin: 0;
-    padding: 5px 10px;
-    border-bottom: 2px solid #ddd;
-}
-
-div.sphinxsidebar h4{
-    font-size: 1.3em;
-}
- 
-div.sphinxsidebar h3 a {
-    color: #000000;
-}
- 
- 
-div.sphinxsidebar p {
-    color: #888;
-    padding: 5px 20px;
-}
- 
-div.sphinxsidebar p.topless {
-}
- 
-div.sphinxsidebar ul {
-    margin: 10px 20px;
-    padding: 0;
-    color: #373839;
-}
- 
-div.sphinxsidebar a {
-    color: #444;
-}
- 
-div.sphinxsidebar input {
-    border: 1px solid #ccc;
-    font-family: sans-serif;
-    font-size: 1em;
-}
-
-div.sphinxsidebar input[type=text]{
-    margin-left: 20px;
-}
-
-/* -- sidebars -------------------------------------------------------------- */
-
-div.sidebar {
-    margin: 0 0 0.5em 1em;
-    border: 2px solid #c6d880;
-    background-color: #e6efc2;
-    width: 40%;
-    float: right;
-    border-right-style: none;
-    border-left-style: none;
-    padding: 10px 20px;
-}
-
-p.sidebar-title {
-    font-weight: bold;
-}
-
-/* -- body styles ----------------------------------------------------------- */
- 
-a, a .pre {
-    color: #1b61d6;
-    text-decoration: none;
-}
- 
-a:hover, a:hover .pre {
-    text-decoration: underline;
-}
- 
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: "Neuton", sans-serif;
-    background-color: #ffffff;
-    font-weight: normal;
-    color: #373839;
-    margin: 30px 0px 10px 0px;
-    padding: 5px 0;
-}
- 
-div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; }
-div.body h2 { font-size: 150%; background-color: #ffffff; }
-div.body h3 { font-size: 120%; background-color: #ffffff; }
-div.body h4 { font-size: 110%; background-color: #ffffff; }
-div.body h5 { font-size: 100%; background-color: #ffffff; }
-div.body h6 { font-size: 100%; background-color: #ffffff; }
- 
-a.headerlink {
-    color: #1b61d6;
-    font-size: 0.8em;
-    padding: 0 4px 0 4px;
-    text-decoration: none;
-}
- 
-a.headerlink:hover {
-    text-decoration: underline;
-}
- 
-div.body p, div.body dd, div.body li {
-    line-height: 1.5em;
-}
- 
-div.admonition p.admonition-title + p {
-    display: inline;
-}
-
-div.admonition {
-    background: #eeeeec;
-    border: 2px solid #babdb6;
-    border-right-style: none;
-    border-left-style: none;
-    padding: 10px 20px 10px 60px;
-}
-
-div.highlight{
-    background-color: white;
-}
-
-div.note {
-    border: 2px solid #7a9eec;
-    border-right-style: none;
-    border-left-style: none;
-    padding: 10px 20px 10px 60px;
-    background: #e1ecfe url(dialog-note.png) no-repeat 10px 8px;
-}
- 
-div.seealso {
-    background: #fff6bf url(dialog-seealso.png) no-repeat 10px 8px;
-    border: 2px solid #ffd324;
-    border-left-style: none;
-    border-right-style: none;
-    padding: 10px 20px 10px 60px;
-}
- 
-div.topic {
-    background: #eeeeee;
-    border: 2px solid #C6C9CB;
-    padding: 10px 20px;
-    border-right-style: none;
-    border-left-style: none;
-}
- 
-div.warning {
-    background: #fbe3e4 url(dialog-warning.png) no-repeat 10px 8px;
-    border: 2px solid #fbc2c4;
-    border-right-style: none;
-    border-left-style: none;
-    padding: 10px 20px 10px 60px;
-}
-
-div.admonition-todo {
-    background: #f2d9b4 url(dialog-todo.png) no-repeat 10px 8px;
-    border: 2px solid #e9b96e;
-    border-right-style: none;
-    border-left-style: none;
-    padding: 10px 20px 10px 60px;
-}
- 
-div.note p.admonition-title,
-div.warning p.admonition-title,
-div.seealso p.admonition-title,
-div.admonition-todo p.admonition-title {
-    display: none;
-}
- 
-p.admonition-title:after {
-    content: ":";
-}
- 
-pre {
-    padding: 10px;
-    background-color: #fafafa;
-    color: #222;
-    line-height: 1.2em;
-    border: 2px solid #C6C9CB;
-    font-size: 1.1em;
-    margin: 1.5em 0 1.5em 0;
-    border-right-style: none;
-    border-left-style: none;
-}
- 
-tt {
-    background-color: transparent;
-    color: #222;
-    font-size: 1.1em;
-    font-family: monospace;
-}
-
-.viewcode-back {
-    font-family: "Nobile", sans-serif;
-}
-
-div.viewcode-block:target {
-    background-color: #fff6bf;
-    border: 2px solid #ffd324;
-    border-left-style: none;
-    border-right-style: none;
-    padding: 10px 20px;
-}
-
-table.highlighttable {
-    width: 100%;
-}
-
-table.highlighttable td {
-    padding: 0;
-}
-
-a em.std-term {
-   color: #007f00;
-}
-
-a:hover em.std-term {
-    text-decoration: underline;
-}
-
-.download {
-    font-family: "Nobile", sans-serif;
-    font-weight: normal;
-    font-style: normal;
-}
-
-tt.xref {
-    font-weight: normal;
-    font-style: normal;
-}

+ 0 - 159
doc/build/_static/sidebar.js

@@ -1,159 +0,0 @@
-/*
- * sidebar.js
- * ~~~~~~~~~~
- *
- * This script makes the Sphinx sidebar collapsible.
- *
- * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds
- * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
- * used to collapse and expand the sidebar.
- *
- * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
- * and the width of the sidebar and the margin-left of the document
- * are decreased. When the sidebar is expanded the opposite happens.
- * This script saves a per-browser/per-session cookie used to
- * remember the position of the sidebar among the pages.
- * Once the browser is closed the cookie is deleted and the position
- * reset to the default (expanded).
- *
- * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-$(function() {
-  
-  
-  
-  
-  
-  
-  
-
-  // global elements used by the functions.
-  // the 'sidebarbutton' element is defined as global after its
-  // creation, in the add_sidebar_button function
-  var bodywrapper = $('.bodywrapper');
-  var sidebar = $('.sphinxsidebar');
-  var sidebarwrapper = $('.sphinxsidebarwrapper');
-
-  // for some reason, the document has no sidebar; do not run into errors
-  if (!sidebar.length) return;
-
-  // original margin-left of the bodywrapper and width of the sidebar
-  // with the sidebar expanded
-  var bw_margin_expanded = bodywrapper.css('margin-left');
-  var ssb_width_expanded = sidebar.width();
-
-  // margin-left of the bodywrapper and width of the sidebar
-  // with the sidebar collapsed
-  var bw_margin_collapsed = '.8em';
-  var ssb_width_collapsed = '.8em';
-
-  // colors used by the current theme
-  var dark_color = $('.related').css('background-color');
-  var light_color = $('.document').css('background-color');
-
-  function sidebar_is_collapsed() {
-    return sidebarwrapper.is(':not(:visible)');
-  }
-
-  function toggle_sidebar() {
-    if (sidebar_is_collapsed())
-      expand_sidebar();
-    else
-      collapse_sidebar();
-  }
-
-  function collapse_sidebar() {
-    sidebarwrapper.hide();
-    sidebar.css('width', ssb_width_collapsed);
-    bodywrapper.css('margin-left', bw_margin_collapsed);
-    sidebarbutton.css({
-        'margin-left': '0',
-        'height': bodywrapper.height()
-    });
-    sidebarbutton.find('span').text('»');
-    sidebarbutton.attr('title', _('Expand sidebar'));
-    document.cookie = 'sidebar=collapsed';
-  }
-
-  function expand_sidebar() {
-    bodywrapper.css('margin-left', bw_margin_expanded);
-    sidebar.css('width', ssb_width_expanded);
-    sidebarwrapper.show();
-    sidebarbutton.css({
-        'margin-left': ssb_width_expanded-12,
-        'height': bodywrapper.height()
-    });
-    sidebarbutton.find('span').text('«');
-    sidebarbutton.attr('title', _('Collapse sidebar'));
-    document.cookie = 'sidebar=expanded';
-  }
-
-  function add_sidebar_button() {
-    sidebarwrapper.css({
-        'float': 'left',
-        'margin-right': '0',
-        'width': ssb_width_expanded - 28
-    });
-    // create the button
-    sidebar.append(
-        '<div id="sidebarbutton"><span>&laquo;</span></div>'
-    );
-    var sidebarbutton = $('#sidebarbutton');
-    light_color = sidebarbutton.css('background-color');
-    // find the height of the viewport to center the '<<' in the page
-    var viewport_height;
-    if (window.innerHeight)
- 	  viewport_height = window.innerHeight;
-    else
-	  viewport_height = $(window).height();
-    sidebarbutton.find('span').css({
-        'display': 'block',
-        'margin-top': (viewport_height - sidebar.position().top - 20) / 2
-    });
-
-    sidebarbutton.click(toggle_sidebar);
-    sidebarbutton.attr('title', _('Collapse sidebar'));
-    sidebarbutton.css({
-        'color': '#FFFFFF',
-        'border-left': '1px solid ' + dark_color,
-        'font-size': '1.2em',
-        'cursor': 'pointer',
-        'height': bodywrapper.height(),
-        'padding-top': '1px',
-        'margin-left': ssb_width_expanded - 12
-    });
-
-    sidebarbutton.hover(
-      function () {
-          $(this).css('background-color', dark_color);
-      },
-      function () {
-          $(this).css('background-color', light_color);
-      }
-    );
-  }
-
-  function set_position_from_cookie() {
-    if (!document.cookie)
-      return;
-    var items = document.cookie.split(';');
-    for(var k=0; k<items.length; k++) {
-      var key_val = items[k].split('=');
-      var key = key_val[0].replace(/ /, "");  // strip leading spaces
-      if (key == 'sidebar') {
-        var value = key_val[1];
-        if ((value == 'collapsed') && (!sidebar_is_collapsed()))
-          collapse_sidebar();
-        else if ((value == 'expanded') && (sidebar_is_collapsed()))
-          expand_sidebar();
-      }
-    }
-  }
-
-  add_sidebar_button();
-  var sidebarbutton = $('#sidebarbutton');
-  set_position_from_cookie();
-});

+ 0 - 339
doc/build/_static/sphinxdoc.css

@@ -1,339 +0,0 @@
-/*
- * sphinxdoc.css_t
- * ~~~~~~~~~~~~~~~
- *
- * Sphinx stylesheet -- sphinxdoc theme.  Originally created by
- * Armin Ronacher for Werkzeug.
- *
- * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-@import url("basic.css");
-
-/* -- page layout ----------------------------------------------------------- */
-
-body {
-    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
-                 'Verdana', sans-serif;
-    font-size: 14px;
-    letter-spacing: -0.01em;
-    line-height: 150%;
-    text-align: center;
-    background-color: #BFD1D4;
-    color: black;
-    padding: 0;
-    border: 1px solid #aaa;
-
-    margin: 0px 80px 0px 80px;
-    min-width: 740px;
-}
-
-div.document {
-    background-color: white;
-    text-align: left;
-    background-image: url(contents.png);
-    background-repeat: repeat-x;
-}
-
-div.bodywrapper {
-    margin: 0 240px 0 0;
-    border-right: 1px solid #ccc;
-}
-
-div.body {
-    margin: 0;
-    padding: 0.5em 20px 20px 20px;
-}
-
-div.related {
-    font-size: 1em;
-}
-
-div.related ul {
-    background-image: url(navigation.png);
-    height: 2em;
-    border-top: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-}
-
-div.related ul li {
-    margin: 0;
-    padding: 0;
-    height: 2em;
-    float: left;
-}
-
-div.related ul li.right {
-    float: right;
-    margin-right: 5px;
-}
-
-div.related ul li a {
-    margin: 0;
-    padding: 0 5px 0 5px;
-    line-height: 1.75em;
-    color: #EE9816;
-}
-
-div.related ul li a:hover {
-    color: #3CA8E7;
-}
-
-div.sphinxsidebarwrapper {
-    padding: 0;
-}
-
-div.sphinxsidebar {
-    margin: 0;
-    padding: 0.5em 15px 15px 0;
-    width: 210px;
-    float: right;
-    font-size: 1em;
-    text-align: left;
-}
-
-div.sphinxsidebar h3, div.sphinxsidebar h4 {
-    margin: 1em 0 0.5em 0;
-    font-size: 1em;
-    padding: 0.1em 0 0.1em 0.5em;
-    color: white;
-    border: 1px solid #86989B;
-    background-color: #AFC1C4;
-}
-
-div.sphinxsidebar h3 a {
-    color: white;
-}
-
-div.sphinxsidebar ul {
-    padding-left: 1.5em;
-    margin-top: 7px;
-    padding: 0;
-    line-height: 130%;
-}
-
-div.sphinxsidebar ul ul {
-    margin-left: 20px;
-}
-
-div.footer {
-    background-color: #E3EFF1;
-    color: #86989B;
-    padding: 3px 8px 3px 0;
-    clear: both;
-    font-size: 0.8em;
-    text-align: right;
-}
-
-div.footer a {
-    color: #86989B;
-    text-decoration: underline;
-}
-
-/* -- body styles ----------------------------------------------------------- */
-
-p {    
-    margin: 0.8em 0 0.5em 0;
-}
-
-a {
-    color: #CA7900;
-    text-decoration: none;
-}
-
-a:hover {
-    color: #2491CF;
-}
-
-div.body a {
-    text-decoration: underline;
-}
-
-h1 {
-    margin: 0;
-    padding: 0.7em 0 0.3em 0;
-    font-size: 1.5em;
-    color: #11557C;
-}
-
-h2 {
-    margin: 1.3em 0 0.2em 0;
-    font-size: 1.35em;
-    padding: 0;
-}
-
-h3 {
-    margin: 1em 0 -0.3em 0;
-    font-size: 1.2em;
-}
-
-div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
-    color: black!important;
-}
-
-h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
-    display: none;
-    margin: 0 0 0 0.3em;
-    padding: 0 0.2em 0 0.2em;
-    color: #aaa!important;
-}
-
-h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
-h5:hover a.anchor, h6:hover a.anchor {
-    display: inline;
-}
-
-h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
-h5 a.anchor:hover, h6 a.anchor:hover {
-    color: #777;
-    background-color: #eee;
-}
-
-a.headerlink {
-    color: #c60f0f!important;
-    font-size: 1em;
-    margin-left: 6px;
-    padding: 0 4px 0 4px;
-    text-decoration: none!important;
-}
-
-a.headerlink:hover {
-    background-color: #ccc;
-    color: white!important;
-}
-
-cite, code, tt {
-    font-family: 'Consolas', 'Deja Vu Sans Mono',
-                 'Bitstream Vera Sans Mono', monospace;
-    font-size: 0.95em;
-    letter-spacing: 0.01em;
-}
-
-tt {
-    background-color: #f2f2f2;
-    border-bottom: 1px solid #ddd;
-    color: #333;
-}
-
-tt.descname, tt.descclassname, tt.xref {
-    border: 0;
-}
-
-hr {
-    border: 1px solid #abc;
-    margin: 2em;
-}
-
-a tt {
-    border: 0;
-    color: #CA7900;
-}
-
-a tt:hover {
-    color: #2491CF;
-}
-
-pre {
-    font-family: 'Consolas', 'Deja Vu Sans Mono',
-                 'Bitstream Vera Sans Mono', monospace;
-    font-size: 0.95em;
-    letter-spacing: 0.015em;
-    line-height: 120%;
-    padding: 0.5em;
-    border: 1px solid #ccc;
-    background-color: #f8f8f8;
-}
-
-pre a {
-    color: inherit;
-    text-decoration: underline;
-}
-
-td.linenos pre {
-    padding: 0.5em 0;
-}
-
-div.quotebar {
-    background-color: #f8f8f8;
-    max-width: 250px;
-    float: right;
-    padding: 2px 7px;
-    border: 1px solid #ccc;
-}
-
-div.topic {
-    background-color: #f8f8f8;
-}
-
-table {
-    border-collapse: collapse;
-    margin: 0 -0.5em 0 -0.5em;
-}
-
-table td, table th {
-    padding: 0.2em 0.5em 0.2em 0.5em;
-}
-
-div.admonition, div.warning {
-    font-size: 0.9em;
-    margin: 1em 0 1em 0;
-    border: 1px solid #86989B;
-    background-color: #f7f7f7;
-    padding: 0;
-}
-
-div.admonition p, div.warning p {
-    margin: 0.5em 1em 0.5em 1em;
-    padding: 0;
-}
-
-div.admonition pre, div.warning pre {
-    margin: 0.4em 1em 0.4em 1em;
-}
-
-div.admonition p.admonition-title,
-div.warning p.admonition-title {
-    margin: 0;
-    padding: 0.1em 0 0.1em 0.5em;
-    color: white;
-    border-bottom: 1px solid #86989B;
-    font-weight: bold;
-    background-color: #AFC1C4;
-}
-
-div.warning {
-    border: 1px solid #940000;
-}
-
-div.warning p.admonition-title {
-    background-color: #CF0000;
-    border-bottom-color: #940000;
-}
-
-div.admonition ul, div.admonition ol,
-div.warning ul, div.warning ol {
-    margin: 0.1em 0.5em 0.5em 3em;
-    padding: 0;
-}
-
-div.versioninfo {
-    margin: 1em 0 0 0;
-    border: 1px solid #ccc;
-    background-color: #DDEAF0;
-    padding: 8px;
-    line-height: 1.3em;
-    font-size: 0.9em;
-}
-
-.viewcode-back {
-    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
-                 'Verdana', sans-serif;
-}
-
-div.viewcode-block:target {
-    background-color: #f4debf;
-    border-top: 1px solid #ac9;
-    border-bottom: 1px solid #ac9;
-}

BIN
doc/build/_static/transparent.gif


+ 762 - 10
doc/build/camlib.html

@@ -7,7 +7,7 @@
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>This is the main file for camlib &mdash; Cirkuix 0.5 documentation</title>
+  <title>Camlib &mdash; Cirkuix 0.5 documentation</title>
   
 
   
@@ -52,7 +52,9 @@
   
 
   
-    <link rel="top" title="Cirkuix 0.5 documentation" href="index.html"/> 
+    <link rel="top" title="Cirkuix 0.5 documentation" href="index.html"/>
+        <link rel="next" title="FlatCAM Objects" href="flatcamobj.html"/>
+        <link rel="prev" title="Welcome to FlatCAM’s documentation!" href="index.html"/> 
 
   <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
 
@@ -78,11 +80,12 @@
       <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
         
         
-            <!-- Local TOC -->
-            <div class="local-toc"><ul>
-<li><a class="reference internal" href="#">This is the main file for camlib</a></li>
+            <ul class="current">
+<li class="toctree-l1 current"><a class="current reference internal" href="">Camlib</a></li>
+<li class="toctree-l1"><a class="reference internal" href="flatcamobj.html">FlatCAM Objects</a></li>
+<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a></li>
 </ul>
-</div>
+
         
       </div>
       &nbsp;
@@ -104,7 +107,7 @@
   <ul class="wy-breadcrumbs">
     <li><a href="index.html">Docs</a> &raquo;</li>
       
-    <li>This is the main file for camlib</li>
+    <li>Camlib</li>
       <li class="wy-breadcrumbs-aside">
         
           <a href="_sources/camlib.txt" rel="nofollow"> View page source</a>
@@ -115,15 +118,764 @@
 </div>
           <div role="main">
             
-  <div class="section" id="this-is-the-main-file-for-camlib">
-<h1>This is the main file for camlib<a class="headerlink" href="#this-is-the-main-file-for-camlib" title="Permalink to this headline">¶</a></h1>
-<p>Some text.</p>
+  <div class="section" id="module-camlib">
+<span id="camlib"></span><h1>Camlib<a class="headerlink" href="#module-camlib" title="Permalink to this headline">¶</a></h1>
+<dl class="class">
+<dt id="camlib.Geometry">
+<em class="property">class </em><tt class="descclassname">camlib.</tt><tt class="descname">Geometry</tt><a class="headerlink" href="#camlib.Geometry" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="method">
+<dt id="camlib.Geometry.bounds">
+<tt class="descname">bounds</tt><big>(</big><big>)</big><a class="headerlink" href="#camlib.Geometry.bounds" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns coordinates of rectangular bounds
+of geometry: (xmin, ymin, xmax, ymax).</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Geometry.clear_polygon">
+<tt class="descname">clear_polygon</tt><big>(</big><em>polygon</em>, <em>tooldia</em>, <em>overlap=0.15</em><big>)</big><a class="headerlink" href="#camlib.Geometry.clear_polygon" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates geometry inside a polygon for a tool to cover
+the whole area.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Geometry.convert_units">
+<tt class="descname">convert_units</tt><big>(</big><em>units</em><big>)</big><a class="headerlink" href="#camlib.Geometry.convert_units" title="Permalink to this definition">¶</a></dt>
+<dd><p>Converts the units of the object to <tt class="docutils literal"><span class="pre">units</span></tt> by scaling all
+the geometry appropriately. This call <tt class="docutils literal"><span class="pre">scale()</span></tt>. Don&#8217;t call
+it again in descendents.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>units</strong> (<em>str</em>) &#8211; &#8220;IN&#8221; or &#8220;MM&#8221;</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Scaling factor resulting from unit change.</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Geometry.from_dict">
+<tt class="descname">from_dict</tt><big>(</big><em>d</em><big>)</big><a class="headerlink" href="#camlib.Geometry.from_dict" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets object&#8217;s attributes from a dictionary.
+Attributes to include are listed in <tt class="docutils literal"><span class="pre">self.ser_attrs</span></tt>.
+This method will look only for only and all the
+attributes in <tt class="docutils literal"><span class="pre">self.ser_attrs</span></tt>. They must all
+be present. Use only for deserializing saved
+objects.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>d</strong> (<em>dict</em>) &#8211; Dictionary of attributes to set in the object.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Geometry.get_empty_area">
+<tt class="descname">get_empty_area</tt><big>(</big><em>boundary=None</em><big>)</big><a class="headerlink" href="#camlib.Geometry.get_empty_area" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the complement of self.solid_geometry within
+the given boundary polygon. If not specified, it defaults to
+the rectangular bounding box of self.solid_geometry.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Geometry.isolation_geometry">
+<tt class="descname">isolation_geometry</tt><big>(</big><em>offset</em><big>)</big><a class="headerlink" href="#camlib.Geometry.isolation_geometry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates contours around geometry at a given
+offset distance.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>offset</strong> (<em>float</em>) &#8211; Offset distance.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">The buffered geometry.</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">Shapely.MultiPolygon or Shapely.Polygon</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Geometry.offset">
+<tt class="descname">offset</tt><big>(</big><em>vect</em><big>)</big><a class="headerlink" href="#camlib.Geometry.offset" title="Permalink to this definition">¶</a></dt>
+<dd><p>Offset the geometry by the given vector. Override this method.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>vect</strong> (<em>tuple</em>) &#8211; (x, y) vector by which to offset the object.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Geometry.scale">
+<tt class="descname">scale</tt><big>(</big><em>factor</em><big>)</big><a class="headerlink" href="#camlib.Geometry.scale" title="Permalink to this definition">¶</a></dt>
+<dd><p>Scales all of the object&#8217;s geometry by a given factor. Override
+this method.
+:param factor: Number by which to scale.
+:type factor: float
+:return: None
+:rtype: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Geometry.size">
+<tt class="descname">size</tt><big>(</big><big>)</big><a class="headerlink" href="#camlib.Geometry.size" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns (width, height) of rectangular
+bounds of geometry.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Geometry.to_dict">
+<tt class="descname">to_dict</tt><big>(</big><big>)</big><a class="headerlink" href="#camlib.Geometry.to_dict" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns a respresentation of the object as a dictionary.
+Attributes to include are listed in <tt class="docutils literal"><span class="pre">self.ser_attrs</span></tt>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">A dictionary-encoded copy of the object.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">dict</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="camlib.Gerber">
+<em class="property">class </em><tt class="descclassname">camlib.</tt><tt class="descname">Gerber</tt><big>(</big><em>Geometry</em><big>)</big><a class="headerlink" href="#camlib.Gerber" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>ATTRIBUTES</strong></p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">apertures</span></tt> (dict): The keys are names/identifiers of each aperture.
+The values are dictionaries key/value pairs which describe the aperture. The
+type key is always present and the rest depend on the key:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="24%" />
+<col width="76%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>type</td>
+<td>(str) &#8220;C&#8221;, &#8220;R&#8221;, or &#8220;O&#8221;</td>
+</tr>
+<tr class="row-odd"><td>others</td>
+<td>Depend on <tt class="docutils literal"><span class="pre">type</span></tt></td>
+</tr>
+</tbody>
+</table>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">paths</span></tt> (list): A path is described by a line an aperture that follows that
+line. Each paths[i] is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="20%" />
+<col width="80%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>linestring</td>
+<td>(Shapely.LineString) The actual path.</td>
+</tr>
+<tr class="row-odd"><td>aperture</td>
+<td>(str) The key for an aperture in apertures.</td>
+</tr>
+</tbody>
+</table>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">flashes</span></tt> (list): Flashes are single-point strokes of an aperture. Each
+is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="20%" />
+<col width="80%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>loc</td>
+<td>(list) [x (float), y (float)] coordinates.</td>
+</tr>
+<tr class="row-odd"><td>aperture</td>
+<td>(str) The key for an aperture in apertures.</td>
+</tr>
+</tbody>
+</table>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">regions</span></tt> (list): Are surfaces defined by a polygon (Shapely.Polygon),
+which have an exterior and zero or more interiors. An aperture is also
+associated with a region. Each is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="18%" />
+<col width="82%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>polygon</td>
+<td>(Shapely.Polygon) The polygon defining the region.</td>
+</tr>
+<tr class="row-odd"><td>aperture</td>
+<td>(str) The key for an aperture in apertures.</td>
+</tr>
+</tbody>
+</table>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">flash_geometry</span></tt> (list): List of (Shapely) geometric object resulting
+from <tt class="docutils literal"><span class="pre">flashes</span></tt>. These are generated from <tt class="docutils literal"><span class="pre">flashes</span></tt> in <tt class="docutils literal"><span class="pre">do_flashes()</span></tt>.</li>
+<li><tt class="docutils literal"><span class="pre">buffered_paths</span></tt> (list): List of (Shapely) polygons resulting from
+<em>buffering</em> (or thickening) the <tt class="docutils literal"><span class="pre">paths</span></tt> with the aperture. These are
+generated from <tt class="docutils literal"><span class="pre">paths</span></tt> in <tt class="docutils literal"><span class="pre">buffer_paths()</span></tt>.</li>
+</ul>
+<p><strong>USAGE</strong>:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">g</span> <span class="o">=</span> <span class="n">Gerber</span><span class="p">()</span>
+<span class="n">g</span><span class="o">.</span><span class="n">parse_file</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
+<span class="n">g</span><span class="o">.</span><span class="n">create_geometry</span><span class="p">()</span>
+<span class="n">do_something</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">solid_geometry</span><span class="p">)</span>
+</pre></div>
+</div>
+<dl class="method">
+<dt id="camlib.Gerber.aperture_parse">
+<tt class="descname">aperture_parse</tt><big>(</big><em>gline</em><big>)</big><a class="headerlink" href="#camlib.Gerber.aperture_parse" title="Permalink to this definition">¶</a></dt>
+<dd><p>Parse gerber aperture definition into dictionary of apertures.
+The following kinds and their attributes are supported:</p>
+<ul class="simple">
+<li><em>Circular (C)</em>: size (float)</li>
+<li><em>Rectangle (R)</em>: width (float), height (float)</li>
+<li><em>Obround (O)</em>: width (float), height (float).</li>
+</ul>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>gline</strong> (<em>str</em>) &#8211; Line of Gerber code known to have an aperture definition.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Identifier of the aperture.</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">str</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Gerber.buffer_paths">
+<tt class="descname">buffer_paths</tt><big>(</big><big>)</big><a class="headerlink" href="#camlib.Gerber.buffer_paths" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is part of the parsing process. &#8220;Thickens&#8221; the paths
+by their appertures. This will only work for circular appertures.
+:return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Gerber.create_geometry">
+<tt class="descname">create_geometry</tt><big>(</big><big>)</big><a class="headerlink" href="#camlib.Gerber.create_geometry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Geometry from a Gerber file is made up entirely of polygons.
+Every stroke (linear or circular) has an aperture which gives
+it thickness. Additionally, aperture strokes have non-zero area,
+and regions naturally do as well.</p>
+<p>:rtype : None
+:return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Gerber.do_flashes">
+<tt class="descname">do_flashes</tt><big>(</big><big>)</big><a class="headerlink" href="#camlib.Gerber.do_flashes" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates geometry for Gerber flashes (aperture on a single point).</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Gerber.fix_regions">
+<tt class="descname">fix_regions</tt><big>(</big><big>)</big><a class="headerlink" href="#camlib.Gerber.fix_regions" title="Permalink to this definition">¶</a></dt>
+<dd><p>Overwrites the region polygons with fixed
+versions if found to be invalid (according to Shapely).</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="camlib.Gerber.frac_digits">
+<tt class="descname">frac_digits</tt><em class="property"> = None</em><a class="headerlink" href="#camlib.Gerber.frac_digits" title="Permalink to this definition">¶</a></dt>
+<dd><p>Number of fraction digits in Gerber numbers. Used during parsing.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Gerber.get_bounding_box">
+<tt class="descname">get_bounding_box</tt><big>(</big><em>margin=0.0</em>, <em>rounded=False</em><big>)</big><a class="headerlink" href="#camlib.Gerber.get_bounding_box" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates and returns a rectangular polygon bounding at a distance of
+margin from the object&#8217;s <tt class="docutils literal"><span class="pre">solid_geometry</span></tt>. If margin &gt; 0, the polygon
+can optionally have rounded corners of radius equal to margin.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>margin</strong> (<em>float</em>) &#8211; Distance to enlarge the rectangular bounding
+box in both positive and negative, x and y axes.</li>
+<li><strong>rounded</strong> (<em>bool</em>) &#8211; Wether or not to have rounded corners.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">The bounding box.</p>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">Shapely.Polygon</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="camlib.Gerber.int_digits">
+<tt class="descname">int_digits</tt><em class="property"> = None</em><a class="headerlink" href="#camlib.Gerber.int_digits" title="Permalink to this definition">¶</a></dt>
+<dd><p>Number of integer digits in Gerber numbers. Used during parsing.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Gerber.offset">
+<tt class="descname">offset</tt><big>(</big><em>vect</em><big>)</big><a class="headerlink" href="#camlib.Gerber.offset" title="Permalink to this definition">¶</a></dt>
+<dd><p>Offsets the objects&#8217; geometry on the XY plane by a given vector.
+These are:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">paths</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">regions</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">flashes</span></tt></li>
+</ul>
+<p>Then <tt class="docutils literal"><span class="pre">buffered_paths</span></tt>, <tt class="docutils literal"><span class="pre">flash_geometry</span></tt> and <tt class="docutils literal"><span class="pre">solid_geometry</span></tt>
+are re-created with <tt class="docutils literal"><span class="pre">self.create_geometry()</span></tt>.
+:param vect: (x, y) offset vector.
+:type vect: tuple
+:return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Gerber.parse_file">
+<tt class="descname">parse_file</tt><big>(</big><em>filename</em><big>)</big><a class="headerlink" href="#camlib.Gerber.parse_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calls Gerber.parse_lines() with array of lines
+read from the given file.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Gerber.parse_lines">
+<tt class="descname">parse_lines</tt><big>(</big><em>glines</em><big>)</big><a class="headerlink" href="#camlib.Gerber.parse_lines" title="Permalink to this definition">¶</a></dt>
+<dd><p>Main Gerber parser. Reads Gerber and populates <tt class="docutils literal"><span class="pre">self.paths</span></tt>, <tt class="docutils literal"><span class="pre">self.apertures</span></tt>,
+<tt class="docutils literal"><span class="pre">self.flashes</span></tt>, <tt class="docutils literal"><span class="pre">self.regions</span></tt> and <tt class="docutils literal"><span class="pre">self.units</span></tt>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>glines</strong> (<em>list</em>) &#8211; Gerber code as list of strings, each element being
+one line of the source file.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">None</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Gerber.scale">
+<tt class="descname">scale</tt><big>(</big><em>factor</em><big>)</big><a class="headerlink" href="#camlib.Gerber.scale" title="Permalink to this definition">¶</a></dt>
+<dd><p>Scales the objects&#8217; geometry on the XY plane by a given factor.
+These are:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">apertures</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">paths</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">regions</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">flashes</span></tt></li>
+</ul>
+<p>Then <tt class="docutils literal"><span class="pre">buffered_paths</span></tt>, <tt class="docutils literal"><span class="pre">flash_geometry</span></tt> and <tt class="docutils literal"><span class="pre">solid_geometry</span></tt>
+are re-created with <tt class="docutils literal"><span class="pre">self.create_geometry()</span></tt>.
+:param factor: Number by which to scale.
+:type factor: float
+:rtype : None</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="camlib.Excellon">
+<em class="property">class </em><tt class="descclassname">camlib.</tt><tt class="descname">Excellon</tt><a class="headerlink" href="#camlib.Excellon" title="Permalink to this definition">¶</a></dt>
+<dd><p><em>ATTRIBUTES</em></p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">tools</span></tt> (dict): The key is the tool name and the value is
+the size (diameter).</li>
+<li><tt class="docutils literal"><span class="pre">drills</span></tt> (list): Each is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="31%" />
+<col width="69%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>point</td>
+<td>(Shapely.Point) Where to drill</td>
+</tr>
+<tr class="row-odd"><td>tool</td>
+<td>(str) A key in <tt class="docutils literal"><span class="pre">tools</span></tt></td>
+</tr>
+</tbody>
+</table>
+<dl class="method">
+<dt id="camlib.Excellon.offset">
+<tt class="descname">offset</tt><big>(</big><em>vect</em><big>)</big><a class="headerlink" href="#camlib.Excellon.offset" title="Permalink to this definition">¶</a></dt>
+<dd><p>Offsets geometry on the XY plane in the object by a given vector.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>vect</strong> (<em>tuple</em>) &#8211; (x, y) offset vector.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Excellon.parse_file">
+<tt class="descname">parse_file</tt><big>(</big><em>filename</em><big>)</big><a class="headerlink" href="#camlib.Excellon.parse_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>Reads the specified file as array of lines as
+passes it to <tt class="docutils literal"><span class="pre">parse_lines()</span></tt>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>filename</strong> (<em>str</em>) &#8211; The file to be read and parsed.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Excellon.parse_lines">
+<tt class="descname">parse_lines</tt><big>(</big><em>elines</em><big>)</big><a class="headerlink" href="#camlib.Excellon.parse_lines" title="Permalink to this definition">¶</a></dt>
+<dd><p>Main Excellon parser.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>elines</strong> (<em>list</em>) &#8211; List of strings, each being a line of Excellon code.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.Excellon.scale">
+<tt class="descname">scale</tt><big>(</big><em>factor</em><big>)</big><a class="headerlink" href="#camlib.Excellon.scale" title="Permalink to this definition">¶</a></dt>
+<dd><p>Scales geometry on the XY plane in the object by a given factor.
+Tool sizes, feedrates an Z-plane dimensions are untouched.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>factor</strong> (<em>float</em>) &#8211; Number by which to scale the object.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">NOne</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="camlib.CNCjob">
+<em class="property">class </em><tt class="descclassname">camlib.</tt><tt class="descname">CNCjob</tt><big>(</big><em>units='in'</em>, <em>kind='generic'</em>, <em>z_move=0.1</em>, <em>feedrate=3.0</em>, <em>z_cut=-0.002</em>, <em>tooldia=0.0</em><big>)</big><a class="headerlink" href="#camlib.CNCjob" title="Permalink to this definition">¶</a></dt>
+<dd><p>Represents work to be done by a CNC machine.</p>
+<p><em>ATTRIBUTES</em></p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">gcode_parsed</span></tt> (list): Each is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="34%" />
+<col width="66%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>geom</td>
+<td>(Shapely.LineString) Tool path (XY plane)</td>
+</tr>
+<tr class="row-odd"><td>kind</td>
+<td>(string) &#8220;AB&#8221;, A is &#8220;T&#8221; (travel) or
+&#8220;C&#8221; (cut). B is &#8220;F&#8221; (fast) or &#8220;S&#8221; (slow).</td>
+</tr>
+</tbody>
+</table>
+<dl class="method">
+<dt id="camlib.CNCjob.gcode_parse">
+<tt class="descname">gcode_parse</tt><big>(</big><big>)</big><a class="headerlink" href="#camlib.CNCjob.gcode_parse" title="Permalink to this definition">¶</a></dt>
+<dd><p>G-Code parser (from self.gcode). Generates dictionary with
+single-segment LineString&#8217;s and &#8220;kind&#8221; indicating cut or travel,
+fast or feedrate speed.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.CNCjob.generate_from_excellon">
+<tt class="descname">generate_from_excellon</tt><big>(</big><em>exobj</em><big>)</big><a class="headerlink" href="#camlib.CNCjob.generate_from_excellon" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generates G-code for drilling from Excellon object.
+self.gcode becomes a list, each element is a
+different job for each tool in the excellon code.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.CNCjob.generate_from_excellon_by_tool">
+<tt class="descname">generate_from_excellon_by_tool</tt><big>(</big><em>exobj</em>, <em>tools='all'</em><big>)</big><a class="headerlink" href="#camlib.CNCjob.generate_from_excellon_by_tool" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates gcode for this object from an Excellon object
+for the specified tools.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>exobj</strong> (<em>Excellon</em>) &#8211; Excellon object to process</li>
+<li><strong>tools</strong> &#8211; Comma separated tool names</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Type:</th><td class="field-body"><p class="first">tools: str</p>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">None</p>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">None</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.CNCjob.generate_from_geometry">
+<tt class="descname">generate_from_geometry</tt><big>(</big><em>geometry</em>, <em>append=True</em>, <em>tooldia=None</em>, <em>tolerance=0</em><big>)</big><a class="headerlink" href="#camlib.CNCjob.generate_from_geometry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generates G-Code from a Geometry object. Stores in <tt class="docutils literal"><span class="pre">self.gcode</span></tt>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>geometry</strong> (<em>Geometry</em>) &#8211; Geometry defining the toolpath</li>
+<li><strong>append</strong> (<em>bool</em>) &#8211; Wether to append to self.gcode or re-write it.</li>
+<li><strong>tooldia</strong> (<em>bool</em>) &#8211; If given, sets the tooldia property but does
+not affect the process in any other way.</li>
+<li><strong>tolerance</strong> &#8211; All points in the simplified object will be within the
+tolerance distance of the original geometry.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">None</p>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">None</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.CNCjob.linear2gcode">
+<tt class="descname">linear2gcode</tt><big>(</big><em>linear</em>, <em>tolerance=0</em><big>)</big><a class="headerlink" href="#camlib.CNCjob.linear2gcode" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generates G-code to cut along the linear feature.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>linear</strong> &#8211; The path to cut along.</li>
+<li><strong>tolerance</strong> (<em>float</em>) &#8211; All points in the simplified object will be within the
+tolerance distance of the original geometry.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Type:</th><td class="field-body"><p class="first">Shapely.LinearRing or Shapely.Linear String</p>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">G-code to cut alon the linear feature.</p>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">str</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.CNCjob.offset">
+<tt class="descname">offset</tt><big>(</big><em>vect</em><big>)</big><a class="headerlink" href="#camlib.CNCjob.offset" title="Permalink to this definition">¶</a></dt>
+<dd><p>Offsets all the geometry on the XY plane in the object by the
+given vector.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>vect</strong> (<em>tuple</em>) &#8211; (x, y) offset vector.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.CNCjob.plot2">
+<tt class="descname">plot2</tt><big>(</big><em>axes, tooldia=None, dpi=75, margin=0.1, color={'C': ['#5E6CFF', '#4650BD'], 'T': ['#F0E24D', '#B5AB3A']}, alpha={'C': 1.0, 'T': 0.3}, tool_tolerance=0.0005</em><big>)</big><a class="headerlink" href="#camlib.CNCjob.plot2" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plots the G-code job onto the given axes.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>axes</strong> &#8211; Matplotlib axes on which to plot.</li>
+<li><strong>tooldia</strong> &#8211; Tool diameter.</li>
+<li><strong>dpi</strong> &#8211; Not used!</li>
+<li><strong>margin</strong> &#8211; Not used!</li>
+<li><strong>color</strong> &#8211; Color specification.</li>
+<li><strong>alpha</strong> &#8211; Transparency specification.</li>
+<li><strong>tool_tolerance</strong> &#8211; Tolerance when drawing the toolshape.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">None</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.CNCjob.polygon2gcode">
+<tt class="descname">polygon2gcode</tt><big>(</big><em>polygon</em>, <em>tolerance=0</em><big>)</big><a class="headerlink" href="#camlib.CNCjob.polygon2gcode" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates G-Code for the exterior and all interior paths
+of a polygon.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>polygon</strong> (<em>Shapely.Polygon</em>) &#8211; A Shapely.Polygon</li>
+<li><strong>tolerance</strong> (<em>float</em>) &#8211; All points in the simplified object will be within the
+tolerance distance of the original geometry.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">G-code to cut along polygon.</p>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">str</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.CNCjob.pre_parse">
+<tt class="descname">pre_parse</tt><big>(</big><em>gtext</em><big>)</big><a class="headerlink" href="#camlib.CNCjob.pre_parse" title="Permalink to this definition">¶</a></dt>
+<dd><p>Separates parts of the G-Code text into a list of dictionaries.
+Used by <tt class="docutils literal"><span class="pre">self.gcode_parse()</span></tt>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>gtext</strong> &#8211; A single string with g-code</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="camlib.CNCjob.scale">
+<tt class="descname">scale</tt><big>(</big><em>factor</em><big>)</big><a class="headerlink" href="#camlib.CNCjob.scale" title="Permalink to this definition">¶</a></dt>
+<dd><p>Scales all the geometry on the XY plane in the object by the
+given factor. Tool sizes, feedrates, or Z-axis dimensions are
+not altered.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>factor</strong> (<em>float</em>) &#8211; Number by which to scale the object.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">None</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
 </div>
 
 
           </div>
           <footer>
   
+    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
+      
+        <a href="flatcamobj.html" class="btn btn-neutral float-right" title="FlatCAM Objects"/>Next <span class="icon icon-circle-arrow-right"></span></a>
+      
+      
+        <a href="index.html" class="btn btn-neutral" title="Welcome to FlatCAM’s documentation!"><span class="icon icon-circle-arrow-left"></span> Previous</a>
+      
+    </div>
+  
 
   <hr/>
 

+ 181 - 147
doc/build/genindex.html

@@ -79,7 +79,10 @@
       <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
         
         
-            <ul class="simple">
+            <ul>
+<li class="toctree-l1"><a class="reference internal" href="camlib.html">Camlib</a></li>
+<li class="toctree-l1"><a class="reference internal" href="flatcamobj.html">FlatCAM Objects</a></li>
+<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a></li>
 </ul>
 
         
@@ -125,6 +128,7 @@
  | <a href="#G"><strong>G</strong></a>
  | <a href="#I"><strong>I</strong></a>
  | <a href="#L"><strong>L</strong></a>
+ | <a href="#M"><strong>M</strong></a>
  | <a href="#N"><strong>N</strong></a>
  | <a href="#O"><strong>O</strong></a>
  | <a href="#P"><strong>P</strong></a>
@@ -139,17 +143,21 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.adjust_axes">adjust_axes() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.PlotCanvas.adjust_axes">adjust_axes() (FlatCAM.PlotCanvas method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Gerber.aperture_parse">aperture_parse() (FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.aperture_parse">aperture_parse() (camlib.Gerber method)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App">App (class in FlatCAM)</a>
+  <dt><a href="app.html#FlatCAM.App">App (class in FlatCAM)</a>
+  </dt>
+
+      
+  <dt><a href="app.html#FlatCAM.PlotCanvas.auto_adjust_axes">auto_adjust_axes() (FlatCAM.PlotCanvas method)</a>
   </dt>
 
   </dl></td>
@@ -159,21 +167,21 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.Geometry.bounds">bounds() (FlatCAM.Geometry method)</a>
+  <dt><a href="camlib.html#camlib.Geometry.bounds">bounds() (camlib.Geometry method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Gerber.buffer_paths">buffer_paths() (FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.buffer_paths">buffer_paths() (camlib.Gerber method)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.build_list">build_list() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.build_list">build_list() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.build_ui">build_ui() (FlatCAM.FlatCAMObj method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.build_ui">build_ui() (FlatCAM.FlatCAMObj method)</a>
   </dt>
 
   </dl></td>
@@ -183,31 +191,39 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.clear_plots">clear_plots() (FlatCAM.App method)</a>
+  <dt><a href="camlib.html#module-camlib">camlib (module)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Geometry.clear_polygon">clear_polygon() (FlatCAM.Geometry method)</a>
+  <dt><a href="app.html#FlatCAM.PlotCanvas.clear">clear() (FlatCAM.PlotCanvas method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.CNCjob">CNCjob (class in FlatCAM)</a>
+  <dt><a href="camlib.html#camlib.Geometry.clear_polygon">clear_polygon() (camlib.Geometry method)</a>
+  </dt>
+
+      
+  <dt><a href="camlib.html#camlib.CNCjob">CNCjob (class in camlib)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.FlatCAMGerber.convert_units">convert_units() (FlatCAM.FlatCAMGerber method)</a>
+  <dt><a href="app.html#FlatCAM.PlotCanvas.connect">connect() (FlatCAM.PlotCanvas method)</a>
+  </dt>
+
+      
+  <dt><a href="camlib.html#camlib.Geometry.convert_units">convert_units() (camlib.Geometry method)</a>
   </dt>
 
       <dd><dl>
         
-  <dt><a href="index.html#FlatCAM.Geometry.convert_units">(FlatCAM.Geometry method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMGerber.convert_units">(FlatCAM.FlatCAMGerber method)</a>
   </dt>
 
       </dl></dd>
       
-  <dt><a href="index.html#FlatCAM.Gerber.create_geometry">create_geometry() (FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.create_geometry">create_geometry() (camlib.Gerber method)</a>
   </dt>
 
   </dl></td>
@@ -217,13 +233,13 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.deserialize">deserialize() (FlatCAM.FlatCAMObj method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.deserialize">deserialize() (FlatCAM.FlatCAMObj method)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.Gerber.do_flashes">do_flashes() (FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.do_flashes">do_flashes() (camlib.Gerber method)</a>
   </dt>
 
   </dl></td>
@@ -233,7 +249,7 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.Excellon">Excellon (class in FlatCAM)</a>
+  <dt><a href="camlib.html#camlib.Excellon">Excellon (class in camlib)</a>
   </dt>
 
   </dl></td>
@@ -243,49 +259,49 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.file_chooser_action">file_chooser_action() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.file_chooser_action">file_chooser_action() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.file_chooser_save_action">file_chooser_save_action() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.file_chooser_save_action">file_chooser_save_action() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Gerber.fix_regions">fix_regions() (FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.fix_regions">fix_regions() (camlib.Gerber method)</a>
   </dt>
 
       
-  <dt><a href="index.html#module-FlatCAM">FlatCAM (module)</a>
+  <dt><a href="app.html#module-FlatCAM">FlatCAM (module)</a>, <a href="flatcamobj.html#module-FlatCAM">[1]</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.FlatCAMCNCjob">FlatCAMCNCjob (class in FlatCAM)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMCNCjob">FlatCAMCNCjob (class in FlatCAM)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.FlatCAMExcellon">FlatCAMExcellon (class in FlatCAM)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMExcellon">FlatCAMExcellon (class in FlatCAM)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.FlatCAMGeometry">FlatCAMGeometry (class in FlatCAM)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMGeometry">FlatCAMGeometry (class in FlatCAM)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.FlatCAMGerber">FlatCAMGerber (class in FlatCAM)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMGerber">FlatCAMGerber (class in FlatCAM)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.FlatCAMObj">FlatCAMObj (class in FlatCAM)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj">FlatCAMObj (class in FlatCAM)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Gerber.frac_digits">frac_digits (FlatCAM.Gerber attribute)</a>
+  <dt><a href="camlib.html#camlib.Gerber.frac_digits">frac_digits (camlib.Gerber attribute)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Geometry.from_dict">from_dict() (FlatCAM.Geometry method)</a>
+  <dt><a href="camlib.html#camlib.Geometry.from_dict">from_dict() (camlib.Geometry method)</a>
   </dt>
 
   </dl></td>
@@ -295,49 +311,49 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.CNCjob.gcode_parse">gcode_parse() (FlatCAM.CNCjob method)</a>
+  <dt><a href="camlib.html#camlib.CNCjob.gcode_parse">gcode_parse() (camlib.CNCjob method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.CNCjob.generate_from_excellon">generate_from_excellon() (FlatCAM.CNCjob method)</a>
+  <dt><a href="camlib.html#camlib.CNCjob.generate_from_excellon">generate_from_excellon() (camlib.CNCjob method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.CNCjob.generate_from_excellon_by_tool">generate_from_excellon_by_tool() (FlatCAM.CNCjob method)</a>
+  <dt><a href="camlib.html#camlib.CNCjob.generate_from_excellon_by_tool">generate_from_excellon_by_tool() (camlib.CNCjob method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.CNCjob.generate_from_geometry">generate_from_geometry() (FlatCAM.CNCjob method)</a>
+  <dt><a href="camlib.html#camlib.CNCjob.generate_from_geometry">generate_from_geometry() (camlib.CNCjob method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Geometry">Geometry (class in FlatCAM)</a>
+  <dt><a href="camlib.html#camlib.Geometry">Geometry (class in camlib)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Gerber">Gerber (class in FlatCAM)</a>
+  <dt><a href="camlib.html#camlib.Gerber">Gerber (class in camlib)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.Gerber.get_bounding_box">get_bounding_box() (FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.get_bounding_box">get_bounding_box() (camlib.Gerber method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.get_current">get_current() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.get_current">get_current() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Geometry.get_empty_area">get_empty_area() (FlatCAM.Geometry method)</a>
+  <dt><a href="camlib.html#camlib.Geometry.get_empty_area">get_empty_area() (camlib.Geometry method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.get_eval">get_eval() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.get_eval">get_eval() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.get_radio_value">get_radio_value() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.get_radio_value">get_radio_value() (FlatCAM.App method)</a>
   </dt>
 
   </dl></td>
@@ -347,17 +363,17 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.info">info() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.info">info() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Gerber.int_digits">int_digits (FlatCAM.Gerber attribute)</a>
+  <dt><a href="camlib.html#camlib.Gerber.int_digits">int_digits (camlib.Gerber attribute)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.Geometry.isolation_geometry">isolation_geometry() (FlatCAM.Geometry method)</a>
+  <dt><a href="camlib.html#camlib.Geometry.isolation_geometry">isolation_geometry() (camlib.Geometry method)</a>
   </dt>
 
   </dl></td>
@@ -367,13 +383,23 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.CNCjob.linear2gcode">linear2gcode() (FlatCAM.CNCjob method)</a>
+  <dt><a href="camlib.html#camlib.CNCjob.linear2gcode">linear2gcode() (camlib.CNCjob method)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.load_defaults">load_defaults() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.load_defaults">load_defaults() (FlatCAM.App method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="M">M</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="app.html#FlatCAM.PlotCanvas.mpl_connect">mpl_connect() (FlatCAM.PlotCanvas method)</a>
   </dt>
 
   </dl></td>
@@ -383,7 +409,13 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.new_object">new_object() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.PlotCanvas.new_axes">new_axes() (FlatCAM.PlotCanvas method)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="app.html#FlatCAM.App.new_object">new_object() (FlatCAM.App method)</a>
   </dt>
 
   </dl></td>
@@ -393,247 +425,255 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.CNCjob.offset">offset() (FlatCAM.CNCjob method)</a>
+  <dt><a href="camlib.html#camlib.CNCjob.offset">offset() (camlib.CNCjob method)</a>
   </dt>
 
       <dd><dl>
         
-  <dt><a href="index.html#FlatCAM.Excellon.offset">(FlatCAM.Excellon method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMGeometry.offset">(FlatCAM.FlatCAMGeometry method)</a>
   </dt>
 
         
-  <dt><a href="index.html#FlatCAM.FlatCAMGeometry.offset">(FlatCAM.FlatCAMGeometry method)</a>
+  <dt><a href="camlib.html#camlib.Excellon.offset">(camlib.Excellon method)</a>
   </dt>
 
         
-  <dt><a href="index.html#FlatCAM.Geometry.offset">(FlatCAM.Geometry method)</a>
+  <dt><a href="camlib.html#camlib.Geometry.offset">(camlib.Geometry method)</a>
   </dt>
 
         
-  <dt><a href="index.html#FlatCAM.Gerber.offset">(FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.offset">(camlib.Gerber method)</a>
   </dt>
 
       </dl></dd>
       
-  <dt><a href="index.html#FlatCAM.App.on_about">on_about() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_about">on_about() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_activate_name">on_activate_name() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_activate_name">on_activate_name() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_canvas_configure">on_canvas_configure() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_canvas_configure">on_canvas_configure() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_cb_plot_toggled">on_cb_plot_toggled() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_cb_plot_toggled">on_cb_plot_toggled() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_clear_plots">on_clear_plots() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_clear_plots">on_clear_plots() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_click_over_plot">on_click_over_plot() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_click_over_plot">on_click_over_plot() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_closewindow">on_closewindow() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_closewindow">on_closewindow() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_cncjob_exportgcode">on_cncjob_exportgcode() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_cncjob_exportgcode">on_cncjob_exportgcode() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_create_aligndrill">on_create_aligndrill() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_create_aligndrill">on_create_aligndrill() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_create_mirror">on_create_mirror() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_create_mirror">on_create_mirror() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_delete">on_delete() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_delete">on_delete() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_entry_eval_activate">on_entry_eval_activate() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_entry_eval_activate">on_entry_eval_activate() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_eval_update">on_eval_update() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_eval_update">on_eval_update() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_excellon_tool_choose">on_excellon_tool_choose() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_excellon_tool_choose">on_excellon_tool_choose() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_file_new">on_file_new() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_file_new">on_file_new() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_file_openproject">on_file_openproject() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_file_openproject">on_file_openproject() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_file_savedefaults">on_file_savedefaults() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_file_savedefaults">on_file_savedefaults() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_file_saveproject">on_file_saveproject() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_file_saveproject">on_file_saveproject() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_file_saveprojectas">on_file_saveprojectas() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_file_saveprojectas">on_file_saveprojectas() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_file_saveprojectcopy">on_file_saveprojectcopy() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_file_saveprojectcopy">on_file_saveprojectcopy() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_fileopenexcellon">on_fileopenexcellon() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_fileopenexcellon">on_fileopenexcellon() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_fileopengcode">on_fileopengcode() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_fileopengcode">on_fileopengcode() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_fileopengerber">on_fileopengerber() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_fileopengerber">on_fileopengerber() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_filequit">on_filequit() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_filequit">on_filequit() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_generate_cncjob">on_generate_cncjob() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_generate_cncjob">on_generate_cncjob() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_generate_excellon_cncjob">on_generate_excellon_cncjob() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_generate_excellon_cncjob">on_generate_excellon_cncjob() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_generate_gerber_bounding_box">on_generate_gerber_bounding_box() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_generate_gerber_bounding_box">on_generate_gerber_bounding_box() (FlatCAM.App method)</a>
+  </dt>
+
+      
+  <dt><a href="app.html#FlatCAM.App.on_generate_isolation">on_generate_isolation() (FlatCAM.App method)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.on_generate_isolation">on_generate_isolation() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_generate_paintarea">on_generate_paintarea() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_generate_paintarea">on_generate_paintarea() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_gerber_generate_cutout">on_gerber_generate_cutout() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_gerber_generate_cutout">on_gerber_generate_cutout() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_gerber_generate_noncopper">on_gerber_generate_noncopper() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_gerber_generate_noncopper">on_gerber_generate_noncopper() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_key_over_plot">on_key_over_plot() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_key_over_plot">on_key_over_plot() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.PlotCanvas.on_mouse_move">on_mouse_move() (FlatCAM.PlotCanvas method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_mouse_move_over_plot">on_mouse_move_over_plot() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_mouse_move_over_plot">on_mouse_move_over_plot() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_offset_object">on_offset_object() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_offset_object">on_offset_object() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_options_app2object">on_options_app2object() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_options_app2object">on_options_app2object() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_options_app2project">on_options_app2project() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_options_app2project">on_options_app2project() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_options_combo_change">on_options_combo_change() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_options_combo_change">on_options_combo_change() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_options_object2app">on_options_object2app() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_options_object2app">on_options_object2app() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_options_object2project">on_options_object2project() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_options_object2project">on_options_object2project() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_options_project2app">on_options_project2app() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_options_project2app">on_options_project2app() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_options_project2object">on_options_project2object() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_options_project2object">on_options_project2object() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_options_update">on_options_update() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_options_update">on_options_update() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_row_activated">on_row_activated() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_row_activated">on_row_activated() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_scale_object">on_scale_object() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_scale_object">on_scale_object() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_toggle_pointbox">on_toggle_pointbox() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.PlotCanvas.on_scroll">on_scroll() (FlatCAM.PlotCanvas method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_toggle_units">on_toggle_units() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_toggle_pointbox">on_toggle_pointbox() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_toolbar_replot">on_toolbar_replot() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_toggle_units">on_toggle_units() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_tools_doublesided">on_tools_doublesided() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_toolbar_replot">on_toolbar_replot() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_tree_selection_changed">on_tree_selection_changed() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_tools_doublesided">on_tools_doublesided() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_update_plot">on_update_plot() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_tree_selection_changed">on_tree_selection_changed() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_zoom_fit">on_zoom_fit() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_update_plot">on_update_plot() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_zoom_in">on_zoom_in() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_zoom_fit">on_zoom_fit() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.on_zoom_out">on_zoom_out() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_zoom_in">on_zoom_in() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.open_project">open_project() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.on_zoom_out">on_zoom_out() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.options2form">options2form() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.open_project">open_project() (FlatCAM.App method)</a>
+  </dt>
+
+      
+  <dt><a href="app.html#FlatCAM.App.options2form">options2form() (FlatCAM.App method)</a>
   </dt>
 
   </dl></td>
@@ -643,55 +683,53 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.Excellon.parse_file">parse_file() (FlatCAM.Excellon method)</a>
+  <dt><a href="camlib.html#camlib.Excellon.parse_file">parse_file() (camlib.Excellon method)</a>
   </dt>
 
       <dd><dl>
         
-  <dt><a href="index.html#FlatCAM.Gerber.parse_file">(FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.parse_file">(camlib.Gerber method)</a>
   </dt>
 
       </dl></dd>
       
-  <dt><a href="index.html#FlatCAM.Excellon.parse_lines">parse_lines() (FlatCAM.Excellon method)</a>
+  <dt><a href="camlib.html#camlib.Excellon.parse_lines">parse_lines() (camlib.Excellon method)</a>
   </dt>
 
       <dd><dl>
         
-  <dt><a href="index.html#FlatCAM.Gerber.parse_lines">(FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.parse_lines">(camlib.Gerber method)</a>
   </dt>
 
       </dl></dd>
       
-  <dt><a href="index.html#FlatCAM.FlatCAMGerber.plot">plot() (FlatCAM.FlatCAMGerber method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMGeometry.plot">plot() (FlatCAM.FlatCAMGeometry method)</a>
   </dt>
 
-      <dd><dl>
-        
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.plot">(FlatCAM.FlatCAMObj method)</a>
+      
+  <dt><a href="camlib.html#camlib.CNCjob.plot2">plot2() (camlib.CNCjob method)</a>
   </dt>
 
-      </dl></dd>
       
-  <dt><a href="index.html#FlatCAM.CNCjob.plot2">plot2() (FlatCAM.CNCjob method)</a>
+  <dt><a href="app.html#FlatCAM.App.plot_all">plot_all() (FlatCAM.App method)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.plot_all">plot_all() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.PlotCanvas">PlotCanvas (class in FlatCAM)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.CNCjob.polygon2gcode">polygon2gcode() (FlatCAM.CNCjob method)</a>
+  <dt><a href="camlib.html#camlib.CNCjob.polygon2gcode">polygon2gcode() (camlib.CNCjob method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.populate_objects_combo">populate_objects_combo() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.populate_objects_combo">populate_objects_combo() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.CNCjob.pre_parse">pre_parse() (FlatCAM.CNCjob method)</a>
+  <dt><a href="camlib.html#camlib.CNCjob.pre_parse">pre_parse() (camlib.CNCjob method)</a>
   </dt>
 
   </dl></td>
@@ -701,24 +739,24 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.read_form">read_form() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.read_form">read_form() (FlatCAM.App method)</a>
   </dt>
 
       <dd><dl>
         
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.read_form">(FlatCAM.FlatCAMObj method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.read_form">(FlatCAM.FlatCAMObj method)</a>
   </dt>
 
       </dl></dd>
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.read_form_item">read_form_item() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.read_form_item">read_form_item() (FlatCAM.App method)</a>
   </dt>
 
       <dd><dl>
         
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.read_form_item">(FlatCAM.FlatCAMObj method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.read_form_item">(FlatCAM.FlatCAMObj method)</a>
   </dt>
 
       </dl></dd>
@@ -729,77 +767,73 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.save_project">save_project() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.save_project">save_project() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.CNCjob.scale">scale() (FlatCAM.CNCjob method)</a>
+  <dt><a href="camlib.html#camlib.CNCjob.scale">scale() (camlib.CNCjob method)</a>
   </dt>
 
       <dd><dl>
         
-  <dt><a href="index.html#FlatCAM.Excellon.scale">(FlatCAM.Excellon method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMGeometry.scale">(FlatCAM.FlatCAMGeometry method)</a>
   </dt>
 
         
-  <dt><a href="index.html#FlatCAM.FlatCAMGeometry.scale">(FlatCAM.FlatCAMGeometry method)</a>
+  <dt><a href="camlib.html#camlib.Excellon.scale">(camlib.Excellon method)</a>
   </dt>
 
         
-  <dt><a href="index.html#FlatCAM.Geometry.scale">(FlatCAM.Geometry method)</a>
+  <dt><a href="camlib.html#camlib.Geometry.scale">(camlib.Geometry method)</a>
   </dt>
 
         
-  <dt><a href="index.html#FlatCAM.Gerber.scale">(FlatCAM.Gerber method)</a>
+  <dt><a href="camlib.html#camlib.Gerber.scale">(camlib.Gerber method)</a>
   </dt>
 
       </dl></dd>
       
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.serialize">serialize() (FlatCAM.FlatCAMObj method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.serialize">serialize() (FlatCAM.FlatCAMObj method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.set_form_item">set_form_item() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.set_form_item">set_form_item() (FlatCAM.App method)</a>
   </dt>
 
       <dd><dl>
         
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.set_form_item">(FlatCAM.FlatCAMObj method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.set_form_item">(FlatCAM.FlatCAMObj method)</a>
   </dt>
 
       </dl></dd>
       
-  <dt><a href="index.html#FlatCAM.App.set_list_selection">set_list_selection() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.set_list_selection">set_list_selection() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.set_progress_bar">set_progress_bar() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.set_progress_bar">set_progress_bar() (FlatCAM.App method)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.setup_axes">setup_axes() (FlatCAM.FlatCAMObj method)</a>
-  </dt>
-
-      
-  <dt><a href="index.html#FlatCAM.App.setup_component_editor">setup_component_editor() (FlatCAM.App method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.setup_axes">setup_axes() (FlatCAM.FlatCAMObj method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.setup_obj_classes">setup_obj_classes() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.setup_component_editor">setup_component_editor() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.setup_plot">setup_plot() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.setup_obj_classes">setup_obj_classes() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.App.setup_project_list">setup_project_list() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.setup_project_list">setup_project_list() (FlatCAM.App method)</a>
   </dt>
 
       
-  <dt><a href="index.html#FlatCAM.Geometry.size">size() (FlatCAM.Geometry method)</a>
+  <dt><a href="camlib.html#camlib.Geometry.size">size() (camlib.Geometry method)</a>
   </dt>
 
   </dl></td>
@@ -809,13 +843,13 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.Geometry.to_dict">to_dict() (FlatCAM.Geometry method)</a>
+  <dt><a href="camlib.html#camlib.Geometry.to_dict">to_dict() (camlib.Geometry method)</a>
   </dt>
 
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.to_form">to_form() (FlatCAM.FlatCAMObj method)</a>
+  <dt><a href="flatcamobj.html#FlatCAM.FlatCAMObj.to_form">to_form() (FlatCAM.FlatCAMObj method)</a>
   </dt>
 
   </dl></td>
@@ -825,7 +859,7 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.versionCheck">versionCheck() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.App.versionCheck">versionCheck() (FlatCAM.App method)</a>
   </dt>
 
   </dl></td>
@@ -835,7 +869,7 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
       
-  <dt><a href="index.html#FlatCAM.App.zoom">zoom() (FlatCAM.App method)</a>
+  <dt><a href="app.html#FlatCAM.PlotCanvas.zoom">zoom() (FlatCAM.PlotCanvas method)</a>
   </dt>
 
   </dl></td>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 10 - 2425
doc/build/index.html


BIN
doc/build/objects.inv


+ 14 - 2
doc/build/py-modindex.html

@@ -85,7 +85,10 @@
       <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
         
         
-            <ul class="simple">
+            <ul>
+<li class="toctree-l1"><a class="reference internal" href="camlib.html">Camlib</a></li>
+<li class="toctree-l1"><a class="reference internal" href="flatcamobj.html">FlatCAM Objects</a></li>
+<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a></li>
 </ul>
 
         
@@ -122,17 +125,26 @@
    <h1>Python Module Index</h1>
 
    <div class="modindex-jumpbox">
+   <a href="#cap-c"><strong>c</strong></a> | 
    <a href="#cap-f"><strong>f</strong></a>
    </div>
 
    <table class="indextable modindextable" cellspacing="0" cellpadding="2">
      <tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
+     <tr class="cap" id="cap-c"><td></td><td>
+       <strong>c</strong></td><td></td></tr>
+     <tr>
+       <td></td>
+       <td>
+       <a href="camlib.html#module-camlib"><tt class="xref">camlib</tt></a></td><td>
+       <em></em></td></tr>
+     <tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
      <tr class="cap" id="cap-f"><td></td><td>
        <strong>f</strong></td><td></td></tr>
      <tr>
        <td></td>
        <td>
-       <a href="index.html#module-FlatCAM"><tt class="xref">FlatCAM</tt></a></td><td>
+       <a href="flatcamobj.html#module-FlatCAM"><tt class="xref">FlatCAM</tt></a></td><td>
        <em></em></td></tr>
    </table>
 

+ 4 - 1
doc/build/search.html

@@ -86,7 +86,10 @@
       <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
         
         
-            <ul class="simple">
+            <ul>
+<li class="toctree-l1"><a class="reference internal" href="camlib.html">Camlib</a></li>
+<li class="toctree-l1"><a class="reference internal" href="flatcamobj.html">FlatCAM Objects</a></li>
+<li class="toctree-l1"><a class="reference internal" href="app.html">FlatCAM Application</a></li>
 </ul>
 
         

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
doc/build/searchindex.js


+ 10 - 0
doc/source/app.rst

@@ -0,0 +1,10 @@
+FlatCAM Application
+===================
+
+.. automodule:: FlatCAM
+
+.. autoclass:: App
+    :members:
+
+.. autoclass:: PlotCanvas
+    :members:

+ 16 - 0
doc/source/camlib.rst

@@ -0,0 +1,16 @@
+Camlib
+======
+
+.. automodule:: camlib
+
+.. autoclass:: Geometry
+    :members:
+
+.. autoclass:: Gerber(Geometry)
+    :members:
+
+.. autoclass:: Excellon
+    :members:
+
+.. autoclass:: CNCjob
+    :members:

+ 19 - 0
doc/source/flatcamobj.rst

@@ -0,0 +1,19 @@
+FlatCAM Objects
+===============
+
+.. automodule:: FlatCAM
+
+.. autoclass:: FlatCAMObj
+    :members:
+
+.. autoclass:: FlatCAMGerber
+    :members:
+
+.. autoclass:: FlatCAMExcellon
+    :members:
+
+.. autoclass:: FlatCAMCNCjob
+    :members:
+
+.. autoclass:: FlatCAMGeometry
+    :members:

+ 3 - 30
doc/source/index.rst

@@ -13,37 +13,10 @@ Contents:
 .. toctree::
    :maxdepth: 2
 
-.. automodule:: FlatCAM
+   camlib
+   flatcamobj
+   app
 
-.. autoclass:: App
-    :members:
-
-.. autoclass:: Geometry
-    :members:
-
-.. autoclass:: Gerber(Geometry)
-    :members:
-
-.. autoclass:: Excellon
-    :members:
-
-.. autoclass:: CNCjob
-    :members:
-
-.. autoclass:: FlatCAMObj
-    :members:
-
-.. autoclass:: FlatCAMGerber
-    :members:
-
-.. autoclass:: FlatCAMExcellon
-    :members:
-
-.. autoclass:: FlatCAMCNCjob
-    :members:
-
-.. autoclass:: FlatCAMGeometry
-    :members:
 
 
 Indices and tables

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác