Procházet zdrojové kódy

Offset feature. G-Code/CNC job processing fixes and optimization.

Juan Pablo Caram před 12 roky
rodič
revize
42f3652668
10 změnil soubory, kde provedl 783 přidání a 82 odebrání
  1. 51 5
      FlatCAM.py
  2. 314 0
      FlatCAM.ui
  3. 142 24
      camlib.py
  4. 1 1
      defaults.json
  5. binární
      doc/build/.doctrees/environment.pickle
  6. binární
      doc/build/.doctrees/index.doctree
  7. 43 13
      doc/build/genindex.html
  8. 232 39
      doc/build/index.html
  9. binární
      doc/build/objects.inv
  10. 0 0
      doc/build/searchindex.js

+ 51 - 5
FlatCAM.py

@@ -490,6 +490,15 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         self.ser_attrs += ['options', 'kind']
         self.ser_attrs += ['options', 'kind']
 
 
     def scale(self, factor):
     def scale(self, factor):
+        """
+        Scales all geometry by a given factor.
+
+        :param factor: Factor by which to scale the object's geometry/
+        :type factor: float
+        :return: None
+        :rtype: None
+        """
+
         if type(self.solid_geometry) == list:
         if type(self.solid_geometry) == list:
             self.solid_geometry = [affinity.scale(g, factor, factor, origin=(0, 0))
             self.solid_geometry = [affinity.scale(g, factor, factor, origin=(0, 0))
                                    for g in self.solid_geometry]
                                    for g in self.solid_geometry]
@@ -497,6 +506,24 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             self.solid_geometry = affinity.scale(self.solid_geometry, factor, factor,
             self.solid_geometry = affinity.scale(self.solid_geometry, factor, factor,
                                                  origin=(0, 0))
                                                  origin=(0, 0))
 
 
+    def offset(self, vect):
+        """
+        Offsets all geometry by a given vector/
+
+        :param vect: (x, y) vector by which to offset the object's geometry.
+        :type vect: tuple
+        :return: None
+        :rtype: None
+        """
+
+        dx, dy = vect
+
+        if type(self.solid_geometry) == list:
+            self.solid_geometry = [affinity.translate(g, xoff=dx, yoff=dy)
+                                   for g in self.solid_geometry]
+        else:
+            self.solid_geometry = affinity.translate(self.solid_geometry, xoff=dx, yoff=dy)
+
     def convert_units(self, units):
     def convert_units(self, units):
         factor = Geometry.convert_units(self, units)
         factor = Geometry.convert_units(self, units)
 
 
@@ -1037,7 +1064,11 @@ class App:
         m_y = 25  # pixels
         m_y = 25  # pixels
         width = xmax - xmin
         width = xmax - xmin
         height = ymax - ymin
         height = ymax - ymin
-        r = width / height
+        try:
+            r = width / height
+        except:
+            print "ERROR: Height is", height
+            return
         Fw, Fh = self.canvas.get_width_height()
         Fw, Fh = self.canvas.get_width_height()
         Fr = float(Fw) / Fh
         Fr = float(Fw) / Fh
         x_ratio = float(m_x) / Fw
         x_ratio = float(m_x) / Fw
@@ -1281,6 +1312,19 @@ class App:
     ########################################
     ########################################
     ##         EVENT HANDLERS             ##
     ##         EVENT HANDLERS             ##
     ########################################
     ########################################
+    def on_offset_object(self, widget):
+        obj = self.get_current()
+        assert isinstance(obj, FlatCAMObj)
+        try:
+            vect = self.get_eval("entry_eval_" + obj.kind + "_offset")
+        except:
+            self.info("ERROR: Vector is not in (x, y) format.")
+        assert isinstance(obj, Geometry)
+        obj.offset(vect)
+        obj.plot(self.figure)
+        self.on_zoom_fit(None)
+        return
+
     def on_cb_plot_toggled(self, widget):
     def on_cb_plot_toggled(self, widget):
         self.get_current().read_form()
         self.get_current().read_form()
         self.get_current().plot(self.figure)
         self.get_current().plot(self.figure)
@@ -1943,7 +1987,8 @@ class App:
 
 
         def geo_init(geo_obj, app_obj):
         def geo_init(geo_obj, app_obj):
             assert isinstance(geo_obj, FlatCAMGeometry)
             assert isinstance(geo_obj, FlatCAMGeometry)
-            gerber = app_obj.stuff[app_obj.selected_item_name]
+            #gerber = app_obj.stuff[app_obj.selected_item_name]  # TODO: Remove.
+            gerber = app_obj.get_current()
             assert isinstance(gerber, FlatCAMGerber)
             assert isinstance(gerber, FlatCAMGerber)
             gerber.read_form()
             gerber.read_form()
             bounding_box = gerber.solid_geometry.envelope.buffer(gerber.options["noncoppermargin"])
             bounding_box = gerber.solid_geometry.envelope.buffer(gerber.options["noncoppermargin"])
@@ -1967,7 +2012,8 @@ class App:
             # TODO: get from object
             # TODO: get from object
             margin = app_obj.get_eval("entry_eval_gerber_cutoutmargin")
             margin = app_obj.get_eval("entry_eval_gerber_cutoutmargin")
             gap_size = app_obj.get_eval("entry_eval_gerber_cutoutgapsize")
             gap_size = app_obj.get_eval("entry_eval_gerber_cutoutgapsize")
-            gerber = app_obj.stuff[app_obj.selected_item_name]
+            #gerber = app_obj.stuff[app_obj.selected_item_name]
+            gerber = app_obj.get_current()
             minx, miny, maxx, maxy = gerber.bounds()
             minx, miny, maxx, maxy = gerber.bounds()
             minx -= margin
             minx -= margin
             maxx += margin
             maxx += margin
@@ -2059,7 +2105,7 @@ class App:
 
 
             GLib.idle_add(lambda: app_obj.set_progress_bar(0.4, "Analyzing Geometry..."))
             GLib.idle_add(lambda: app_obj.set_progress_bar(0.4, "Analyzing Geometry..."))
             # TODO: The tolerance should not be hard coded. Just for testing.
             # TODO: The tolerance should not be hard coded. Just for testing.
