Explorar o código

- finished to add the Properties data to the Object Properties (former Selected Tab)

Marius Stanciu %!s(int64=5) %!d(string=hai) anos
pai
achega
af85764730

+ 4 - 0
CHANGELOG.md

@@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta
 
 =================================================
 
+20.10.2020
+
+- finished to add the Properties data to the Object Properties (former Selected Tab)
+
 19.10.2020
 
 - added a check (and added to Preferences too) for the verification of tools validity in the Isolation Tool

+ 104 - 16
appGUI/ObjectUI.py

@@ -251,10 +251,27 @@ class GerberObjectUI(ObjectUI):
                                       """)
         grid0.addWidget(self.editor_button, 4, 0, 1, 3)
 
-        separator_line = QtWidgets.QFrame()
-        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
-        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
-        grid0.addWidget(separator_line, 6, 0, 1, 3)
+        # PROPERTIES CB
+        self.properties_lbl = FCLabel('<b>%s</b>:' % _("PROPERTIES"))
+        self.properties_lbl.setToolTip(_("Show the Properties."))
+        self.properties_cb = FCCheckBox()
+
+        grid0.addWidget(self.properties_lbl, 6, 0)
+        grid0.addWidget(self.properties_cb, 6, 1, 1, 2)
+
+        # PROPERTIES Frame
+        self.properties_frame = QtWidgets.QFrame()
+        self.properties_frame.setContentsMargins(0, 0, 0, 0)
+        grid0.addWidget(self.properties_frame, 7, 0, 1, 3)
+        self.properties_box = QtWidgets.QVBoxLayout()
+        self.properties_box.setContentsMargins(0, 0, 0, 0)
+        self.properties_frame.setLayout(self.properties_box)
+        self.properties_frame.hide()
+
+        self.treeWidget = FCTree(columns=2)
+
+        self.properties_box.addWidget(self.treeWidget)
+        self.properties_box.setStretch(0, 0)
 
         # ### Gerber Apertures ####
         self.apertures_table_label = QtWidgets.QLabel('%s:' % _('Apertures'))
@@ -324,6 +341,11 @@ class GerberObjectUI(ObjectUI):
         )
         grid0.addWidget(self.create_buffer_button, 12, 0, 1, 3)
 
+        separator_line1 = QtWidgets.QFrame()
+        separator_line1.setFrameShape(QtWidgets.QFrame.HLine)
+        separator_line1.setFrameShadow(QtWidgets.QFrame.Sunken)
+        grid0.addWidget(separator_line1, 13, 0, 1, 3)
+
         self.tool_lbl = QtWidgets.QLabel('<b>%s</b>' % _("TOOLS"))
         grid0.addWidget(self.tool_lbl, 14, 0, 1, 3)
 
@@ -538,6 +560,28 @@ class ExcellonObjectUI(ObjectUI):
                                       """)
         grid0.addWidget(self.editor_button, 4, 0, 1, 3)
 
