Ejemplo n.º 1
0
class ControlWorkbench(WorkbenchConnection):
    def __init__(self, parent):
        WorkbenchConnection.__init__(self, parent)

        self.driver = Driver.Instance()

        self.load()

    def load(self):
        #-- Toolbar Configuration
        self.toolbar.Realize()

        self.scrollPanel = wx.lib.scrolledpanel.ScrolledPanel(self._panel,
                                                              size=(290, -1))
        self.scrollPanel.SetupScrolling(scroll_x=False, scrollIntoView=False)
        self.scrollPanel.SetAutoLayout(1)

        self.controls = ExpandableControl(self.scrollPanel)

        self.controls.addPanel('camera_control', CameraControl(self.controls))
        self.controls.addPanel('laser_control', LaserControl(self.controls))
        self.controls.addPanel('ldr_value', LDRControl(self.controls))
        self.controls.addPanel('motor_control', MotorControl(self.controls))
        self.controls.addPanel('gcode_control', GcodeControl(self.controls))

        self.videoView = VideoView(self._panel, self.getFrame, 10)
        self.videoView.SetBackgroundColour(wx.BLACK)

        #-- Layout
        vsbox = wx.BoxSizer(wx.VERTICAL)
        vsbox.Add(self.controls, 0, wx.ALL | wx.EXPAND, 0)
        self.scrollPanel.SetSizer(vsbox)
        vsbox.Fit(self.scrollPanel)

        self.addToPanel(self.scrollPanel, 0)
        self.addToPanel(self.videoView, 1)

        self.updateCallbacks()
        self.Layout()

    def updateCallbacks(self):
        self.controls.updateCallbacks()

    def getFrame(self):
        return self.driver.camera.captureImage()

    def updateToolbarStatus(self, status):
        if status:
            if self.IsShown():
                self.videoView.play()
            self.controls.enableContent()
        else:
            self.videoView.stop()
            self.controls.disableContent()

    def updateProfileToAllControls(self):
        self.controls.updateProfile()
Ejemplo n.º 2
0
class PlatformExtrinsicsMainPage(Page):
    def __init__(self,
                 parent,
                 afterCancelCallback=None,
                 afterCalibrationCallback=None):
        Page.__init__(
            self,
            parent,
            title=_("Platform Extrinsics"),
            subTitle=
            _("Put the pattern on the platform as shown in the picture and press Calibrate to continue"
              ),
            left=_("Cancel"),
            right=_("Calibrate"),
            buttonLeftCallback=self.onCancel,
            buttonRightCallback=self.onCalibrate,
            panelOrientation=wx.HORIZONTAL,
            viewProgress=True)

        self.driver = Driver.Instance()
        self.cameraIntrinsics = calibration.CameraIntrinsics.Instance()
        self.platformExtrinsics = calibration.PlatformExtrinsics.Instance()

        self.onCalibration = False

        self.afterCancelCallback = afterCancelCallback
        self.afterCalibrationCallback = afterCalibrationCallback

        #-- Image View
        imageView = ImageView(self._panel)
        imageView.setImage(
            wx.Image(resources.getPathForImage("pattern-position-left.jpg")))

        #-- Video View
        self.videoView = VideoView(self._panel, self.getFrame, 50)
        self.videoView.SetBackgroundColour(wx.BLACK)

        #-- Layout
        self.addToPanel(imageView, 3)
        self.addToPanel(self.videoView, 2)

        #-- Events
        self.Bind(wx.EVT_SHOW, self.onShow)

        self.Layout()

    def initialize(self):
        self.gauge.SetValue(0)
        self._rightButton.Enable()

    def onShow(self, event):
        if event.GetShow():
            self.videoView.play()
            self.GetParent().Layout()
            self.Layout()
        else:
            try:
                self.initialize()
                self.videoView.stop()
            except:
                pass

    def getFrame(self):
        if self.onCalibration:
            frame = self.platformExtrinsics.getImage()
        else:
            frame = self.driver.camera.captureImage()
        if frame is not None:
            retval, frame = self.cameraIntrinsics.detectChessboard(frame)

        return frame

    def onCalibrate(self):
        self.onCalibration = True
        self.platformExtrinsics.setImage(self.driver.camera.captureImage())

        self.platformExtrinsics.setCallbacks(
            self.beforeCalibration,
            lambda p: wx.CallAfter(self.progressCalibration, p),
            lambda r: wx.CallAfter(self.afterCalibration, r))
        self.platformExtrinsics.start()

    def beforeCalibration(self):
        self._rightButton.Disable()
        self.gauge.SetValue(0)
        self.waitCursor = wx.BusyCursor()

    def progressCalibration(self, progress):
        self.gauge.SetValue(progress)

    def afterCalibration(self, result):
        self.onCalibrationFinished(result)
        self.onCalibration = False

    def onCalibrationFinished(self, result):
        self._rightButton.Enable()
        if self.afterCalibrationCallback is not None:
            self.afterCalibrationCallback(result)
        if hasattr(self, 'waitCursor'):
            del self.waitCursor

    def onCancel(self):
        boardUnplugCallback = self.driver.board.unplugCallback
        cameraUnplugCallback = self.driver.camera.unplugCallback
        self.driver.board.setUnplugCallback(None)
        self.driver.camera.setUnplugCallback(None)
        if not hasattr(self, 'waitCursor'):
            self.waitCursor = wx.BusyCursor()
        self.onCalibration = False
        self.platformExtrinsics.cancel()
        if self.afterCancelCallback is not None:
            self.afterCancelCallback()
        del self.waitCursor
        self.driver.board.setUnplugCallback(boardUnplugCallback)
        self.driver.camera.setUnplugCallback(cameraUnplugCallback)