-            job_obj.generate_from_geometry(geometry, tolerance=0.001)
+            job_obj.generate_from_geometry(geometry, tolerance=0.0005)
 
 
             GLib.idle_add(lambda: app_obj.set_progress_bar(0.5, "Parsing G-Code..."))
             GLib.idle_add(lambda: app_obj.set_progress_bar(0.5, "Parsing G-Code..."))
             job_obj.gcode_parse()
             job_obj.gcode_parse()
@@ -2129,7 +2175,7 @@ class App:
             f = open(filename, 'w')
             f = open(filename, 'w')
             f.write(cncjob.gcode)
             f.write(cncjob.gcode)
             f.close()
             f.close()
-            print "Saved to:", filename
+            self.info("Saved to: " + filename)
 
 
         self.file_chooser_save_action(on_success)
         self.file_chooser_save_action(on_success)
 
 

+ 314 - 0
FlatCAM.ui

@@ -744,6 +744,89 @@ THE SOFTWARE.</property>
                     <property name="position">12</property>
                     <property name="position">12</property>
                   </packing>
                   </packing>
                 </child>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label93">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="xalign">0</property>
+                    <property name="ypad">3</property>
+                    <property name="label" translatable="yes">Offset:</property>
+                    <attributes>
+                      <attribute name="weight" value="semibold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">13</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box26">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="margin_bottom">3</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label94">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Offset Vector: </property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_cncjob_offset">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">(0.0, 0.0)</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">14</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button21">
+                    <property name="label" translatable="yes">Offset</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <signal name="activate" handler="on_offset_object" swapped="no"/>
+                    <signal name="clicked" handler="on_offset_object" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">15</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
               </object>
               </object>
             </child>
             </child>
           </object>
           </object>
@@ -1165,6 +1248,83 @@ THE SOFTWARE.</property>
                     <property name="position">12</property>
                     <property name="position">12</property>
                   </packing>
                   </packing>
                 </child>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label91">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="xalign">0</property>
+                    <property name="ypad">3</property>
+                    <property name="label" translatable="yes">Offset:</property>
+                    <attributes>
+                      <attribute name="weight" value="semibold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">13</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box23">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="margin_bottom">3</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label92">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Offset Vector: </property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_excellon_offset">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">(0.0, 0.0)</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">14</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button20">
+                    <property name="label" translatable="yes">Offset</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <signal name="activate" handler="on_offset_object" swapped="no"/>
+                    <signal name="clicked" handler="on_offset_object" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">15</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
                 <child>
                 <child>
                   <placeholder/>
                   <placeholder/>
                 </child>
                 </child>
@@ -1701,6 +1861,80 @@ THE SOFTWARE.</property>
                     <property name="position">15</property>
                     <property name="position">15</property>
                   </packing>
                   </packing>
                 </child>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label95">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="xalign">0</property>
+                    <property name="ypad">3</property>
+                    <property name="label" translatable="yes">Offset:</property>
+                    <attributes>
+                      <attribute name="weight" value="semibold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">16</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box28">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="margin_bottom">3</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label96">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Offset Vector: </property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_geometry_offset">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">(0.0, 0.0)</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">17</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button22">
+                    <property name="label" translatable="yes">Offset</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <signal name="activate" handler="on_offset_object" swapped="no"/>
+                    <signal name="clicked" handler="on_offset_object" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">18</property>
+                  </packing>
+                </child>
                 <child>
                 <child>
                   <placeholder/>
                   <placeholder/>
                 </child>
                 </child>
@@ -2383,6 +2617,86 @@ THE SOFTWARE.</property>
                     <property name="position">23</property>
                     <property name="position">23</property>
                   </packing>
                   </packing>
                 </child>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label97">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="xalign">0</property>
+                    <property name="ypad">3</property>
+                    <property name="label" translatable="yes">Offset:</property>
+                    <attributes>
+                      <attribute name="weight" value="semibold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">24</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box29">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="margin_bottom">3</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label98">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Offset Vector: </property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_gerber_offset">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">(0.0, 0.0)</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">25</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button23">
+                    <property name="label" translatable="yes">Offset</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <signal name="activate" handler="on_offset_object" swapped="no"/>
+                    <signal name="clicked" handler="on_offset_object" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">26</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
                 <child>
                 <child>
                   <placeholder/>
                   <placeholder/>
                 </child>
                 </child>

+ 142 - 24
camlib.py

@@ -43,6 +43,11 @@ class Geometry:
         """
         """
         Creates contours around geometry at a given
         Creates contours around geometry at a given
         offset distance.
         offset distance.
+
+        :param offset: Offset distance.
+        :type offset: float
+        :return: The buffered geometry.
+        :rtype: Shapely.MultiPolygon or Shapely.Polygon
         """
         """
         return self.solid_geometry.buffer(offset)
         return self.solid_geometry.buffer(offset)
         
         
@@ -107,6 +112,16 @@ class Geometry:
         """
         """
         return
         return
 
 
+    def offset(self, vect):
+        """
+        Offset the geometry by the given vector. Override this method.
+
+        :param vect: (x, y) vector by which to offset the object.
+        :type vect: tuple
+        :return: None
+        """
+        return
+
     def convert_units(self, units):
     def convert_units(self, units):
         """
         """
         Converts the units of the object to ``units`` by scaling all
         Converts the units of the object to ``units`` by scaling all
@@ -379,16 +394,63 @@ class Gerber (Geometry):
         # Now buffered_paths, flash_geometry and solid_geometry
         # Now buffered_paths, flash_geometry and solid_geometry
         self.create_geometry()
         self.create_geometry()
 
 
+    def offset(self, vect):
+        """
+        Offsets the objects' geometry on the XY plane by a given vector.
+        These are:
+
+        * ``paths``
+        * ``regions``
+        * ``flashes``
+
+        Then ``buffered_paths``, ``flash_geometry`` and ``solid_geometry``
+        are re-created with ``self.create_geometry()``.
+        :param vect: (x, y) offset vector.
+        :type vect: tuple
+        :return: None
+        """
+
+        dx, dy = vect
+
+        # Paths
+        print "Shifting paths..."
+        for path in self.paths:
+            path['linestring'] = affinity.translate(path['linestring'],
+                                                    xoff=dx, yoff=dy)
+
+        # Flashes
+        print "Shifting flashes..."
+        for fl in self.flashes:
+            # TODO: Shouldn't 'loc' be a numpy.array()?
+            fl['loc'][0] += dx
+            fl['loc'][1] += dy
+
+        # Regions
+        print "Shifting regions..."
+        for reg in self.regions:
+            reg['polygon'] = affinity.translate(reg['polygon'],
+                                                xoff=dx, yoff=dy)
+
+        # Now buffered_paths, flash_geometry and solid_geometry
+        self.create_geometry()
+
     def fix_regions(self):
     def fix_regions(self):
         """
         """
         Overwrites the region polygons with fixed
         Overwrites the region polygons with fixed
         versions if found to be invalid (according to Shapely).
         versions if found to be invalid (according to Shapely).
         """
         """