+        # PROPERTIES CB
+        self.properties_lbl = FCLabel('<b>%s</b>:' % _("PROPERTIES"))
+        self.properties_lbl.setToolTip(_("Show the Properties."))
+        self.properties_cb = FCCheckBox()
+
+        grid0.addWidget(self.properties_lbl, 6, 0)
+        grid0.addWidget(self.properties_cb, 6, 1, 1, 2)
+
+        # PROPERTIES Frame
+        self.properties_frame = QtWidgets.QFrame()
+        self.properties_frame.setContentsMargins(0, 0, 0, 0)
+        grid0.addWidget(self.properties_frame, 7, 0, 1, 3)
+        self.properties_box = QtWidgets.QVBoxLayout()
+        self.properties_box.setContentsMargins(0, 0, 0, 0)
+        self.properties_frame.setLayout(self.properties_box)
+        self.properties_frame.hide()
+
+        self.treeWidget = FCTree(columns=2)
+
+        self.properties_box.addWidget(self.treeWidget)
+        self.properties_box.setStretch(0, 0)
+
         # ### Tools Drills ####
         self.tools_table_label = QtWidgets.QLabel('<b>%s</b>' % _('Tools Table'))
         self.tools_table_label.setToolTip(
@@ -561,9 +605,9 @@ class ExcellonObjectUI(ObjectUI):
         hlay_plot.addStretch()
         hlay_plot.addWidget(self.plot_cb)
 
-        grid0.addWidget(self.tools_table_label, 6, 0)
-        grid0.addWidget(self.table_visibility_cb, 6, 1)
-        grid0.addLayout(hlay_plot, 6, 2)
+        grid0.addWidget(self.tools_table_label, 8, 0)
+        grid0.addWidget(self.table_visibility_cb, 8, 1)
+        grid0.addLayout(hlay_plot, 8, 2)
 
         # #############################################################################################################
         # #############################################################################################################
@@ -814,6 +858,28 @@ class GeometryObjectUI(ObjectUI):
                                       """)
         grid_header.addWidget(self.editor_button, 4, 0, 1, 3)
 
+        # PROPERTIES CB
+        self.properties_lbl = FCLabel('<b>%s</b>:' % _("PROPERTIES"))
+        self.properties_lbl.setToolTip(_("Show the Properties."))
+        self.properties_cb = FCCheckBox()
+
+        grid_header.addWidget(self.properties_lbl, 6, 0)
+        grid_header.addWidget(self.properties_cb, 6, 1, 1, 2)
+
+        # PROPERTIES Frame
+        self.properties_frame = QtWidgets.QFrame()
+        self.properties_frame.setContentsMargins(0, 0, 0, 0)
+        grid_header.addWidget(self.properties_frame, 7, 0, 1, 3)
+        self.properties_box = QtWidgets.QVBoxLayout()
+        self.properties_box.setContentsMargins(0, 0, 0, 0)
+        self.properties_frame.setLayout(self.properties_box)
+        self.properties_frame.hide()
+
+        self.treeWidget = FCTree(columns=2)
+
+        self.properties_box.addWidget(self.treeWidget)
+        self.properties_box.setStretch(0, 0)
+
         # add a frame and inside add a vertical box layout. Inside this vbox layout I add all the Tools widgets
         # this way I can hide/show the frame
         self.geo_tools_frame = QtWidgets.QFrame()
@@ -1758,6 +1824,28 @@ class CNCObjectUI(ObjectUI):
                                        """)
         f_lay.addWidget(self.editor_button, 4, 0, 1, 3)
 
+        # PROPERTIES CB
+        self.properties_lbl = FCLabel('<b>%s</b>:' % _("PROPERTIES"))
+        self.properties_lbl.setToolTip(_("Show the Properties."))
+        self.properties_cb = FCCheckBox()
+
+        f_lay.addWidget(self.properties_lbl, 6, 0)
+        f_lay.addWidget(self.properties_cb, 6, 1, 1, 2)
+
+        # PROPERTIES Frame
+        self.properties_frame = QtWidgets.QFrame()
+        self.properties_frame.setContentsMargins(0, 0, 0, 0)
+        f_lay.addWidget(self.properties_frame, 7, 0, 1, 3)
+        self.properties_box = QtWidgets.QVBoxLayout()
+        self.properties_box.setContentsMargins(0, 0, 0, 0)
+        self.properties_frame.setLayout(self.properties_box)
+        self.properties_frame.hide()
+
+        self.treeWidget = FCTree(columns=2)
+
+        self.properties_box.addWidget(self.treeWidget)
+        self.properties_box.setStretch(0, 0)
+
         # Annotation
         self.annotation_cb = FCCheckBox(_("Display Annotation"))
         self.annotation_cb.setToolTip(
@@ -1765,12 +1853,12 @@ class CNCObjectUI(ObjectUI):
               "When checked it will display numbers in order for each end\n"
               "of a travel line.")
         )
-        f_lay.addWidget(self.annotation_cb, 6, 0, 1, 3)
+        f_lay.addWidget(self.annotation_cb, 8, 0, 1, 3)
 
         separator_line = QtWidgets.QFrame()
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
         separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
-        f_lay.addWidget(separator_line, 8, 0, 1, 3)
+        f_lay.addWidget(separator_line, 10, 0, 1, 3)
 
         # Travelled Distance
         self.t_distance_label = QtWidgets.QLabel("<b>%s:</b>" % _("Travelled distance"))
@@ -1781,9 +1869,9 @@ class CNCObjectUI(ObjectUI):
         self.t_distance_entry = FCEntry()
         self.units_label = QtWidgets.QLabel()
 