Ejemplo n.º 3
0
class ScanningWorkbench(WorkbenchConnection):
    def __init__(self, parent):
        WorkbenchConnection.__init__(self, parent)

        self.scanning = False
        self.showVideoViews = False

        self.simpleScan = SimpleScan.Instance()
        self.textureScan = TextureScan.Instance()

        self.currentScan = self.simpleScan

        self.load()

        self.pointCloudTimer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onPointCloudTimer, self.pointCloudTimer)

    def load(self):
        #-- Toolbar Configuration
        self.playTool = self.toolbar.AddLabelTool(
            wx.NewId(),
            _("Play"),
            wx.Bitmap(resources.getPathForImage("play.png")),
            shortHelp=_("Play"))
        self.stopTool = self.toolbar.AddLabelTool(
            wx.NewId(),
            _("Stop"),
            wx.Bitmap(resources.getPathForImage("stop.png")),
            shortHelp=_("Stop"))
        self.pauseTool = self.toolbar.AddLabelTool(
            wx.NewId(),
            _("Pause"),
            wx.Bitmap(resources.getPathForImage("pause.png")),
            shortHelp=_("Pause"))
        self.toolbar.Realize()

        #-- Disable Toolbar Items
        self.enableLabelTool(self.playTool, False)
        self.enableLabelTool(self.stopTool, False)
        self.enableLabelTool(self.pauseTool, False)

        #-- Bind Toolbar Items
        self.Bind(wx.EVT_TOOL, self.onPlayToolClicked, self.playTool)
        self.Bind(wx.EVT_TOOL, self.onStopToolClicked, self.stopTool)
        self.Bind(wx.EVT_TOOL, self.onPauseToolClicked, self.pauseTool)

        self.scrollPanel = wx.lib.scrolledpanel.ScrolledPanel(self._panel,
                                                              size=(290, -1))
        self.scrollPanel.SetupScrolling(scroll_x=False, scrollIntoView=False)
        self.scrollPanel.SetAutoLayout(1)

        self.controls = ExpandableControl(self.scrollPanel)

        self.controls.addPanel('scan_parameters',
                               ScanParameters(self.controls))
        self.controls.addPanel('rotative_platform',
                               RotativePlatform(self.controls))
        self.controls.addPanel('image_acquisition',
                               ImageAcquisition(self.controls))
        self.controls.addPanel('image_segmentation',
                               ImageSegmentation(self.controls))
        self.controls.addPanel('point_cloud_generation',
                               PointCloudGeneration(self.controls))

        self.splitterWindow = wx.SplitterWindow(self._panel)

        self.videoView = VideoView(self.splitterWindow, self.getFrame, 10)
        self.videoView.SetBackgroundColour(wx.BLACK)

        self.scenePanel = wx.Panel(self.splitterWindow)
        self.sceneView = SceneView(self.scenePanel)
        self.gauge = wx.Gauge(self.scenePanel, size=(-1, 30))
        self.gauge.Hide()

        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.sceneView, 1, wx.ALL | wx.EXPAND, 0)
        vbox.Add(self.gauge, 0, wx.ALL | wx.EXPAND, 0)
        self.scenePanel.SetSizer(vbox)

        self.splitterWindow.SplitVertically(self.videoView, self.scenePanel)
        self.splitterWindow.SetMinimumPaneSize(200)

        #-- Layout
        vsbox = wx.BoxSizer(wx.VERTICAL)
        vsbox.Add(self.controls, 0, wx.ALL | wx.EXPAND, 0)
        self.scrollPanel.SetSizer(vsbox)
        vsbox.Fit(self.scrollPanel)

        self.addToPanel(self.scrollPanel, 0)
        self.addToPanel(self.splitterWindow, 1)

        #- Video View Selector
        _choices = []
        choices = profile.getProfileSettingObject('img_type').getType()
        for i in choices:
            _choices.append(_(i))
        self.videoViewsDict = dict(zip(_choices, choices))

        self.buttonShowVideoViews = wx.BitmapButton(
            self.videoView, wx.NewId(),
            wx.Bitmap(resources.getPathForImage("views.png"),
                      wx.BITMAP_TYPE_ANY), (10, 10))
        self.comboVideoViews = wx.ComboBox(
            self.videoView,
            value=_(profile.getProfileSetting('img_type')),
            choices=_choices,
            style=wx.CB_READONLY,
            pos=(60, 10))

        self.buttonShowVideoViews.Hide()
        self.comboVideoViews.Hide()

        self.buttonShowVideoViews.Bind(wx.EVT_BUTTON, self.onShowVideoViews)
        self.comboVideoViews.Bind(wx.EVT_COMBOBOX,
                                  self.onComboBoVideoViewsSelect)

        self.updateCallbacks()
        self.Layout()

    def updateCallbacks(self):
        self.controls.updateCallbacks()

    def enableRestore(self, value):
        self.controls.enableRestore(value)

    def onShow(self, event):
        if event.GetShow():
            self.updateStatus(self.currentScan.driver.isConnected)
            self.pointCloudTimer.Stop()
        else:
            try:
                self.pointCloudTimer.Stop()
                self.videoView.stop()
            except:
                pass

    def onShowVideoViews(self, event):
        self.showVideoViews = not self.showVideoViews
        if self.showVideoViews:
            self.comboVideoViews.Show()
        else:
            self.comboVideoViews.Hide()

    def onComboBoVideoViewsSelect(self, event):
        value = self.videoViewsDict[self.comboVideoViews.GetValue()]
        self.currentScan.setImageType(value)
        profile.putProfileSetting('img_type', value)

    def getFrame(self):
        if self.scanning:
            return self.currentScan.getImage()
        else:
            return self.currentScan.getImage(self.driver.camera.captureImage())

    def onPointCloudTimer(self, event):
        p, r = self.currentScan.getProgress()
        self.gauge.SetRange(r)
        self.gauge.SetValue(p)
        pointCloud = self.currentScan.getPointCloudIncrement()
        if pointCloud is not None:
            if pointCloud[0] is not None and pointCloud[1] is not None:
                if len(pointCloud[0]) > 0:
                    self.sceneView.appendPointCloud(pointCloud[0],
                                                    pointCloud[1])

    def onPlayToolClicked(self, event):
        if self.currentScan.inactive:
            #-- Resume
            self.enableLabelTool(self.pauseTool, True)
            self.enableLabelTool(self.playTool, False)
            self.currentScan.resume()
            self.pointCloudTimer.Start(milliseconds=50)
        else:
            result = True
            if self.sceneView._object is not None:
                dlg = wx.MessageDialog(
                    self,
                    _("Your current model will be erased.\nDo you really want to do it?"
                      ), _("Clear Point Cloud"), wx.YES_NO | wx.ICON_QUESTION)
                result = dlg.ShowModal() == wx.ID_YES
                dlg.Destroy()
            if result:
                value = profile.getProfileSetting('scan_type')
                if value == 'Simple Scan':
                    self.currentScan = self.simpleScan
                elif value == 'Texture Scan':
                    self.currentScan = self.textureScan
                self.gauge.SetValue(0)
                self.gauge.Show()
                self.scenePanel.Layout()
                self.Layout()
                self.currentScan.setCallbacks(
                    self.beforeScan, lambda r: wx.CallAfter(self.afterScan, r))
                self.currentScan.start()

    def beforeScan(self):
        self.scanning = True
        self.buttonShowVideoViews.Show()
        self.enableLabelTool(self.disconnectTool, False)
        self.enableLabelTool(self.playTool, False)
        self.enableLabelTool(self.stopTool, True)
        self.enableLabelTool(self.pauseTool, True)
        self.sceneView.createDefaultObject()
        self.sceneView.setShowDeleteMenu(False)
        self.videoView.setMilliseconds(200)
        self.combo.Disable()
        self.GetParent().menuFile.Enable(
            self.GetParent().menuLaunchWizard.GetId(), False)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuLoadModel.GetId(), False)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuSaveModel.GetId(), False)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuClearModel.GetId(), False)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuOpenProfile.GetId(), False)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuSaveProfile.GetId(), False)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuResetProfile.GetId(), False)
        self.GetParent().menuFile.Enable(self.GetParent().menuExit.GetId(),
                                         False)
        self.GetParent().menuEdit.Enable(
            self.GetParent().menuPreferences.GetId(), False)
        self.GetParent().menuHelp.Enable(self.GetParent().menuWelcome.GetId(),
                                         False)
        panel = self.controls.panels['scan_parameters']
        section = panel.sections['scan_parameters']
        section.disable('scan_type')
        section.disable('use_laser')
        panel = self.controls.panels['rotative_platform']
        section = panel.sections['motor_scanning']
        section.disable('feed_rate_scanning')
        section.disable('acceleration_scanning')
        panel = self.controls.panels['image_acquisition']
        section = panel.sections['camera_scanning']
        if not sys.isDarwin():
            section.disable('framerate_scanning')
            section.disable('resolution_scanning')
        self.enableRestore(False)
        self.pointCloudTimer.Start(milliseconds=50)

    def afterScan(self, response):
        ret, result = response
        if ret:
            dlg = wx.MessageDialog(
                self,
                _("Scanning has finished. If you want to save your point cloud go to File > Save Model"
                  ), _("Scanning finished!"), wx.OK | wx.ICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()
            self.scanning = False
            self.onScanFinished()

    def onStopToolClicked(self, event):
        paused = self.currentScan.inactive
        self.currentScan.pause()
        dlg = wx.MessageDialog(
            self,
            _("Your current scanning will be stopped.\nDo you really want to do it?"
              ), _("Stop Scanning"), wx.YES_NO | wx.ICON_QUESTION)
        result = dlg.ShowModal() == wx.ID_YES
        dlg.Destroy()

        if result:
            self.scanning = False
            self.currentScan.stop()
            self.onScanFinished()
        else:
            if not paused:
                self.currentScan.resume()

    def onScanFinished(self):
        self.buttonShowVideoViews.Hide()
        self.comboVideoViews.Hide()
        self.enableLabelTool(self.disconnectTool, True)
        self.enableLabelTool(self.playTool, True)
        self.enableLabelTool(self.stopTool, False)
        self.enableLabelTool(self.pauseTool, False)
        self.sceneView.setShowDeleteMenu(True)
        self.combo.Enable()
        self.GetParent().menuFile.Enable(
            self.GetParent().menuLaunchWizard.GetId(), True)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuLoadModel.GetId(), True)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuSaveModel.GetId(), True)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuClearModel.GetId(), True)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuOpenProfile.GetId(), True)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuSaveProfile.GetId(), True)
        self.GetParent().menuFile.Enable(
            self.GetParent().menuResetProfile.GetId(), True)
        self.GetParent().menuFile.Enable(self.GetParent().menuExit.GetId(),
                                         True)
        self.GetParent().menuEdit.Enable(
            self.GetParent().menuPreferences.GetId(), True)
        self.GetParent().menuHelp.Enable(self.GetParent().menuWelcome.GetId(),
                                         True)
        panel = self.controls.panels['scan_parameters']
        section = panel.sections['scan_parameters']
        section.enable('scan_type')
        section.enable('use_laser')
        panel = self.controls.panels['rotative_platform']
        section = panel.sections['motor_scanning']
        section.enable('feed_rate_scanning')
        section.enable('acceleration_scanning')
        panel = self.controls.panels['image_acquisition']
        section = panel.sections['camera_scanning']
        if not sys.isDarwin():
            section.enable('framerate_scanning')
            section.enable('resolution_scanning')
        self.enableRestore(True)
        self.pointCloudTimer.Stop()
        self.videoView.setMilliseconds(10)
        self.gauge.Hide()
        self.scenePanel.Layout()
        self.Layout()

    def onPauseToolClicked(self, event):
        self.enableLabelTool(self.pauseTool, False)
        self.enableLabelTool(self.playTool, True)
        self.currentScan.pause()
        self.pointCloudTimer.Stop()

    def updateToolbarStatus(self, status):
        if status:
            if self.IsShown():
                self.videoView.play()
            self.enableLabelTool(self.playTool, True)
            self.enableLabelTool(self.stopTool, False)
            self.enableLabelTool(self.pauseTool, False)
            self.controls.enableContent()
        else:
            self.videoView.stop()
            self.enableLabelTool(self.playTool, False)
            self.enableLabelTool(self.stopTool, False)
            self.enableLabelTool(self.pauseTool, False)
            self.controls.disableContent()

    def updateProfileToAllControls(self):
        self.controls.updateProfile()
