Ver código fonte

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

Juan Pablo Caram 12 anos atrás
pai
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>

Diferenças do arquivo suprimidas por serem muito extensas
+ 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>
 
         

Diferenças do arquivo suprimidas por serem muito extensas
+ 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

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff