Kaynağa Gözat

Area clearing feature, pending minor fixes.

Juan Pablo Caram 12 yıl önce
ebeveyn
işleme
773bb13702
3 değiştirilmiş dosya ile 191 ekleme ve 3 silme
  1. 51 0
      camlib.py
  2. 35 3
      cirkuix.py
  3. 105 0
      cirkuix.ui

+ 51 - 0
camlib.py

@@ -665,6 +665,22 @@ def get_bounds(geometry_set):
 
 
 def arc(center, radius, start, stop, direction, steps_per_circ):
+    """
+    Creates a Shapely.LineString for the specified arc.
+    @param center: Coordinates of the center [x, y]
+    @type center: list
+    @param radius: Radius of the arc.
+    @type radius: float
+    @param start: Starting angle in radians
+    @type start: float
+    @param stop: End angle in radians
+    @type stop: float
+    @param direction: Orientation of the arc, "CW" or "CCW"
+    @type direction: string
+    @param steps_per_circ: Number of straight line segments to
+        represent a circle.
+    @type steps_per_circ: int
+    """
     da_sign = {"cw": -1.0, "ccw": 1.0}
     points = []
     if direction == "ccw" and stop <= start:
@@ -683,6 +699,41 @@ def arc(center, radius, start, stop, direction, steps_per_circ):
     return LineString(points)
 
 
+def clear_poly(poly, tooldia, overlap = 0.1):
+    """
+    Creates a list of Shapely geometry objects covering the inside
+    of a Shapely.Polygon. Use for removing all the copper in a region
+    or bed flattening.
+    @param poly: Target polygon
+    @type poly: Shapely.Polygon
+    @param tooldia: Diameter of the tool
+    @type tooldia: float
+    @param overlap: Fraction of the tool diameter to overlap
+        in each pass.
+    @type overlap: float
+    @return list of Shapely.Polygon
+    """
+    poly_cuts = [poly.buffer(-tooldia/2.0)]
+    while True:
+        poly = poly_cuts[-1].buffer(-tooldia*(1-overlap))
+        if poly.area > 0:
+            poly_cuts.append(poly)
+        else:
+            break
+    return poly_cuts
+
+
+def find_polygon(poly_set, point):
+    """
+    Return the first polygon in the list of polygons poly_set
+    that contains the given point.
+    """
+    p = Point(point)
+    for poly in poly_set:
+        if poly.contains(p):
+            return poly
+    return None
+
 ############### cam.py ####################
 def coord(gstr, digits, fraction):
     """

+ 35 - 3
cirkuix.py

@@ -278,7 +278,9 @@ class CirkuixGeometry(CirkuixObj, Geometry):
             "multicolored": False,
             "cutz": -0.002,
             "travelz": 0.1,
-            "feedrate": 5.0
+            "feedrate": 5.0,
+            "painttooldia": 0.0625,
+            "paintoverlap": 0.15
         })
 
         self.form_kinds.update({
@@ -287,7 +289,9 @@ class CirkuixGeometry(CirkuixObj, Geometry):
             "multicolored": "cb",
             "cutz": "entry_eval",
             "travelz": "entry_eval",
-            "feedrate": "entry_eval"
+            "feedrate": "entry_eval",
+            "painttooldia": "entry_eval",
+            "paintoverlap": "entry_eval"
         })
 
     def plot(self, figure):
@@ -366,6 +370,8 @@ class App:
         # a key if self.stuff
         self.selected_item_name = None
 
+        self.plot_click_subscribers = {}
+
         # For debugging only
         def someThreadFunc(self):
             print "Hello World!"
@@ -707,7 +713,6 @@ class App:
         # TODO: Do something if this is None. Offer changing name?
         self.new_object("geometry", iso_name, iso_init)
 
-        
     def on_generate_cncjob(self, widget):
         print "Generating CNC job"
 
@@ -731,6 +736,30 @@ class App:
 
         self.new_object("cncjob", job_name, job_init)
 
+    def on_generate_paintarea(self, widget):
+        self.info("Click inside the desired polygon.")
+        geo = self.stuff[self.selected_item_name]
+        geo.read_form()
+        tooldia = geo.options["painttooldia"]
+        overlap = geo.options["paintoverlap"]
+
+        def doit(event):
+            self.plot_click_subscribers.pop("generate_paintarea")
+            self.info("")
+            point = [event.xdata, event.ydata]
+            poly = find_polygon(geo.solid_geometry, point)
+
+            def gen_paintarea(geo_obj, app_obj):
+                assert isinstance(geo_obj, CirkuixGeometry)
+                assert isinstance(app_obj, App)
+                cp = clear_poly(poly, tooldia, overlap)
+                geo_obj.solid_geometry = cp
+
+            name = self.selected_item_name + "_paint"
+            self.new_object("geometry", name, gen_paintarea)
+
+        self.plot_click_subscribers["generate_paintarea"] = doit
+
     def on_cncjob_tooldia_activate(self, widget):
         job = self.stuff[self.selected_item_name]
         tooldia = self.get_eval("entry_eval_cncjob_tooldia")
@@ -947,6 +976,9 @@ class App:
         try:
             print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
             event.button, event.x, event.y, event.xdata, event.ydata)
+
+            for subscriber in self.plot_click_subscribers:
+                self.plot_click_subscribers[subscriber](event)
         except:
             print "Outside plot!"
         

+ 105 - 0
cirkuix.ui

@@ -661,6 +661,111 @@
                     <property name="position">8</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label6">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">5</property>
+                    <property name="xalign">0</property>
+                    <property name="ypad">3</property>
+                    <property name="label" translatable="yes">Paint Area:</property>
+                    <attributes>
+                      <attribute name="weight" value="semibold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">9</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkGrid" id="grid5">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="row_spacing">2</property>
+                    <property name="column_spacing">5</property>
+                    <child>
+                      <object class="GtkLabel" id="label32">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Tool diam:</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_geometry_painttooldia">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label33">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Overlap:</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_geometry_paintoverlap">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">10</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button6">
+                    <property name="label" translatable="yes">Generate</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <signal name="activate" handler="on_generate_paintarea" swapped="no"/>
+                    <signal name="clicked" handler="on_generate_paintarea" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">11</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
                 <child>
                   <placeholder/>
                 </child>