Ejemplo n.º 4
0
class CameraIntrinsicsMainPage(Page):
    def __init__(self,
                 parent,
                 afterCancelCallback=None,
                 afterCalibrationCallback=None):
        Page.__init__(self,
                      parent,
                      title=_("Camera Intrinsics"),
                      subTitle=_("Press space bar to perform captures"),
                      left=_("Cancel"),
                      right=_("Calibrate"),
                      buttonLeftCallback=self.onCancel,
                      buttonRightCallback=self.onCalibrate,
                      panelOrientation=wx.HORIZONTAL,
                      viewProgress=True)

        self.driver = Driver.Instance()
        self.cameraIntrinsics = calibration.CameraIntrinsics.Instance()

        self.afterCancelCallback = afterCancelCallback
        self.afterCalibrationCallback = afterCalibrationCallback

        #-- Video View
        self.videoView = VideoView(self._panel, self.getFrame, 50)
        self.videoView.SetBackgroundColour(wx.BLACK)

        #-- Image Grid Panel
        self.imageGridPanel = wx.Panel(self._panel)
        self.rows, self.columns = 2, 6
        self.panelGrid = []
        self.gridSizer = wx.GridSizer(self.rows, self.columns, 3, 3)
        for panel in xrange(self.rows * self.columns):
            self.panelGrid.append(ImageView(self.imageGridPanel))
            self.panelGrid[panel].Bind(wx.EVT_KEY_DOWN, self.onKeyPress)
            self.panelGrid[panel].SetBackgroundColour((221, 221, 221))
            self.panelGrid[panel].setImage(
                wx.Image(resources.getPathForImage("void.png")))
            self.gridSizer.Add(self.panelGrid[panel], 0, wx.ALL | wx.EXPAND)
        self.imageGridPanel.SetSizer(self.gridSizer)

        #-- Layout
        self.addToPanel(self.videoView, 1)
        self.addToPanel(self.imageGridPanel, 3)

        #-- Events
        self.Bind(wx.EVT_SHOW, self.onShow)
        self.videoView.Bind(wx.EVT_KEY_DOWN, self.onKeyPress)
        self.imageGridPanel.Bind(wx.EVT_KEY_DOWN, self.onKeyPress)

        self.videoView.SetFocus()
        self.Layout()

    def initialize(self):
        self._rightButton.Hide()
        self.subTitleText.SetLabel(_("Press space bar to perform captures"))
        self.currentGrid = 0
        self.gauge.SetValue(0)
        for panel in xrange(self.rows * self.columns):
            self.panelGrid[panel].SetBackgroundColour((221, 221, 221))
            self.panelGrid[panel].setImage(
                wx.Image(resources.getPathForImage("void.png")))

    def onShow(self, event):
        if event.GetShow():
            self.gauge.SetValue(0)
            self.videoView.play()
            calibration.CameraIntrinsics.Instance().clearImageStack()
            self.GetParent().Layout()
            self.Layout()
        else:
            try:
                self.initialize()
                self.videoView.stop()
            except:
                pass

    def getFrame(self):
        frame = self.driver.camera.captureImage(mirror=True)
        if frame is not None:
            retval, frame = self.cameraIntrinsics.detectChessboard(frame)
            if retval:
                self.videoView.SetBackgroundColour((45, 178, 0))
            else:
                self.videoView.SetBackgroundColour((217, 0, 0))
        return frame

    def onKeyPress(self, event):
        if event.GetKeyCode() == 32:  #-- spacebar
            if self.driver.isConnected:
                self.videoView.pause()
                frame = self.driver.camera.captureImage(mirror=False,
                                                        flush=True)
                if frame is not None:
                    retval, frame = self.cameraIntrinsics.detectChessboard(
                        frame, capture=True)
                    frame = cv2.flip(frame, 1)  #-- Mirror
                    self.addFrameToGrid(retval, frame)
                    self.gauge.SetValue(7 * self.currentGrid)
                self.videoView.play()

    def addFrameToGrid(self, retval, image):
        if self.currentGrid < (self.columns * self.rows):
            if retval:
                self.panelGrid[self.currentGrid].setFrame(image)
                self.panelGrid[self.currentGrid].SetBackgroundColour(
                    (45, 178, 0))
                self.currentGrid += 1
            else:
                self.panelGrid[self.currentGrid].setFrame(image)
                self.panelGrid[self.currentGrid].SetBackgroundColour(
                    (217, 0, 0))

        if self.currentGrid is (self.columns * self.rows):
            self.subTitleText.SetLabel(_("Press Calibrate to continue"))
            self.buttonRightCallback()
            # self._rightButton.Enable()

    def onCalibrate(self):
        self.cameraIntrinsics.setCallbacks(
            self.beforeCalibration,
            lambda p: wx.CallAfter(self.progressCalibration, p),
            lambda r: wx.CallAfter(self.afterCalibration, r))
        self.cameraIntrinsics.start()

    def beforeCalibration(self):
        self.videoView.pause()
        self._rightButton.Disable()
        self.gauge.SetValue(95)
        if not hasattr(self, 'waitCursor'):
            self.waitCursor = wx.BusyCursor()

    def progressCalibration(self, progress):
        self.gauge.SetValue(max(95, progress))

    def afterCalibration(self, result):
        self._rightButton.Enable()
        if self.afterCalibrationCallback is not None:
            self.afterCalibrationCallback(result)
        if hasattr(self, 'waitCursor'):
            del self.waitCursor

    def onCancel(self):
        boardUnplugCallback = self.driver.board.unplugCallback
        cameraUnplugCallback = self.driver.camera.unplugCallback
        self.driver.board.setUnplugCallback(None)
        self.driver.camera.setUnplugCallback(None)
        if not hasattr(self, 'waitCursor'):
            self.waitCursor = wx.BusyCursor()
        self.onCalibration = False
        self.cameraIntrinsics.cancel()
        if self.afterCancelCallback is not None:
            self.afterCancelCallback()
        del self.waitCursor
        self.driver.board.setUnplugCallback(boardUnplugCallback)
        self.driver.camera.setUnplugCallback(cameraUnplugCallback)