-        f_lay.addWidget(self.t_distance_label, 10, 0)
-        f_lay.addWidget(self.t_distance_entry, 10, 1)
-        f_lay.addWidget(self.units_label, 10, 2)
+        f_lay.addWidget(self.t_distance_label, 12, 0)
+        f_lay.addWidget(self.t_distance_entry, 12, 1)
+        f_lay.addWidget(self.units_label, 12, 2)
 
         # Estimated Time
         self.t_time_label = QtWidgets.QLabel("<b>%s:</b>" % _("Estimated time"))
@@ -1794,9 +1882,9 @@ class CNCObjectUI(ObjectUI):
         self.t_time_entry = FCEntry()
         self.units_time_label = QtWidgets.QLabel()
 
-        f_lay.addWidget(self.t_time_label, 12, 0)
-        f_lay.addWidget(self.t_time_entry, 12, 1)
-        f_lay.addWidget(self.units_time_label, 12, 2)
+        f_lay.addWidget(self.t_time_label, 14, 0)
+        f_lay.addWidget(self.t_time_entry, 14, 1)
+        f_lay.addWidget(self.units_time_label, 14, 2)
 
         self.t_distance_label.hide()
         self.t_distance_entry.setVisible(False)
@@ -1806,7 +1894,7 @@ class CNCObjectUI(ObjectUI):
         separator_line = QtWidgets.QFrame()
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
         separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
-        f_lay.addWidget(separator_line, 14, 0, 1, 3)
+        f_lay.addWidget(separator_line, 16, 0, 1, 3)
 
         hlay = QtWidgets.QHBoxLayout()
         self.custom_box.addLayout(hlay)

+ 20 - 0
appObjects/FlatCAMCNCJob.py

@@ -574,8 +574,14 @@ class CNCJobObject(FlatCAMObj, CNCjob):
         self.ui.updateplot_button.clicked.connect(self.on_updateplot_button_click)
         self.ui.export_gcode_button.clicked.connect(self.on_exportgcode_button_click)
         self.ui.review_gcode_button.clicked.connect(self.on_edit_code_click)
+
+        # Editor Signal
         self.ui.editor_button.clicked.connect(lambda: self.app.object2editor())
 
+        # Properties
+        self.ui.properties_cb.stateChanged.connect(self.on_properties)
+        self.calculations_finished.connect(self.update_area_chull)
+
         # autolevelling signals
         self.ui.sal_cb.stateChanged.connect(self.on_toggle_autolevelling)
         self.ui.al_mode_radio.activated_custom.connect(self.on_mode_radio)
@@ -699,6 +705,20 @@ class CNCJobObject(FlatCAMObj, CNCjob):
         except (TypeError, AttributeError):
             pass
 
+    def on_properties(self, state):
+        if state:
+            self.ui.properties_frame.show()
+        else:
+            self.ui.properties_frame.hide()
+            return
+
+        self.ui.treeWidget.clear()
+        self.add_properties_items(obj=self, treeWidget=self.ui.treeWidget)
+
+        self.ui.treeWidget.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.MinimumExpanding)
+        # make sure that the FCTree widget columns are resized to content
+        self.ui.treeWidget.resize_sig.emit()
+
     def on_add_al_probepoints(self):
         # create the solid_geo
 

+ 18 - 1
appObjects/FlatCAMExcellon.py

@@ -176,7 +176,11 @@ class ExcellonObject(FlatCAMObj, Excellon):
 
         # Editor
         self.ui.editor_button.clicked.connect(lambda: self.app.object2editor())
-        
+
+        # Properties
+        self.ui.properties_cb.stateChanged.connect(self.on_properties)
+        self.calculations_finished.connect(self.update_area_chull)
+
         self.ui.drill_button.clicked.connect(lambda: self.app.drilling_tool.run(toggle=True))
         # self.ui.milling_button.clicked.connect(lambda: self.app.milling_tool.run(toggle=True))
 
@@ -603,6 +607,19 @@ class ExcellonObject(FlatCAMObj, Excellon):
     def on_table_visibility_toggle(self, state):
         self.ui.tools_table.show() if state else self.ui.tools_table.hide()
 