+
         for region in self.regions:
         for region in self.regions:
             if not region['polygon'].is_valid:
             if not region['polygon'].is_valid:
                 region['polygon'] = region['polygon'].buffer(0)
                 region['polygon'] = region['polygon'].buffer(0)
     
     
     def buffer_paths(self):
     def buffer_paths(self):
+        """
+        This is part of the parsing process. "Thickens" the paths
+        by their appertures. This will only work for circular appertures.
+        :return: None
+        """
+
         self.buffered_paths = []
         self.buffered_paths = []
         for path in self.paths:
         for path in self.paths:
             width = self.apertures[path["aperture"]]["size"]
             width = self.apertures[path["aperture"]]["size"]
@@ -613,6 +675,7 @@ class Gerber (Geometry):
         """
         """
         Creates geometry for Gerber flashes (aperture on a single point).
         Creates geometry for Gerber flashes (aperture on a single point).
         """
         """
+
         self.flash_geometry = []
         self.flash_geometry = []
         for flash in self.flashes:
         for flash in self.flashes:
             aperture = self.apertures[flash['aperture']]
             aperture = self.apertures[flash['aperture']]
@@ -660,6 +723,7 @@ class Gerber (Geometry):
         :rtype : None
         :rtype : None
         :return: None
         :return: None
         """
         """
+
         # if len(self.buffered_paths) == 0:
         # if len(self.buffered_paths) == 0:
         #     self.buffer_paths()
         #     self.buffer_paths()
         print "... buffer_paths()"
         print "... buffer_paths()"
@@ -669,10 +733,9 @@ class Gerber (Geometry):
         print "... do_flashes()"
         print "... do_flashes()"
         self.do_flashes()
         self.do_flashes()
         print "... cascaded_union()"
         print "... cascaded_union()"
-        self.solid_geometry = cascaded_union(
-                                self.buffered_paths + 
-                                [poly['polygon'] for poly in self.regions] +
-                                self.flash_geometry)
+        self.solid_geometry = cascaded_union(self.buffered_paths +
+                                             [poly['polygon'] for poly in self.regions] +
+                                             self.flash_geometry)
 
 
     def get_bounding_box(self, margin=0.0, rounded=False):
     def get_bounding_box(self, margin=0.0, rounded=False):
         """
         """
@@ -688,6 +751,7 @@ class Gerber (Geometry):
         :return: The bounding box.
         :return: The bounding box.
         :rtype: Shapely.Polygon
         :rtype: Shapely.Polygon
         """
         """
+
         bbox = self.solid_geometry.envelope.buffer(margin)
         bbox = self.solid_geometry.envelope.buffer(margin)
         if not rounded:
         if not rounded:
             bbox = bbox.envelope
             bbox = bbox.envelope
@@ -710,12 +774,14 @@ class Excellon(Geometry):
     tool              (str) A key in ``tools``
     tool              (str) A key in ``tools``
     ================  ====================================
     ================  ====================================
     """
     """
+
     def __init__(self):
     def __init__(self):
         """
         """
         The constructor takes no parameters.
         The constructor takes no parameters.
         :return: Excellon object.
         :return: Excellon object.
         :rtype: Excellon
         :rtype: Excellon
         """
         """
+
         Geometry.__init__(self)
         Geometry.__init__(self)
         
         
         self.tools = {}
         self.tools = {}
@@ -820,6 +886,25 @@ class Excellon(Geometry):
         for drill in self.drills:
         for drill in self.drills:
             drill['point'] = affinity.scale(drill['point'], factor, factor, origin=(0, 0))
             drill['point'] = affinity.scale(drill['point'], factor, factor, origin=(0, 0))
 
 
+        self.create_geometry()
+
+    def offset(self, vect):
+        """
+        Offsets geometry on the XY plane in the object by a given vector.
+
+        :param vect: (x, y) offset vector.
+        :type vect: tuple
+        :return: None
+        """
+
+        dx, dy = vect
+
+        # Drills
+        for drill in self.drills:
+            drill['point'] = affinity.translate(drill['point'], xoff=dx, yoff=dy)
+
+        self.create_geometry()
+
     def convert_units(self, units):
     def convert_units(self, units):
         factor = Geometry.convert_units(self, units)
         factor = Geometry.convert_units(self, units)
 
 
@@ -1095,6 +1180,8 @@ class CNCjob(Geometry):
         fast or feedrate speed.
         fast or feedrate speed.
         """
         """
 
 
+        kind = ["C", "F"]  # T=travel, C=cut, F=fast, S=slow
+
         # Results go here
         # Results go here
         geometry = []        
         geometry = []        
         
         