Ejemplo n.º 5
0
class CalibrationWorkbench(WorkbenchConnection):

    def __init__(self, parent):
        WorkbenchConnection.__init__(self, parent)

        self.calibrating = False

        self.load()

    def load(self):
        #-- Toolbar Configuration
        self.toolbar.Realize()

        self.scrollPanel = wx.lib.scrolledpanel.ScrolledPanel(self._panel, size=(290,-1))
        self.scrollPanel.SetupScrolling(scroll_x=False, scrollIntoView=False)
        self.scrollPanel.SetAutoLayout(1)

        self.controls = ExpandableControl(self.scrollPanel)

        self.videoView = VideoView(self._panel, self.getFrame, 10)
        self.videoView.SetBackgroundColour(wx.BLACK)

        #-- Add Scroll Panels
        self.controls.addPanel('camera_settings', CameraSettingsPanel(self.controls))
        self.controls.addPanel('pattern_settings', PatternSettingsPanel(self.controls))
        self.controls.addPanel('laser_settings', LaserSettingsPanel(self.controls))
        self.controls.addPanel('camera_intrinsics_panel', CameraIntrinsicsPanel(self.controls, buttonStartCallback=self.onCameraIntrinsicsStartCallback))
        self.controls.addPanel('laser_triangulation_panel', LaserTriangulationPanel(self.controls, buttonStartCallback=self.onLaserTriangulationStartCallback))
        self.controls.addPanel('platform_extrinsics_panel', PlatformExtrinsicsPanel(self.controls, buttonStartCallback=self.onPlatformExtrinsicsStartCallback))

        #-- Add Calibration Pages
        self.cameraIntrinsicsMainPage = CameraIntrinsicsMainPage(self._panel,
                                                                 afterCancelCallback=self.onCancelCallback,
                                                                 afterCalibrationCallback=self.onCameraIntrinsicsAfterCalibrationCallback)

        self.cameraIntrinsicsResultPage = CameraIntrinsicsResultPage(self._panel,
                                                                     buttonRejectCallback=self.onCancelCallback,
                                                                     buttonAcceptCallback=self.onCameraIntrinsicsAcceptCallback)

        self.laserTriangulationMainPage = LaserTriangulationMainPage(self._panel,
                                                                     afterCancelCallback=self.onCancelCallback,
                                                                     afterCalibrationCallback=self.onLaserTriangulationAfterCalibrationCallback)

        self.laserTriangulationResultPage = LaserTriangulationResultPage(self._panel,
                                                                         buttonRejectCallback=self.onCancelCallback,
                                                                         buttonAcceptCallback=self.onLaserTriangulationAcceptCallback)

        self.platformExtrinsicsMainPage = PlatformExtrinsicsMainPage(self._panel,
                                                                     afterCancelCallback=self.onCancelCallback,
                                                                     afterCalibrationCallback=self.onPlatformExtrinsicsAfterCalibrationCallback)

        self.platformExtrinsicsResultPage = PlatformExtrinsicsResultPage(self._panel,
                                                                         buttonRejectCallback=self.onCancelCallback,
                                                                         buttonAcceptCallback=self.onPlatformExtrinsicsAcceptCallback)

        self.cameraIntrinsicsMainPage.Hide()
        self.cameraIntrinsicsResultPage.Hide()
        self.laserTriangulationMainPage.Hide()
        self.laserTriangulationResultPage.Hide()
        self.platformExtrinsicsMainPage.Hide()
        self.platformExtrinsicsResultPage.Hide()

        #-- Layout
        vsbox = wx.BoxSizer(wx.VERTICAL)
        vsbox.Add(self.controls, 0, wx.ALL|wx.EXPAND, 0)
        self.scrollPanel.SetSizer(vsbox)
        vsbox.Fit(self.scrollPanel)

        self.addToPanel(self.scrollPanel, 0)
        self.addToPanel(self.videoView, 1)

        self.addToPanel(self.cameraIntrinsicsMainPage, 1)
        self.addToPanel(self.cameraIntrinsicsResultPage, 1)
        self.addToPanel(self.laserTriangulationMainPage, 1)
        self.addToPanel(self.laserTriangulationResultPage, 1)
        self.addToPanel(self.platformExtrinsicsMainPage, 1)
        self.addToPanel(self.platformExtrinsicsResultPage, 1)

        self.updateCallbacks()
        self.Layout()

    def updateCallbacks(self):
        self.controls.updateCallbacks()

    def getFrame(self):
        frame = Driver.Instance().camera.captureImage()
        self.cameraIntrinsics = CameraIntrinsics.Instance()
        if frame is not None:
            retval, frame = self.cameraIntrinsics.detectChessboard(frame)
        return frame

    def enableMenus(self, value):
        main = self.GetParent()
        main.menuFile.Enable(main.menuLaunchWizard.GetId(), value)
        main.menuFile.Enable(main.menuOpenProfile.GetId(), value)
        main.menuFile.Enable(main.menuSaveProfile.GetId(), value)
        main.menuFile.Enable(main.menuResetProfile.GetId(), value)
        main.menuFile.Enable(main.menuExit.GetId(), value)
        main.menuEdit.Enable(main.menuPreferences.GetId(), value)
        main.menuHelp.Enable(main.menuWelcome.GetId(), value)
        main.Layout()

    def onCameraIntrinsicsStartCallback(self):
        self.calibrating = True
        self.enableLabelTool(self.disconnectTool, False)
        self.controls.setExpandable(False)
        self.controls.panels['camera_intrinsics_panel'].buttonsPanel.Disable()
        self.combo.Disable()
        self.enableMenus(False)
        self.videoView.stop()
        self.videoView.Hide()
        self.cameraIntrinsicsMainPage.Show()
        self.cameraIntrinsicsMainPage.videoView.SetFocus()
        self.Layout()

    def onLaserTriangulationStartCallback(self):
        self.calibrating = True
        self.enableLabelTool(self.disconnectTool, False)
        self.controls.setExpandable(False)
        self.controls.panels['laser_triangulation_panel'].buttonsPanel.Disable()
        self.combo.Disable()
        self.enableMenus(False)
        self.videoView.stop()
        self.videoView.Hide()
        self.laserTriangulationMainPage.Show()
        self.Layout()

    def onPlatformExtrinsicsStartCallback(self):
        if profile.getProfileSettingFloat('pattern_distance') == 0:
            PatternDistanceWindow(self)
            self.updateProfileToAllControls()
        else:
            self.calibrating = True
            self.enableLabelTool(self.disconnectTool, False)
            self.controls.setExpandable(False)
            self.controls.panels['platform_extrinsics_panel'].buttonsPanel.Disable()
            self.combo.Disable()
            self.enableMenus(False)
            self.videoView.stop()
            self.videoView.Hide()
            self.platformExtrinsicsMainPage.Show()
            self.Layout()

    def onCancelCallback(self):
        self.calibrating = False
        self.enableLabelTool(self.disconnectTool, True)
        self.controls.setExpandable(True)
        self.controls.panels['camera_intrinsics_panel'].buttonsPanel.Enable()
        self.controls.panels['laser_triangulation_panel'].buttonsPanel.Enable()
        self.controls.panels['platform_extrinsics_panel'].buttonsPanel.Enable()
        self.controls.updateProfile()
        self.combo.Enable()
        self.enableMenus(True)
        self.cameraIntrinsicsMainPage.Hide()
        self.cameraIntrinsicsResultPage.Hide()
        self.laserTriangulationMainPage.Hide()
        self.laserTriangulationResultPage.Hide()
        self.platformExtrinsicsMainPage.Hide()
        self.platformExtrinsicsResultPage.Hide()
        self.videoView.play()
        self.videoView.Show()
        self.Layout()

    def onCameraIntrinsicsAfterCalibrationCallback(self, result):
        self.cameraIntrinsicsResultPage.processCalibration(result)
        if result[0]:
            self.cameraIntrinsicsMainPage.Hide()
            self.cameraIntrinsicsResultPage.Show()
        else:
            self.cameraIntrinsicsMainPage.initialize()
        self.Layout()

    def onCameraIntrinsicsAcceptCallback(self):
        self.videoView.play()
        self.calibrating = False
        self.enableLabelTool(self.disconnectTool, True)
        self.controls.setExpandable(True)
        self.controls.panels['camera_intrinsics_panel'].buttonsPanel.Enable()
        self.controls.panels['camera_intrinsics_panel'].updateAllControlsToProfile()
        self.combo.Enable()
        self.enableMenus(True)
        self.cameraIntrinsicsResultPage.Hide()
        self.videoView.Show()
        self.Layout()

    def onLaserTriangulationAfterCalibrationCallback(self, result):
        self.laserTriangulationResultPage.processCalibration(result)
        if result[0]:
            self.laserTriangulationMainPage.Hide()
            self.laserTriangulationResultPage.Show()
        else:
            self.laserTriangulationMainPage.initialize()
        self.Layout()

    def onLaserTriangulationAcceptCallback(self):
        self.videoView.play()
        self.calibrating = False
        self.enableLabelTool(self.disconnectTool, True)
        self.controls.setExpandable(True)
        self.controls.panels['laser_triangulation_panel'].buttonsPanel.Enable()
        self.controls.panels['laser_triangulation_panel'].updateAllControlsToProfile()
        self.combo.Enable()
        self.enableMenus(True)
        self.laserTriangulationResultPage.Hide()
        self.videoView.Show()
        self.Layout()

    def onPlatformExtrinsicsAfterCalibrationCallback(self, result):
        self.platformExtrinsicsResultPage.processCalibration(result)
        if result[0]:
            self.platformExtrinsicsMainPage.Hide()
            self.platformExtrinsicsResultPage.Show()
        else:
            self.platformExtrinsicsMainPage.initialize()
        self.Layout()

    def onPlatformExtrinsicsAcceptCallback(self):
        self.videoView.play()
        self.calibrating = False
        self.enableLabelTool(self.disconnectTool, True)
        self.controls.setExpandable(True)
        self.controls.panels['platform_extrinsics_panel'].buttonsPanel.Enable()
        self.controls.panels['platform_extrinsics_panel'].updateAllControlsToProfile()
        self.combo.Enable()
        self.enableMenus(True)
        self.platformExtrinsicsResultPage.Hide()
        self.videoView.Show()
        self.Layout()

    def updateToolbarStatus(self, status):
        if status:
            if self.IsShown():
                self.videoView.play()
            self.controls.panels['camera_intrinsics_panel'].buttonsPanel.Enable()
            self.controls.panels['laser_triangulation_panel'].buttonsPanel.Enable()
            self.controls.panels['platform_extrinsics_panel'].buttonsPanel.Enable()
            self.controls.enableContent()
        else:
            self.videoView.stop()
            self.controls.panels['camera_intrinsics_panel'].buttonsPanel.Disable()
            self.controls.panels['laser_triangulation_panel'].buttonsPanel.Disable()
            self.controls.panels['platform_extrinsics_panel'].buttonsPanel.Disable()
            self.controls.disableContent()
            self.calibrating = False
            self.combo.Enable()
            self.controls.setExpandable(True)
            self.cameraIntrinsicsMainPage.Hide()
            self.cameraIntrinsicsResultPage.Hide()
            self.laserTriangulationMainPage.Hide()
            self.laserTriangulationResultPage.Hide()
            self.platformExtrinsicsMainPage.Hide()
            self.platformExtrinsicsResultPage.Hide()
            self.videoView.Show()

    def updateProfileToAllControls(self):
        self.controls.updateProfile()