+    def on_properties(self, state):
+        if state:
+            self.ui.properties_frame.show()
+        else:
+            self.ui.properties_frame.hide()
+            return
+
+        self.ui.treeWidget.clear()
+        self.add_properties_items(obj=self, treeWidget=self.ui.treeWidget)
+
+        # make sure that the FCTree widget columns are resized to content
+        self.ui.treeWidget.resize_sig.emit()
+
     def export_excellon(self, whole, fract, e_zeros=None, form='dec', factor=1, slot_type='routing'):
         """
         Returns two values, first is a boolean , if 1 then the file has slots and second contain the Excellon code

+ 19 - 0
appObjects/FlatCAMGeometry.py

@@ -589,8 +589,13 @@ class GeometryObject(FlatCAMObj, Geometry):
         self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click)
         self.ui.multicolored_cb.stateChanged.connect(self.on_multicolored_cb_click)
 
+        # Editor Signal
         self.ui.editor_button.clicked.connect(self.app.object2editor)
 
+        # Properties
+        self.ui.properties_cb.stateChanged.connect(self.on_properties)
+        self.calculations_finished.connect(self.update_area_chull)
+
         self.ui.generate_cnc_button.clicked.connect(self.on_generatecnc_button_click)
         self.ui.paint_tool_button.clicked.connect(lambda: self.app.paint_tool.run(toggle=False))
         self.ui.generate_ncc_button.clicked.connect(lambda: self.app.ncclear_tool.run(toggle=False))
@@ -614,6 +619,20 @@ class GeometryObject(FlatCAMObj, Geometry):
 
         self.ui.geo_tools_table.drag_drop_sig.connect(self.rebuild_ui)
 
+    def on_properties(self, state):
+        if state:
+            self.ui.properties_frame.show()
+        else:
+            self.ui.properties_frame.hide()
+            return
+
+        self.ui.treeWidget.clear()
+        self.add_properties_items(obj=self, treeWidget=self.ui.treeWidget)
+
+        self.ui.treeWidget.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.MinimumExpanding)
+        # make sure that the FCTree widget columns are resized to content
+        self.ui.treeWidget.resize_sig.emit()
+
     def rebuild_ui(self):
         # read the table tools uid
         current_uid_list = []

+ 17 - 0
appObjects/FlatCAMGerber.py

@@ -150,6 +150,10 @@ class GerberObject(FlatCAMObj, Gerber):
         # Editor
         self.ui.editor_button.clicked.connect(lambda: self.app.object2editor())
 
+        # Properties
+        self.ui.properties_cb.stateChanged.connect(self.on_properties)
+        self.calculations_finished.connect(self.update_area_chull)
+
         # Tools
         self.ui.iso_button.clicked.connect(self.app.isolation_tool.run)
         self.ui.generate_ncc_button.clicked.connect(self.app.ncclear_tool.run)
@@ -343,6 +347,19 @@ class GerberObject(FlatCAMObj, Gerber):
 
         return new_geo
 
+    def on_properties(self, state):
+        if state:
+            self.ui.properties_frame.show()
+        else:
+            self.ui.properties_frame.hide()
+            return
+
+        self.ui.treeWidget.clear()
+        self.add_properties_items(obj=self, treeWidget=self.ui.treeWidget)
+
+        # make sure that the FCTree widget columns are resized to content
+        self.ui.treeWidget.resize_sig.emit()
+
     def on_generate_buffer(self):
         self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Buffering solid geometry"))
 

+ 452 - 3
appObjects/FlatCAMObj.py

@@ -18,7 +18,12 @@ from appCommon.Common import LoudDict
 from appGUI.PlotCanvasLegacy import ShapeCollectionLegacy
 from appGUI.VisPyVisuals import ShapeCollection
 
+from shapely.ops import unary_union
+from shapely.geometry import Polygon, MultiPolygon
+
+from copy import deepcopy
 import sys
+import math
 
 import gettext
 import appTranslation as fcTranslate
@@ -55,6 +60,9 @@ class FlatCAMObj(QtCore.QObject):
     # signal to plot a single object
     plot_single_object = QtCore.pyqtSignal()
 
+    # signal for Properties
+    calculations_finished = QtCore.pyqtSignal(float, float, float, float, float, object)
+
     def __init__(self, name):
         """
         Constructor.
@@ -112,6 +120,9 @@ class FlatCAMObj(QtCore.QObject):
         # self.units = 'IN'
         self.units = self.app.defaults['units']
 
+        # this is the treeWidget from the UI; it is updated when the add_properties_items() method is called
+        self.treeWidget = None
+
         self.plot_single_object.connect(self.single_object_plot)
 
     def __del__(self):
@@ -456,6 +467,444 @@ class FlatCAMObj(QtCore.QObject):
                 self.app.defaults[filter_string] = ';;'.join(filter_list)
                 return
 
+    def add_properties_items(self, obj, treeWidget):
+        self.treeWidget = treeWidget
+        parent = self.treeWidget.invisibleRootItem()
+        apertures = ''
+        tools = ''
+        drills = ''
+        slots = ''
+        others = ''
+
+        font = QtGui.QFont()
+        font.setBold(True)
+
+        p_color = QtGui.QColor("#000000") if self.app.defaults['global_gray_icons'] is False \
+            else QtGui.QColor("#FFFFFF")
+
+        # main Items categories
+        dims = self.treeWidget.addParent(
+            parent, _('Dimensions'), expanded=True, color=p_color, font=font)
+        options = self.treeWidget.addParent(parent, _('Options'), color=p_color, font=font)
+
+        if obj.kind.lower() == 'gerber':
+            apertures = self.treeWidget.addParent(
+                parent, _('Apertures'), expanded=True, color=p_color, font=font)
+        else:
+            tools = self.treeWidget.addParent(
+                parent, _('Tools'), expanded=True, color=p_color, font=font)
+
+        if obj.kind.lower() == 'excellon':
+            drills = self.treeWidget.addParent(
+                parent, _('Drills'), expanded=True, color=p_color, font=font)
+            slots = self.treeWidget.addParent(
+                parent, _('Slots'), expanded=True, color=p_color, font=font)
+
+        if obj.kind.lower() == 'cncjob':
+            others = self.treeWidget.addParent(
+                parent, _('Others'), expanded=True, color=p_color, font=font)
+
+        # separator = self.treeWidget.addParent(parent, '')
+
+        def job_thread(obj_prop):
+            self.app.proc_container.new(_("Calculating dimensions ... Please wait."))
+
+            length = 0.0
+            width = 0.0
+            area = 0.0
+            copper_area = 0.0
+
+            geo = obj_prop.solid_geometry
+            if geo:
+                # calculate physical dimensions
+                try:
+                    xmin, ymin, xmax, ymax = obj_prop.bounds()
+
+                    length = abs(xmax - xmin)
+                    width = abs(ymax - ymin)
+                except Exception as ee:
+                    log.debug("FlatCAMObj.addItems() -> calculate dimensions --> %s" % str(ee))
+
+                # calculate box area
+                if self.app.defaults['units'].lower() == 'mm':
+                    area = (length * width) / 100
+                else:
+                    area = length * width
+
+                if obj_prop.kind.lower() == 'gerber':
+                    # calculate copper area
+                    try:
+                        for geo_el in geo:
+                            copper_area += geo_el.area
+                    except TypeError:
+                        copper_area += geo.area
+                    copper_area /= 100
+            else:
+                xmin = []
+                ymin = []
+                xmax = []
+                ymax = []
+
+                if obj_prop.kind.lower() == 'cncjob':
+                    try:
+                        for tool_k in obj_prop.exc_cnc_tools:
+                            x0, y0, x1, y1 = unary_union(obj_prop.exc_cnc_tools[tool_k]['solid_geometry']).bounds
+                            xmin.append(x0)
+                            ymin.append(y0)
+                            xmax.append(x1)
+                            ymax.append(y1)
+                    except Exception as ee:
+                        log.debug("FlatCAMObj.addItems() --> %s" % str(ee))
+
+                    try:
+                        for tool_k in obj_prop.cnc_tools:
+                            x0, y0, x1, y1 = unary_union(obj_prop.cnc_tools[tool_k]['solid_geometry']).bounds
+                            xmin.append(x0)
+                            ymin.append(y0)
+                            xmax.append(x1)
+                            ymax.append(y1)
+                    except Exception as ee:
+                        log.debug("FlatCAMObj.addItems() --> %s" % str(ee))
+                else:
+                    try:
+                        for tool_k in obj_prop.tools:
+                            x0, y0, x1, y1 = unary_union(obj_prop.tools[tool_k]['solid_geometry']).bounds
+                            xmin.append(x0)
+                            ymin.append(y0)
+                            xmax.append(x1)
+                            ymax.append(y1)
+                    except Exception as ee:
+                        log.debug("FlatCAMObj.addItems() --> %s" % str(ee))
+
+                try:
+                    xmin = min(xmin)
+                    ymin = min(ymin)
+                    xmax = max(xmax)
+                    ymax = max(ymax)
+
+                    length = abs(xmax - xmin)
+                    width = abs(ymax - ymin)
+
+                    # calculate box area
+                    if self.app.defaults['units'].lower() == 'mm':
+                        area = (length * width) / 100
+                    else:
+                        area = length * width
+
+                    if obj_prop.kind.lower() == 'gerber':
+                        # calculate copper area
+
+                        # create a complete solid_geometry from the tools
+                        geo_tools = []
+                        for tool_k in obj_prop.tools:
+                            if 'solid_geometry' in obj_prop.tools[tool_k]:
+                                for geo_el in obj_prop.tools[tool_k]['solid_geometry']:
+                                    geo_tools.append(geo_el)
+
+                        try:
+                            for geo_el in geo_tools:
+                                copper_area += geo_el.area
+                        except TypeError:
+                            copper_area += geo_tools.area
+                        copper_area /= 100
+                except Exception as err:
+                    log.debug("FlatCAMObj.addItems() --> %s" % str(err))
+
+            area_chull = 0.0
+            if obj_prop.kind.lower() != 'cncjob':
+                # calculate and add convex hull area
+                if geo:
+                    if isinstance(geo, list) and geo[0] is not None:
+                        if isinstance(geo, MultiPolygon):
+                            env_obj = geo.convex_hull
+                        elif (isinstance(geo, MultiPolygon) and len(geo) == 1) or \
+                                (isinstance(geo, list) and len(geo) == 1) and isinstance(geo[0], Polygon):
+                            env_obj = unary_union(geo)
+                            env_obj = env_obj.convex_hull
+                        else:
+                            env_obj = unary_union(geo)
+                            env_obj = env_obj.convex_hull
+
+                        area_chull = env_obj.area
+                    else:
+                        area_chull = 0
+                else:
+                    try:
+                        area_chull = []
+                        for tool_k in obj_prop.tools:
+                            area_el = unary_union(obj_prop.tools[tool_k]['solid_geometry']).convex_hull
+                            area_chull.append(area_el.area)
+                        area_chull = max(area_chull)
+                    except Exception as er:
+                        area_chull = None
+                        log.debug("FlatCAMObj.addItems() --> %s" % str(er))
+
+            if self.app.defaults['units'].lower() == 'mm' and area_chull:
+                area_chull = area_chull / 100
+
+            if area_chull is None:
+                area_chull = 0
+
+            self.calculations_finished.emit(area, length, width, area_chull, copper_area, dims)
+
+        self.app.worker_task.emit({'fcn': job_thread, 'params': [obj]})
+
+        # Options items
+        for option in obj.options:
+            if option == 'name':
+                continue
+            self.treeWidget.addChild(options, [str(option), str(obj.options[option])], True)
+
+        # Items that depend on the object type
+        if obj.kind.lower() == 'gerber':
+            temp_ap = {}
+            for ap in obj.apertures:
+                temp_ap.clear()
+                temp_ap = deepcopy(obj.apertures[ap])
+                temp_ap.pop('geometry', None)
+
+                solid_nr = 0
+                follow_nr = 0
+                clear_nr = 0
+
+                if 'geometry' in obj.apertures[ap]:
+                    if obj.apertures[ap]['geometry']:
+                        font.setBold(True)
+                        for el in obj.apertures[ap]['geometry']:
+                            if 'solid' in el:
+                                solid_nr += 1
+                            if 'follow' in el:
+                                follow_nr += 1
+                            if 'clear' in el:
+                                clear_nr += 1
+                else:
+                    font.setBold(False)
+                temp_ap['Solid_Geo'] = '%s Polygons' % str(solid_nr)
+                temp_ap['Follow_Geo'] = '%s LineStrings' % str(follow_nr)
+                temp_ap['Clear_Geo'] = '%s Polygons' % str(clear_nr)
+
+                apid = self.treeWidget.addParent(
+                    apertures, str(ap), expanded=False, color=p_color, font=font)
+                for key in temp_ap:
+                    self.treeWidget.addChild(apid, [str(key), str(temp_ap[key])], True)
+        elif obj.kind.lower() == 'excellon':
+            tot_drill_cnt = 0
+            tot_slot_cnt = 0
+
+            for tool, value in obj.tools.items():
+                toolid = self.treeWidget.addParent(
+                    tools, str(tool), expanded=False, color=p_color, font=font)
+
+                drill_cnt = 0  # variable to store the nr of drills per tool
+                slot_cnt = 0  # variable to store the nr of slots per tool
+
+                # Find no of drills for the current tool
+                if 'drills' in value and value['drills']:
+                    drill_cnt = len(value['drills'])
+
+                tot_drill_cnt += drill_cnt
+
+                # Find no of slots for the current tool
+                if 'slots' in value and value['slots']:
+                    slot_cnt = len(value['slots'])
+
+                tot_slot_cnt += slot_cnt
+
+                self.treeWidget.addChild(
+                    toolid,
+                    [
+                        _('Diameter'),
+                        '%.*f %s' % (self.decimals, value['tooldia'], self.app.defaults['units'].lower())
+                    ],
+                    True
+                )
+                self.treeWidget.addChild(toolid, [_('Drills number'), str(drill_cnt)], True)
+                self.treeWidget.addChild(toolid, [_('Slots number'), str(slot_cnt)], True)
+
+            self.treeWidget.addChild(drills, [_('Drills total number:'), str(tot_drill_cnt)], True)
+            self.treeWidget.addChild(slots, [_('Slots total number:'), str(tot_slot_cnt)], True)
+        elif obj.kind.lower() == 'geometry':
+            for tool, value in obj.tools.items():
+                geo_tool = self.treeWidget.addParent(
+                    tools, str(tool), expanded=False, color=p_color, font=font)
+                for k, v in value.items():
+                    if k == 'solid_geometry':
+                        # printed_value = _('Present') if v else _('None')
+                        try:
+                            printed_value = str(len(v))
+                        except (TypeError, AttributeError):
+                            printed_value = '1'
+                        self.treeWidget.addChild(geo_tool, [str(k), printed_value], True)
+                    elif k == 'data':
+                        tool_data = self.treeWidget.addParent(
+                            geo_tool, str(k).capitalize(), color=p_color, font=font)
+                        for data_k, data_v in v.items():
+                            self.treeWidget.addChild(tool_data, [str(data_k), str(data_v)], True)
+                    else:
+                        self.treeWidget.addChild(geo_tool, [str(k), str(v)], True)
+        elif obj.kind.lower() == 'cncjob':
+            # for cncjob objects made from gerber or geometry
+            for tool, value in obj.cnc_tools.items():
+                geo_tool = self.treeWidget.addParent(
+                    tools, str(tool), expanded=False, color=p_color, font=font)
+                for k, v in value.items():
+                    if k == 'solid_geometry':
+                        printed_value = _('Present') if v else _('None')
+                        self.treeWidget.addChild(geo_tool, [_("Solid Geometry"), printed_value], True)
+                    elif k == 'gcode':
+                        printed_value = _('Present') if v != '' else _('None')
+                        self.treeWidget.addChild(geo_tool, [_("GCode Text"), printed_value], True)
+                    elif k == 'gcode_parsed':
+                        printed_value = _('Present') if v else _('None')
+                        self.treeWidget.addChild(geo_tool, [_("GCode Geometry"), printed_value], True)
+                    elif k == 'data':
+                        pass
+                    else:
+                        self.treeWidget.addChild(geo_tool, [str(k), str(v)], True)
+
+                v = value['data']
+                tool_data = self.treeWidget.addParent(
+                    geo_tool, _("Tool Data"), color=p_color, font=font)
+                for data_k, data_v in v.items():
+                    self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True)
+
+            # for cncjob objects made from excellon
+            for tool_dia, value in obj.exc_cnc_tools.items():
+                exc_tool = self.treeWidget.addParent(
+                    tools, str(value['tool']), expanded=False, color=p_color, font=font
+                )
+                self.treeWidget.addChild(
+                    exc_tool,
+                    [
+                        _('Diameter'),
+                        '%.*f %s' % (self.decimals, tool_dia, self.app.defaults['units'].lower())
+                    ],
+                    True
+                )
+                for k, v in value.items():
+                    if k == 'solid_geometry':
+                        printed_value = _('Present') if v else _('None')
+                        self.treeWidget.addChild(exc_tool, [_("Solid Geometry"), printed_value], True)
+                    elif k == 'nr_drills':
+                        self.treeWidget.addChild(exc_tool, [_("Drills number"), str(v)], True)
+                    elif k == 'nr_slots':
+                        self.treeWidget.addChild(exc_tool, [_("Slots number"), str(v)], True)
+                    elif k == 'gcode':
+                        printed_value = _('Present') if v != '' else _('None')
+                        self.treeWidget.addChild(exc_tool, [_("GCode Text"), printed_value], True)
+                    elif k == 'gcode_parsed':
+                        printed_value = _('Present') if v else _('None')
+                        self.treeWidget.addChild(exc_tool, [_("GCode Geometry"), printed_value], True)
+                    else:
+                        pass
+
+                self.treeWidget.addChild(
+                    exc_tool,
+                    [
+                        _("Depth of Cut"),
+                        '%.*f %s' % (
+                            self.decimals,
+                            (obj.z_cut - abs(value['data']['tools_drill_offset'])),
+                            self.app.defaults['units'].lower()
+                        )
+                    ],
+                    True
+                )
+                self.treeWidget.addChild(
+                    exc_tool,
+                    [
+                        _("Clearance Height"),
+                        '%.*f %s' % (
+                            self.decimals,
+                            obj.z_move,
+                            self.app.defaults['units'].lower()
+                        )
+                    ],
+                    True
+                )
+                self.treeWidget.addChild(
+                    exc_tool,
+                    [
+                        _("Feedrate"),
+                        '%.*f %s/min' % (
+                            self.decimals,
+                            obj.feedrate,
+                            self.app.defaults['units'].lower()
+                        )
+                    ],
+                    True
+                )
+
+                v = value['data']
+                tool_data = self.treeWidget.addParent(
+                    exc_tool, _("Tool Data"), color=p_color, font=font)
+                for data_k, data_v in v.items():
+                    self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True)
+
+            r_time = obj.routing_time
+            if r_time > 1:
+                units_lbl = 'min'
+            else:
+                r_time *= 60
+                units_lbl = 'sec'
+            r_time = math.ceil(float(r_time))
+            self.treeWidget.addChild(
+                others,
+                [
+                    '%s:' % _('Routing time'),
+                    '%.*f %s' % (self.decimals, r_time, units_lbl)],
+                True
+            )
+            self.treeWidget.addChild(
+                others,
+                [
+                    '%s:' % _('Travelled distance'),
+                    '%.*f %s' % (self.decimals, obj.travel_distance, self.app.defaults['units'].lower())
+                ],
+                True
+            )
+
+        # treeWidget.addChild(separator, [''])
+
+    def update_area_chull(self, area, length, width, chull_area, copper_area, location):
+
+        # add dimensions
+        self.treeWidget.addChild(
+            location,
+            ['%s:' % _('Length'), '%.*f %s' % (self.decimals, length, self.app.defaults['units'].lower())],
+            True
+        )
+        self.treeWidget.addChild(
+            location,
+            ['%s:' % _('Width'), '%.*f %s' % (self.decimals, width, self.app.defaults['units'].lower())],
+            True
+        )
+
+        # add box area
+        if self.app.defaults['units'].lower() == 'mm':
+            self.treeWidget.addChild(location, ['%s:' % _('Box Area'), '%.*f %s' % (self.decimals, area, 'cm2')], True)
+            self.treeWidget.addChild(
+                location,
+                ['%s:' % _('Convex_Hull Area'), '%.*f %s' % (self.decimals, chull_area, 'cm2')],
+                True
+            )
+
+        else:
+            self.treeWidget.addChild(location, ['%s:' % _('Box Area'), '%.*f %s' % (self.decimals, area, 'in2')], True)
+            self.treeWidget.addChild(
+                location,
+                ['%s:' % _('Convex_Hull Area'), '%.*f %s' % (self.decimals, chull_area, 'in2')],
+                True
+            )
+
+        # add copper area
+        if self.app.defaults['units'].lower() == 'mm':
+            self.treeWidget.addChild(
+                location, ['%s:' % _('Copper Area'), '%.*f %s' % (self.decimals, copper_area, 'cm2')], True)
+        else:
+            self.treeWidget.addChild(
+                location, ['%s:' % _('Copper Area'), '%.*f %s' % (self.decimals, copper_area, 'in2')], True)
+
     @staticmethod
     def poly2rings(poly):
         return [poly.exterior] + [interior for interior in poly.interiors]
@@ -471,8 +920,8 @@ class FlatCAMObj(QtCore.QObject):
         current_visibility = self.shapes.visible
         # self.shapes.visible = value   # maybe this is slower in VisPy? use enabled property?
 
-        def task(current_visibility):
-            if current_visibility is True:
+        def task(visibility):
+            if visibility is True:
                 if value is False:
                     self.shapes.visible = False
             else:
@@ -517,4 +966,4 @@ class FlatCAMObj(QtCore.QObject):
         del self.options
 
         # Set flag
-        self.deleted = True
+        self.deleted = True