@@ -1103,22 +1190,31 @@ class CNCjob(Geometry):
         
         
         # Last known instruction
         # Last known instruction
         current = {'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'G': 0}
         current = {'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'G': 0}
-        
+
+        # Current path: temporary storage until tool is
+        # lifted or lowered.
+        path = []
+
         # Process every instruction
         # Process every instruction
         for gobj in gobjs:
         for gobj in gobjs:
+
+            # Changing height:
             if 'Z' in gobj:
             if 'Z' in gobj:
                 if ('X' in gobj or 'Y' in gobj) and gobj['Z'] != current['Z']:
                 if ('X' in gobj or 'Y' in gobj) and gobj['Z'] != current['Z']:
                     print "WARNING: Non-orthogonal motion: From", current
                     print "WARNING: Non-orthogonal motion: From", current
                     print "         To:", gobj
                     print "         To:", gobj
                 current['Z'] = gobj['Z']
                 current['Z'] = gobj['Z']
-                
+                # Store the path into geometry and reset path
+                if len(path) > 1:
+                    geometry.append({"geom": LineString(path),
+                                     "kind": kind})
+                    path = [path[-1]]  # Start with the last point of last path.
+
+
             if 'G' in gobj:
             if 'G' in gobj:
                 current['G'] = int(gobj['G'])
                 current['G'] = int(gobj['G'])
                 
                 
             if 'X' in gobj or 'Y' in gobj:
             if 'X' in gobj or 'Y' in gobj:
-                x = 0
-                y = 0
-                kind = ["C", "F"]  # T=travel, C=cut, F=fast, S=slow
                 
                 
                 if 'X' in gobj:
                 if 'X' in gobj:
                     x = gobj['X']
                     x = gobj['X']
@@ -1129,7 +1225,9 @@ class CNCjob(Geometry):
                     y = gobj['Y']
                     y = gobj['Y']
                 else:
                 else:
                     y = current['Y']
                     y = current['Y']
-                
+
+                kind = ["C", "F"]  # T=travel, C=cut, F=fast, S=slow
+
                 if current['Z'] > 0:
                 if current['Z'] > 0:
                     kind[0] = 'T'
                     kind[0] = 'T'
                 if current['G'] > 0:
                 if current['G'] > 0:
@@ -1137,23 +1235,26 @@ class CNCjob(Geometry):
                    
                    
                 arcdir = [None, None, "cw", "ccw"]
                 arcdir = [None, None, "cw", "ccw"]
                 if current['G'] in [0, 1]:  # line
                 if current['G'] in [0, 1]:  # line
-                    geometry.append({'geom': LineString([(current['X'], current['Y']),
-                                                        (x, y)]), 'kind': kind})
+                    path.append((x, y))
+                    # geometry.append({'geom': LineString([(current['X'], current['Y']),
+                    #                                     (x, y)]), 'kind': kind})
                 if current['G'] in [2, 3]:  # arc
                 if current['G'] in [2, 3]:  # arc
                     center = [gobj['I'] + current['X'], gobj['J'] + current['Y']]
                     center = [gobj['I'] + current['X'], gobj['J'] + current['Y']]
                     radius = sqrt(gobj['I']**2 + gobj['J']**2)
                     radius = sqrt(gobj['I']**2 + gobj['J']**2)
                     start = arctan2(-gobj['J'], -gobj['I'])
                     start = arctan2(-gobj['J'], -gobj['I'])
                     stop = arctan2(-center[1]+y, -center[0]+x)
                     stop = arctan2(-center[1]+y, -center[0]+x)
-                    geometry.append({'geom': arc(center, radius, start, stop,
-                                                 arcdir[current['G']],
-                                                 self.steps_per_circ),
-                                     'kind': kind})
+                    path += arc(center, radius, start, stop,
+                                arcdir[current['G']],
+                                self.steps_per_circ)
+                    # geometry.append({'geom': arc(center, radius, start, stop,
+                    #                              arcdir[current['G']],
+                    #                              self.steps_per_circ),
+                    #                  'kind': kind})
 
 
             # Update current instruction
             # Update current instruction
             for code in gobj:
             for code in gobj:
                 current[code] = gobj[code]
                 current[code] = gobj[code]
-                
-        #self.G_geometry = geometry
+
         self.gcode_parsed = geometry
         self.gcode_parsed = geometry
         return geometry
         return geometry
         
         
@@ -1194,7 +1295,7 @@ class CNCjob(Geometry):
         
         
     def plot2(self, axes, tooldia=None, dpi=75, margin=0.1,
     def plot2(self, axes, tooldia=None, dpi=75, margin=0.1,
              color={"T": ["#F0E24D", "#B5AB3A"], "C": ["#5E6CFF", "#4650BD"]},
              color={"T": ["#F0E24D", "#B5AB3A"], "C": ["#5E6CFF", "#4650BD"]},
-             alpha={"T": 0.3, "C": 1.0}, tool_tolerance=0.001):
+             alpha={"T": 0.3, "C": 1.0}, tool_tolerance=0.0005):
         """
         """
         Plots the G-code job onto the given axes.
         Plots the G-code job onto the given axes.
 
 
@@ -1320,6 +1421,21 @@ class CNCjob(Geometry):
 
 
         self.create_geometry()
         self.create_geometry()
 
 
+    def offset(self, vect):
+        """
+        Offsets all the geometry on the XY plane in the object by the
+        given vector.
+
+        :param vect: (x, y) offset vector.
+        :type vect: tuple
+        :return: None
+        """
+        dx, dy = vect
+
+        for g in self.gcode_parsed:
+            g['geom'] = affinity.translate(g['geom'], xoff=dx, yoff=dy)
+
+        self.create_geometry()
 
 
 def get_bounds(geometry_set):
 def get_bounds(geometry_set):
     xmin = Inf
     xmin = Inf
@@ -1343,7 +1459,7 @@ def get_bounds(geometry_set):
 
 
 def arc(center, radius, start, stop, direction, steps_per_circ):
 def arc(center, radius, start, stop, direction, steps_per_circ):
     """
     """
-    Creates a Shapely.LineString for the specified arc.
+    Creates a list of point along the specified arc.
 
 
     :param center: Coordinates of the center [x, y]
     :param center: Coordinates of the center [x, y]
     :type center: list
     :type center: list
@@ -1358,9 +1474,11 @@ def arc(center, radius, start, stop, direction, steps_per_circ):
     :param steps_per_circ: Number of straight line segments to
     :param steps_per_circ: Number of straight line segments to
         represent a circle.
         represent a circle.
     :type steps_per_circ: int
     :type steps_per_circ: int
-    :return: The desired arc.
-    :rtype: Shapely.LineString
+    :return: The desired arc, as list of tuples
+    :rtype: list
     """
     """
+    # TODO: Resolution should be established by fraction of total length, not angle.
+
     da_sign = {"cw": -1.0, "ccw": 1.0}
     da_sign = {"cw": -1.0, "ccw": 1.0}
     points = []
     points = []
     if direction == "ccw" and stop <= start:
     if direction == "ccw" and stop <= start:
@@ -1375,8 +1493,8 @@ def arc(center, radius, start, stop, direction, steps_per_circ):
     delta_angle = da_sign[direction]*angle*1.0/steps
     delta_angle = da_sign[direction]*angle*1.0/steps
     for i in range(steps+1):
     for i in range(steps+1):
         theta = start + delta_angle*i
         theta = start + delta_angle*i
-        points.append([center[0]+radius*cos(theta), center[1]+radius*sin(theta)])
-    return LineString(points)
+        points.append((center[0]+radius*cos(theta), center[1]+radius*sin(theta)))
+    return points
 
 
 
 
 def clear_poly(poly, tooldia, overlap=0.1):
 def clear_poly(poly, tooldia, overlap=0.1):

+ 1 - 1
defaults.json

@@ -1 +1 @@
-{"geometry_paintoverlap": 0.15, "geometry_plot": true, "excellon_feedrate": 5.0, "gerber_plot": true, "gerber_mergepolys": true, "excellon_drillz": -0.1, "geometry_feedrate": 5.0, "units": "IN", "excellon_travelz": 0.1, "gerber_multicolored": false, "gerber_solid": true, "excellon_plot": true, "gerber_isotooldia": 0.016, "gerber_bboxmargin": 0.0, "cncjob_tooldia": 0.016, "geometry_travelz": 0.1, "gerber_cutoutmargin": 0.2, "excellon_solid": false, "geometry_paintmargin": 0.01, "geometry_cutz": -0.002, "geometry_cnctooldia": 0.016, "gerber_gaps": "4", "excellon_multicolored": false, "geometry_painttooldia": 0.0625, "cncjob_plot": true, "gerber_cutoutgapsize": 0.15, "gerber_bboxrounded": false, "geometry_multicolored": false, "gerber_noncoppermargin": 0.0, "geometry_solid": false}
+{"geometry_paintoverlap": 0.15, "geometry_plot": true, "gerber_isotooldia": 0.016, "gerber_plot": true, "gerber_mergepolys": true, "gerber_cutoutgapsize": 0.15, "geometry_feedrate": 3.0, "units": "IN", "excellon_travelz": 0.1, "gerber_multicolored": false, "gerber_solid": true, "excellon_plot": true, "excellon_feedrate": 5.0, "cncjob_tooldia": 0.016, "geometry_travelz": 0.1, "gerber_cutoutmargin": 0.2, "excellon_solid": false, "geometry_paintmargin": 0.01, "geometry_cutz": -0.002, "gerber_noncoppermargin": 0.0, "gerber_gaps": "4", "excellon_multicolored": false, "gerber_bboxmargin": 0.0, "cncjob_plot": true, "excellon_drillz": -0.1, "gerber_bboxrounded": false, "geometry_multicolored": false, "geometry_cnctooldia": 0.016, "geometry_solid": false, "geometry_painttooldia": 0.0625}

binární
doc/build/.doctrees/environment.pickle


binární
doc/build/.doctrees/index.doctree


+ 43 - 13
doc/build/genindex.html

@@ -162,12 +162,16 @@
   </dt>
   </dt>
 
 
       
       
-  <dt><a href="index.html#FlatCAM.App.build_list">build_list() (FlatCAM.App method)</a>
+  <dt><a href="index.html#FlatCAM.Gerber.buffer_paths">buffer_paths() (FlatCAM.Gerber method)</a>
   </dt>
   </dt>
 
 
   </dl></td>
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
   <td style="width: 33%" valign="top"><dl>
       
       
+  <dt><a href="index.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="index.html#FlatCAM.FlatCAMObj.build_ui">build_ui() (FlatCAM.FlatCAMObj method)</a>
   </dt>
   </dt>
 
 
@@ -215,10 +219,6 @@
   <dt><a href="index.html#FlatCAM.FlatCAMObj.deserialize">deserialize() (FlatCAM.FlatCAMObj method)</a>
   <dt><a href="index.html#FlatCAM.FlatCAMObj.deserialize">deserialize() (FlatCAM.FlatCAMObj method)</a>
   </dt>
   </dt>
 
 
-      
-  <dt><a href="index.html#FlatCAM.Gerber.digits">digits (FlatCAM.Gerber attribute)</a>
-  </dt>
-
   </dl></td>
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
   <td style="width: 33%" valign="top"><dl>
       
       
@@ -280,7 +280,7 @@
   </dt>
   </dt>
 
 
       
       
-  <dt><a href="index.html#FlatCAM.Gerber.fraction">fraction (FlatCAM.Gerber attribute)</a>
+  <dt><a href="index.html#FlatCAM.Gerber.frac_digits">frac_digits (FlatCAM.Gerber attribute)</a>
   </dt>
   </dt>
 
 
       
       
@@ -349,6 +349,10 @@
   <dt><a href="index.html#FlatCAM.App.info">info() (FlatCAM.App method)</a>
   <dt><a href="index.html#FlatCAM.App.info">info() (FlatCAM.App method)</a>
   </dt>
   </dt>
 
 
+      
+  <dt><a href="index.html#FlatCAM.Gerber.int_digits">int_digits (FlatCAM.Gerber attribute)</a>
+  </dt>
+
   </dl></td>
   </dl></td>
   <td style="width: 33%" valign="top"><dl>
   <td style="width: 33%" valign="top"><dl>
       
       
@@ -362,6 +366,12 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
   <td style="width: 33%" valign="top"><dl>
       
       
+  <dt><a href="index.html#FlatCAM.CNCjob.linear2gcode">linear2gcode() (FlatCAM.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="index.html#FlatCAM.App.load_defaults">load_defaults() (FlatCAM.App method)</a>
   </dt>
   </dt>
 
 
@@ -382,6 +392,20 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%" valign="top"><dl>
   <td style="width: 33%" valign="top"><dl>
       
       
+  <dt><a href="index.html#FlatCAM.Excellon.offset">offset() (FlatCAM.Excellon method)</a>
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="index.html#FlatCAM.Geometry.offset">(FlatCAM.Geometry method)</a>
+  </dt>
+
+        
+  <dt><a href="index.html#FlatCAM.Gerber.offset">(FlatCAM.Gerber method)</a>
+  </dt>
+
+      </dl></dd>
+      
   <dt><a href="index.html#FlatCAM.App.on_about">on_about() (FlatCAM.App method)</a>
   <dt><a href="index.html#FlatCAM.App.on_about">on_about() (FlatCAM.App method)</a>
   </dt>
   </dt>
 
 
@@ -485,12 +509,12 @@
   <dt><a href="index.html#FlatCAM.App.on_generate_gerber_bounding_box">on_generate_gerber_bounding_box() (FlatCAM.App method)</a>
   <dt><a href="index.html#FlatCAM.App.on_generate_gerber_bounding_box">on_generate_gerber_bounding_box() (FlatCAM.App method)</a>
   </dt>
   </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="index.html#FlatCAM.App.on_generate_isolation">on_generate_isolation() (FlatCAM.App method)</a>
   </dt>
   </dt>
 
 
-  </dl></td>
-  <td style="width: 33%" valign="top"><dl>
       
       
   <dt><a href="index.html#FlatCAM.App.on_generate_paintarea">on_generate_paintarea() (FlatCAM.App method)</a>
   <dt><a href="index.html#FlatCAM.App.on_generate_paintarea">on_generate_paintarea() (FlatCAM.App method)</a>
   </dt>
   </dt>
@@ -544,10 +568,6 @@
   </dt>
   </dt>
 
 
       
       
-  <dt><a href="index.html#FlatCAM.App.on_replot">on_replot() (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="index.html#FlatCAM.App.on_row_activated">on_row_activated() (FlatCAM.App method)</a>
   </dt>
   </dt>
 
 
@@ -564,6 +584,10 @@
   </dt>
   </dt>
 
 
       
       
+  <dt><a href="index.html#FlatCAM.App.on_toolbar_replot">on_toolbar_replot() (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="index.html#FlatCAM.App.on_tools_doublesided">on_tools_doublesided() (FlatCAM.App method)</a>
   </dt>
   </dt>
 
 
@@ -616,9 +640,15 @@
 
 
       </dl></dd>
       </dl></dd>
       
       
-  <dt><a href="index.html#FlatCAM.FlatCAMObj.plot">plot() (FlatCAM.FlatCAMObj method)</a>
+  <dt><a href="index.html#FlatCAM.FlatCAMGerber.plot">plot() (FlatCAM.FlatCAMGerber method)</a>
   </dt>
   </dt>
 
 
+      <dd><dl>
+        
+  <dt><a href="index.html#FlatCAM.FlatCAMObj.plot">(FlatCAM.FlatCAMObj method)</a>
+  </dt>
+
+      </dl></dd>
       
       
   <dt><a href="index.html#FlatCAM.CNCjob.plot2">plot2() (FlatCAM.CNCjob method)</a>
   <dt><a href="index.html#FlatCAM.CNCjob.plot2">plot2() (FlatCAM.CNCjob method)</a>
   </dt>
   </dt>

+ 232 - 39
doc/build/index.html

@@ -1047,22 +1047,6 @@ which may be necessary when updating the UI from code and not by the user.</p>
 </table>
 </table>
 </dd></dl>
 </dd></dl>
 
 
-<dl class="method">
-<dt id="FlatCAM.App.on_replot">
-<tt class="descname">on_replot</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#FlatCAM.App.on_replot" title="Permalink to this definition">¶</a></dt>
-<dd><p>Callback for toolbar button. Re-plots all 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>widget</strong> &#8211; The widget from which this was called.</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">
 <dl class="method">
 <dt id="FlatCAM.App.on_row_activated">
 <dt id="FlatCAM.App.on_row_activated">
 <tt class="descname">on_row_activated</tt><big>(</big><em>widget</em>, <em>path</em>, <em>col</em><big>)</big><a class="headerlink" href="#FlatCAM.App.on_row_activated" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">on_row_activated</tt><big>(</big><em>widget</em>, <em>path</em>, <em>col</em><big>)</big><a class="headerlink" href="#FlatCAM.App.on_row_activated" title="Permalink to this definition">¶</a></dt>
@@ -1140,6 +1124,22 @@ the objects in the project.</p>
 </table>
 </table>
 </dd></dl>
 </dd></dl>
 
 
+<dl class="method">
+<dt id="FlatCAM.App.on_toolbar_replot">
+<tt class="descname">on_toolbar_replot</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#FlatCAM.App.on_toolbar_replot" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for toolbar button. Re-plots all 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>widget</strong> &#8211; The widget from which this was called.</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">
 <dl class="method">
 <dt id="FlatCAM.App.on_tools_doublesided">
 <dt id="FlatCAM.App.on_tools_doublesided">
 <tt class="descname">on_tools_doublesided</tt><big>(</big><em>param</em><big>)</big><a class="headerlink" href="#FlatCAM.App.on_tools_doublesided" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">on_tools_doublesided</tt><big>(</big><em>param</em><big>)</big><a class="headerlink" href="#FlatCAM.App.on_tools_doublesided" title="Permalink to this definition">¶</a></dt>
@@ -1406,13 +1406,13 @@ in the GUI. This selection will in turn trigger
 <dl class="method">
 <dl class="method">
 <dt id="FlatCAM.App.set_progress_bar">
 <dt id="FlatCAM.App.set_progress_bar">
 <tt class="descname">set_progress_bar</tt><big>(</big><em>percentage</em>, <em>text=''</em><big>)</big><a class="headerlink" href="#FlatCAM.App.set_progress_bar" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">set_progress_bar</tt><big>(</big><em>percentage</em>, <em>text=''</em><big>)</big><a class="headerlink" href="#FlatCAM.App.set_progress_bar" title="Permalink to this definition">¶</a></dt>
-<dd><p>Sets the application&#8217;s progress bar to a given fraction and text.</p>
+<dd><p>Sets the application&#8217;s progress bar to a given frac_digits and text.</p>
 <table class="docutils field-list" frame="void" rules="none">
 <table class="docutils field-list" frame="void" rules="none">
 <col class="field-name" />
 <col class="field-name" />
 <col class="field-body" />
 <col class="field-body" />
 <tbody valign="top">
 <tbody valign="top">
 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
 <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
-<li><strong>percentage</strong> (<em>float</em>) &#8211; The fraction (0.0-1.0) of the progress.</li>
+<li><strong>percentage</strong> (<em>float</em>) &#8211; The frac_digits (0.0-1.0) of the progress.</li>
 <li><strong>text</strong> (<em>str</em>) &#8211; Text to display on the progress bar.</li>
 <li><strong>text</strong> (<em>str</em>) &#8211; Text to display on the progress bar.</li>
 </ul>
 </ul>
 </td>
 </td>
@@ -1569,6 +1569,34 @@ the rectangular bounding box of self.solid_geometry.</p>
 <tt class="descname">isolation_geometry</tt><big>(</big><em>offset</em><big>)</big><a class="headerlink" href="#FlatCAM.Geometry.isolation_geometry" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">isolation_geometry</tt><big>(</big><em>offset</em><big>)</big><a class="headerlink" href="#FlatCAM.Geometry.isolation_geometry" title="Permalink to this definition">¶</a></dt>
 <dd><p>Creates contours around geometry at a given
 <dd><p>Creates contours around geometry at a given
 offset distance.</p>
 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="FlatCAM.Geometry.offset">
+<tt class="descname">offset</tt><big>(</big><em>vect</em><big>)</big><a class="headerlink" href="#FlatCAM.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>
 </dd></dl>
 
 
 <dl class="method">
 <dl class="method">
@@ -1744,6 +1772,14 @@ The following kinds and their attributes are supported:</p>
 </table>
 </table>
 </dd></dl>
 </dd></dl>
 
 
+<dl class="method">
+<dt id="FlatCAM.Gerber.buffer_paths">
+<tt class="descname">buffer_paths</tt><big>(</big><big>)</big><a class="headerlink" href="#FlatCAM.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">
 <dl class="method">
 <dt id="FlatCAM.Gerber.create_geometry">
 <dt id="FlatCAM.Gerber.create_geometry">
 <tt class="descname">create_geometry</tt><big>(</big><big>)</big><a class="headerlink" href="#FlatCAM.Gerber.create_geometry" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">create_geometry</tt><big>(</big><big>)</big><a class="headerlink" href="#FlatCAM.Gerber.create_geometry" title="Permalink to this definition">¶</a></dt>
@@ -1755,12 +1791,6 @@ and regions naturally do as well.</p>
 :return: None</p>
 :return: None</p>
 </dd></dl>
 </dd></dl>
 
 
-<dl class="attribute">
-<dt id="FlatCAM.Gerber.digits">
-<tt class="descname">digits</tt><em class="property"> = None</em><a class="headerlink" href="#FlatCAM.Gerber.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">
 <dl class="method">
 <dt id="FlatCAM.Gerber.do_flashes">
 <dt id="FlatCAM.Gerber.do_flashes">
 <tt class="descname">do_flashes</tt><big>(</big><big>)</big><a class="headerlink" href="#FlatCAM.Gerber.do_flashes" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">do_flashes</tt><big>(</big><big>)</big><a class="headerlink" href="#FlatCAM.Gerber.do_flashes" title="Permalink to this definition">¶</a></dt>
@@ -1775,8 +1805,8 @@ versions if found to be invalid (according to Shapely).</p>
 </dd></dl>
 </dd></dl>
 
 
 <dl class="attribute">
 <dl class="attribute">
-<dt id="FlatCAM.Gerber.fraction">
-<tt class="descname">fraction</tt><em class="property"> = None</em><a class="headerlink" href="#FlatCAM.Gerber.fraction" title="Permalink to this definition">¶</a></dt>
+<dt id="FlatCAM.Gerber.frac_digits">
+<tt class="descname">frac_digits</tt><em class="property"> = None</em><a class="headerlink" href="#FlatCAM.Gerber.frac_digits" title="Permalink to this definition">¶</a></dt>
 <dd><p>Number of fraction digits in Gerber numbers. Used during parsing.</p>
 <dd><p>Number of fraction digits in Gerber numbers. Used during parsing.</p>
 </dd></dl>
 </dd></dl>
 
 
@@ -1807,6 +1837,29 @@ box in both positive and negative, x and y axes.</li>
 </table>
 </table>
 </dd></dl>
 </dd></dl>
 
 
+<dl class="attribute">
+<dt id="FlatCAM.Gerber.int_digits">
+<tt class="descname">int_digits</tt><em class="property"> = None</em><a class="headerlink" href="#FlatCAM.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="FlatCAM.Gerber.offset">
+<tt class="descname">offset</tt><big>(</big><em>vect</em><big>)</big><a class="headerlink" href="#FlatCAM.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">
 <dl class="method">
 <dt id="FlatCAM.Gerber.parse_file">
 <dt id="FlatCAM.Gerber.parse_file">
 <tt class="descname">parse_file</tt><big>(</big><em>filename</em><big>)</big><a class="headerlink" href="#FlatCAM.Gerber.parse_file" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">parse_file</tt><big>(</big><em>filename</em><big>)</big><a class="headerlink" href="#FlatCAM.Gerber.parse_file" title="Permalink to this definition">¶</a></dt>
@@ -1817,7 +1870,20 @@ read from the given file.</p>
 <dl class="method">
 <dl class="method">
 <dt id="FlatCAM.Gerber.parse_lines">
 <dt id="FlatCAM.Gerber.parse_lines">
 <tt class="descname">parse_lines</tt><big>(</big><em>glines</em><big>)</big><a class="headerlink" href="#FlatCAM.Gerber.parse_lines" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">parse_lines</tt><big>(</big><em>glines</em><big>)</big><a class="headerlink" href="#FlatCAM.Gerber.parse_lines" title="Permalink to this definition">¶</a></dt>
-<dd><p>Main Gerber parser.</p>
+<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> &#8211; Gerber code as list of strings, each</td>
+</tr>
+</tbody>
+</table>
+<p>element being one line of the source file.
+:type glines: list
+:return: None
+:rtype: None</p>
 </dd></dl>
 </dd></dl>
 
 
 <dl class="method">
 <dl class="method">
@@ -1868,6 +1934,22 @@ the size (diameter).</li>
 </tr>
 </tr>
 </tbody>
 </tbody>
 </table>
 </table>
+<dl class="method">
+<dt id="FlatCAM.Excellon.offset">
+<tt class="descname">offset</tt><big>(</big><em>vect</em><big>)</big><a class="headerlink" href="#FlatCAM.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">
 <dl class="method">
 <dt id="FlatCAM.Excellon.parse_lines">
 <dt id="FlatCAM.Excellon.parse_lines">
 <tt class="descname">parse_lines</tt><big>(</big><em>elines</em><big>)</big><a class="headerlink" href="#FlatCAM.Excellon.parse_lines" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">parse_lines</tt><big>(</big><em>elines</em><big>)</big><a class="headerlink" href="#FlatCAM.Excellon.parse_lines" title="Permalink to this definition">¶</a></dt>
@@ -1943,45 +2025,142 @@ different job for each tool in the excellon code.</p>
 <dt id="FlatCAM.CNCjob.generate_from_excellon_by_tool">
 <dt id="FlatCAM.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="#FlatCAM.CNCjob.generate_from_excellon_by_tool" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">generate_from_excellon_by_tool</tt><big>(</big><em>exobj</em>, <em>tools='all'</em><big>)</big><a class="headerlink" href="#FlatCAM.CNCjob.generate_from_excellon_by_tool" title="Permalink to this definition">¶</a></dt>
 <dd><p>Creates gcode for this object from an Excellon object
 <dd><p>Creates gcode for this object from an Excellon object
-for the specified tools.
-&#64;param exobj: Excellon object to process
-&#64;type exobj: Excellon
-&#64;param tools: Comma separated tool names
-&#64;type: tools: str
-&#64;return: None</p>
+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>
 </dd></dl>
 
 
 <dl class="method">
 <dl class="method">
 <dt id="FlatCAM.CNCjob.generate_from_geometry">
 <dt id="FlatCAM.CNCjob.generate_from_geometry">
-<tt class="descname">generate_from_geometry</tt><big>(</big><em>geometry</em>, <em>append=True</em>, <em>tooldia=None</em><big>)</big><a class="headerlink" href="#FlatCAM.CNCjob.generate_from_geometry" title="Permalink to this definition">¶</a></dt>
-<dd><p>Generates G-Code from a Geometry object.</p>
+<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="#FlatCAM.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 last 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> &#8211; If given, sets the tooldia property but does</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>not affect the process in any other way.
+:type tooldia: bool
+:param tolerance: All points in the simplified object will be within the
+tolerance distance of the original geometry.
+:return: None
+:rtype: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="FlatCAM.CNCjob.linear2gcode">
+<tt class="descname">linear2gcode</tt><big>(</big><em>linear</em>, <em>tolerance=0</em><big>)</big><a class="headerlink" href="#FlatCAM.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> &#8211; All points in the simplified object will be within the</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Type:</th><td class="field-body"><p class="first last">Shapely.LinearRing or Shapely.Linear String</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>tolerance distance of the original geometry.
+:type tolerance: float
+:return: G-code to cut alon the linear feature.
+:rtype: str</p>
 </dd></dl>
 </dd></dl>
 
 
 <dl class="method">
 <dl class="method">
 <dt id="FlatCAM.CNCjob.plot2">
 <dt id="FlatCAM.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}</em><big>)</big><a class="headerlink" href="#FlatCAM.CNCjob.plot2" title="Permalink to this definition">¶</a></dt>
+<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.001</em><big>)</big><a class="headerlink" href="#FlatCAM.CNCjob.plot2" title="Permalink to this definition">¶</a></dt>
 <dd><p>Plots the G-code job onto the given axes.</p>
 <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>
 </dd></dl>
 
 
 <dl class="method">
 <dl class="method">
 <dt id="FlatCAM.CNCjob.polygon2gcode">
 <dt id="FlatCAM.CNCjob.polygon2gcode">
-<tt class="descname">polygon2gcode</tt><big>(</big><em>polygon</em><big>)</big><a class="headerlink" href="#FlatCAM.CNCjob.polygon2gcode" title="Permalink to this definition">¶</a></dt>
+<tt class="descname">polygon2gcode</tt><big>(</big><em>polygon</em>, <em>tolerance=0</em><big>)</big><a class="headerlink" href="#FlatCAM.CNCjob.polygon2gcode" title="Permalink to this definition">¶</a></dt>
 <dd><p>Creates G-Code for the exterior and all interior paths
 <dd><p>Creates G-Code for the exterior and all interior paths
 of a polygon.</p>
 of a polygon.</p>
 <table class="docutils field-list" frame="void" rules="none">
 <table class="docutils field-list" frame="void" rules="none">
 <col class="field-name" />
 <col class="field-name" />
 <col class="field-body" />
 <col class="field-body" />
 <tbody valign="top">
 <tbody valign="top">
-<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>polygon</strong> (<em>Shapely.Polygon</em>) &#8211; A Shapely.Polygon</td>
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>polygon</strong> (<em>Shapely.Polygon</em>) &#8211; A Shapely.Polygon</li>
+<li><strong>tolerance</strong> &#8211; All points in the simplified object will be within the</li>
+</ul>
+</td>
 </tr>
 </tr>
 </tbody>
 </tbody>
 </table>
 </table>
+<p>tolerance distance of the original geometry.
+:type tolerance: float
+:return: G-code to cut along polygon.
+:rtype: str</p>
 </dd></dl>
 </dd></dl>
 
 
 <dl class="method">
 <dl class="method">
 <dt id="FlatCAM.CNCjob.pre_parse">
 <dt id="FlatCAM.CNCjob.pre_parse">
 <tt class="descname">pre_parse</tt><big>(</big><em>gtext</em><big>)</big><a class="headerlink" href="#FlatCAM.CNCjob.pre_parse" title="Permalink to this definition">¶</a></dt>
 <tt class="descname">pre_parse</tt><big>(</big><em>gtext</em><big>)</big><a class="headerlink" href="#FlatCAM.CNCjob.pre_parse" title="Permalink to this definition">¶</a></dt>
-<dd><p>gtext is a single string with g-code</p>
+<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>
 </dd></dl>
 
 
 <dl class="method">
 <dl class="method">
@@ -2144,6 +2323,20 @@ and options.</p>
 </table>
 </table>
 </dd></dl>
 </dd></dl>
 
 
+<dl class="method">
+<dt id="FlatCAM.FlatCAMGerber.plot">
+<tt class="descname">plot</tt><big>(</big><em>figure</em><big>)</big><a class="headerlink" href="#FlatCAM.FlatCAMGerber.plot" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plots the object on to the specified figure.</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>figure</strong> &#8211; Matplotlib figure on which to plot.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
 </dd></dl>
 </dd></dl>
 
 
 <dl class="class">
 <dl class="class">

binární
doc/build/objects.inv


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
doc/build/searchindex.js


Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů