def loadMeshes(self, step, pBar):
        oo = self._orderObject()
        so = self._shapeObject()
        if oo is None or so is None:
            QMessageBox.warning(self, "Get objects",
                                "Must have order and shape loaded")

        if self._orderMesh is None:
            orderVerts = getVerts(oo)
            orderFaces = getFaces(oo)
            orderUVs, orderUVFaces = getUVs(oo)
            pBar.setLabelText("Loading Order")
            QApplication.processEvents()
            self._orderMesh = Mesh(orderVerts,
                                   orderFaces,
                                   uvs=orderUVs,
                                   uvFaces=orderUVFaces)
            pBar.setValue(pBar.value() + step)

        if self._shapeMesh is None:
            shapeVerts = getVerts(so)
            shapeFaces = getFaces(so)
            shapeUVs, shapeUVFaces = getUVs(so)
            pBar.setLabelText("Loading Shape")
            QApplication.processEvents()
            self._shapeMesh = Mesh(shapeVerts,
                                   shapeFaces,
                                   uvs=shapeUVs,
                                   uvFaces=shapeUVFaces)
            pBar.setValue(pBar.value() + step)
    def doUnsub(self):
        obj = self._getObject()
        if obj is None:
            QMessageBox.warning(self, "Get objects",
                                "Must have an object loaded first")
            return
        pBar = QProgressDialog(self)
        pBar.setLabelText("Unsubdividing")
        pBar.setValue(0)
        pBar.setMaximum(100)

        hints = self._getHints()
        verts = getVerts(obj)
        faces = getFaces(obj)
        uvs, uvFaces = getUVs(obj)
        if self.uiSelectEdgesRDO.isChecked():
            centers = getCenters(faces, pBar=pBar)
            selectAdjacentEdges(obj, centers)
        else:

            newName = getObjectName(obj)
            newName = newName + "_UNSUB"
            repositionVerts = self.uiUpdatePositionsRDO.isChecked()
            pinBorders = self.uiPinBordersCHK.isChecked()
            rFaces, rVerts, rUVFaces, rUVs = unSubdivide(
                faces,
                verts,
                uvFaces,
                uvs,
                hints=hints,
                repositionVerts=repositionVerts,
                pinBorders=pinBorders,
                pBar=pBar)
            createRawObject(newName, rFaces, rVerts, rUVFaces, rUVs)
 def getVertsFromSelection(self):
     obj = self._getObject()
     if obj is None:
         QMessageBox.warning(self, "Get objects",
                             "Must have an object loaded first")
         return
     sel = getVertSelection(obj)
     val = ','.join(map(str, sel)) if sel else ''
     self.uiManualHintsLINE.setText(val)
    def guess(self):
        oo = self._orderObject()
        so = self._shapeObject()
        if oo is None or so is None:
            QMessageBox.warning(self, "Get objects",
                                "Must have order and shape loaded")
            return

        pBar = QProgressDialog(self)
        pBar.show()
        pBar.setValue(0)
        self.loadMeshes(33, pBar)

        pBar.setLabelText("Partitioning islands")
        QApplication.processEvents()
        self._matchGen = matchGenerator(self._orderMesh,
                                        self._shapeMesh,
                                        skipMismatchedIslands=True)
        self.uiGuessNextBTN.show()

        self.guessNext()
        pBar.close()
    def guessNext(self):
        try:
            sm = next(self._matchGen)
        except StopIteration:
            self._matchGen = None
            self.uiGuessNextBTN.hide()
            QMessageBox.warning(self, "No more guesses", "No more guesses")
            return

        for _ in range(self.uiPairTABLE.rowCount()):
            self.uiPairTABLE.removeRow(0)

        for i, pair in enumerate(sm):
            self.uiPairTABLE.insertRow(i)

            orderObj = QTableWidgetItem()
            shapeObj = QTableWidgetItem()

            self.uiPairTABLE.setItem(i, 0, orderObj)
            self.uiPairTABLE.setItem(i, 1, shapeObj)

            orderObj.setData(Qt.EditRole, pair[0])
            shapeObj.setData(Qt.EditRole, pair[1])
    def crawl(self):
        pairs = None
        if self.uiAdvancedGRP.isChecked():
            try:
                pairs = self.getPairData()
            except ValueError:
                pass
            if not pairs:
                QMessageBox.warning(self, "Could not get Vert pairs",
                                    "All vert pairs must be fully defined")
                return

        pBar = QProgressDialog(self)
        pBar.show()
        pBar.setLabelText("Crawling")
        pBar.setValue(0)
        QApplication.setOverrideCursor(Qt.WaitCursor)
        QApplication.processEvents()

        self.loadMeshes(33, pBar)

        skipMismatchedIslands = False  # someday figure out how to make this work

        match = None
        title = 'No Match Found'
        msg = 'No Match Found'

        QApplication.processEvents()
        try:
            if self.uiAdvancedGRP.isChecked():
                match = self._crawlAdvanced(pairs, self._orderMesh,
                                            self._shapeMesh, pBar)
            else:
                match = autoCrawlMeshes(
                    self._orderMesh,
                    self._shapeMesh,
                    skipMismatchedIslands=skipMismatchedIslands,
                    pBar=pBar)
        except TopologyMismatch as m:
            title = 'Topology Mismatch'
            msg = str(m) or title
        except IslandMismatch as m:
            title = 'Island Mismatch'
            msg = str(m) or title
        finally:
            QApplication.restoreOverrideCursor()

        if not match:
            pBar.close()
            QMessageBox.warning(self, title, msg)
            return

        pBar.setValue(0)
        pBar.setLabelText("Building output")
        allMatch = []
        for m in match:
            allMatch.extend(m)
        allMatch = sorted(allMatch)

        orderObj = self._orderObject()
        shapeObj = self._shapeObject()
        shapeVerts = getVerts(shapeObj)
        orderVerts = getVerts(orderObj)

        nn = str(self.uiOutputLINE.text())
        fixitObject = cloneObject(orderObj, nn)
        freezeObject(fixitObject)

        self.lastMatch = allMatch

        for oIdx, sIdx in allMatch:
            orderVerts[oIdx] = shapeVerts[sIdx]
        setAllVerts(fixitObject, orderVerts)

        self.uiExportBTN.show()
        pBar.close()
    def _crawlAdvanced(self, pairs, orderMesh, shapeMesh, pBar):
        ois = [frozenset(i) for i in partitionIslands(orderMesh)]
        sis = [frozenset(i) for i in partitionIslands(shapeMesh)]
        oVals, sVals = zip(*pairs)
        oCheck, sCheck = {}, {}
        oOnes, sOnes = [], []
        orderObj = self.uiOrderLINE.text()
        shapeObj = self.uiShapeLINE.text()

        for isles, vals, check in ((ois, oVals, oCheck), (sis, sVals, sCheck)):
            for i in isles:
                for v in vals:
                    if v in i:
                        check.setdefault(i, []).append(v)

        for check, obj, ones in ((oCheck, orderObj, oOnes), (sCheck, shapeObj,
                                                             sOnes)):
            for val in check.values():
                if len(val) not in [1, 3]:
                    QMessageBox.warning(
                        self, "Selection error",
                        "Must have exactly 1 or 3 verts on an island. Found on {0} {1}: {2}"
                        .format(obj, len(val), val))
                    raise TopologyMismatch()
                elif len(val) == 1:
                    ones.append(val[0])

        vertNum = len(orderMesh.vertArray)
        if not oOnes and not sOnes:
            matches = [
                matchByTopology(orderMesh,
                                shapeMesh,
                                pairs,
                                vertNum=vertNum,
                                pBar=pBar)
            ]
        else:
            matches = []
            pairs = [tuple(i) for i in pairs]
            buildPairs = []
            for overts in oCheck.itervalues():
                for sverts in sCheck.itervalues():
                    zPairs = zip(overts, sverts)
                    if all([p in pairs for p in zPairs]):
                        buildPairs.append(zPairs)

            for zPairs in buildPairs:
                if len(zPairs) == 1:
                    for starPairs in starMatchGenerator(
                            orderMesh, shapeMesh, zPairs[0][0], zPairs[0][1]):
                        try:
                            match = matchByTopology(orderMesh,
                                                    shapeMesh,
                                                    starPairs,
                                                    vertNum=vertNum,
                                                    pBar=pBar)
                            break
                        except TopologyMismatch:
                            pass
                    else:
                        raise TopologyMismatch(
                            "Mismatch found in single-vert pairing: {0}".
                            format(zPairs[0]))
                else:
                    match = matchByTopology(orderMesh,
                                            shapeMesh,
                                            zPairs,
                                            vertNum=vertNum,
                                            pBar=pBar)
                matches.append(match)
        return matches