Ejemplo n.º 1
0
def testNewSlider():
    simp = Simplex.buildEmptySystem(None, 'Face')
    model = SimplexModel(simp, None)
    smodel = SliderModel(model)
    fmodel = SliderFilterModel(smodel)
    fmodel.doFilter = True

    app = QApplication(sys.argv)

    topWid = QWidget()
    lay = QVBoxLayout(topWid)

    tv = QTreeView(topWid)
    btn = QPushButton('NEW', topWid)
    lay.addWidget(tv)
    lay.addWidget(btn)

    tv.setModel(fmodel)
    expandRecursive(tv, fmodel)
    topWid.show()

    newSlider = lambda: Slider.createSlider('NewSlider', simp)
    btn.clicked.connect(newSlider)

    sys.exit(app.exec_())
Ejemplo n.º 2
0
def testDeleteBase(path):
    simp = buildDummySystem(path)
    model = SimplexModel(simp, None)
    model = SliderModel(model)
    model = SliderFilterModel(model)

    app = QApplication(sys.argv)

    topWid = QWidget()
    lay = QVBoxLayout(topWid)

    tv = QTreeView(topWid)

    btn = QPushButton('DELETE', topWid)
    lay.addWidget(tv)
    lay.addWidget(btn)

    tv.setModel(model)
    topWid.show()

    expandRecursive(tv, model)
    tv.resizeColumnToContents(0)

    def delCallback():
        sel = tv.selectedIndexes()
        sel = [i for i in sel if i.column() == 0]
        items = [s.model().itemFromIndex(s) for s in sel]
        items[0].delete()
        tv.model().invalidateFilter()

    btn.clicked.connect(delCallback)

    sys.exit(app.exec_())
Ejemplo n.º 3
0
def _writeSimplex(oarch, name, jsString, faces, counts, newShapes, pBar=None):
	''' Separate the writer from oarch creation so garbage
	collection *hopefully* works as expected
	'''
	par = OXform(oarch.getTop(), name)
	props = par.getSchema().getUserProperties()
	prop = OStringProperty(props, "simplex")
	prop.setValue(str(jsString))
	abcMesh = OPolyMesh(par, name)
	schema = abcMesh.getSchema()

	if pBar is not None:
		pBar.setLabelText('Writing Corrected Simplex')
		pBar.setMaximum(len(newShapes))

	for i, newShape in enumerate(newShapes):
		if pBar is not None:
			pBar.setValue(i)
			QApplication.processEvents()
		else:
			print "Writing {0: 3d} of {1}\r".format(i, len(newShapes)),

		verts = mkSampleVertexPoints(newShape)
		abcSample = OPolyMeshSchemaSample(verts, faces, counts)
		schema.set(abcSample)
	if pBar is None:
		print "Writing {0: 3d} of {1}".format(len(newShapes), len(newShapes))
Ejemplo n.º 4
0
def outputCorrectiveReferences(outNames, outRefs, simplex, mesh, poses, sliders, pBar=None):
	'''
	Output the proper files for an external corrective application

	Arguments:
		outNames: The filepath for the output shape and reference indices
		outRefs: The filepath for the deformation references
		simplex: A simplex system
		mesh: The mesh object to deform
		poses: Lists of parameter/value pairs. Each list corresponds to a slider
		sliders: The simplex sliders that correspond to the poses
	'''
	refs, shapes, refIdxs = buildCorrectiveReferences(mesh, simplex, poses, sliders, pBar)

	if pBar is not None:
		pBar.setLabelText('Writing Names')
		QApplication.processEvents()
	nameWrite = ['{};{}'.format(s.name, r) for s, r, in zip(shapes, refIdxs)]
	with open(outNames, 'w') as f:
		f.write('\n'.join(nameWrite))

	if pBar is not None:
		pBar.setLabelText('Writing References')
		QApplication.processEvents()
	refs.dump(outRefs)
Ejemplo n.º 5
0
def readAndApplyCorrectives(inPath, namePath, refPath, outPath, pBar=None):
	'''
	Read the provided files, apply the correctives, then output a new file

	Arguments:
		inPath: The input .smpx file
		namePath: A file correlating the shape names, and the reference
			indices. Separated by ; with one entry per line
		refPath: The reference matrices per point of deformation.
			Created by npArray.dump(refPath)
		outPath: The output .smpx filepath
	'''

	if pBar is not None:
		pBar.setLabelText("Reading reference data")
		QApplication.processEvents()

	jsString, simplex, solver, allShapePts, restPts = loadSimplex(inPath)
	with open(namePath, 'r') as f:
		nr = f.read()
	nr = [i.split(';') for i in nr.split('\n') if i]
	names, refIdxs = zip(*nr)
	refIdxs = map(int, refIdxs)
	refs = np.load(refPath)
	shapeByName = {i.name: i for i in simplex.shapes}
	shapes = [shapeByName[n] for n in names]
	newPts = applyCorrectives(simplex, allShapePts, restPts, solver, shapes, refIdxs, refs, pBar)
	writeSimplex(inPath, outPath, newPts, pBar=pBar)
	print "DONE"
Ejemplo n.º 6
0
	def shapeMatchIndexes(self, indexes):
		# make a dict of name:object
		sel = DCC.getSelectedObjects()
		if not sel:
			return
		mesh = sel[0]

		pairs = coerceIndexToChildType(indexes, ProgPair)
		pairs = [i.model().itemFromIndex(i) for i in pairs]
		pairs = makeUnique([i for i in pairs if not i.shape.isRest])

		# Set up the progress bar
		pBar = QProgressDialog("Matching Shapes", "Cancel", 0, 100, self)
		pBar.setMaximum(len(pairs))

		# Do the extractions
		for pair in pairs:
			c = pair.prog.controller
			c.connectShape(pair.shape, mesh=mesh)

			# ProgressBar
			pBar.setValue(pBar.value() + 1)
			pBar.setLabelText("Matching:\n{0}".format(pair.shape.name))
			QApplication.processEvents()
			if pBar.wasCanceled():
				return

		pBar.close()
Ejemplo n.º 7
0
	def shapeIndexExtract(self, indexes, live=None):
		# Create meshes that are possibly live-connected to the shapes
		if live is None:
			live = self.uiLiveShapeConnectionACT.isChecked()

		pairs = coerceIndexToChildType(indexes, ProgPair)
		pairs = [i.model().itemFromIndex(i) for i in pairs]
		pairs = makeUnique([i for i in pairs if not i.shape.isRest])
		pairs.sort(key=lambda x: naturalSortKey(x.shape.name))

		# Set up the progress bar
		pBar = QProgressDialog("Extracting Shapes", "Cancel", 0, 100, self)
		pBar.setMaximum(len(pairs))

		# Do the extractions
		offset = 10
		for pair in pairs:
			c = pair.prog.controller
			c.extractShape(pair.shape, live=live, offset=offset)
			offset += 5

			# ProgressBar
			pBar.setValue(pBar.value() + 1)
			pBar.setLabelText("Extracting:\n{0}".format(pair.shape.name))
			QApplication.processEvents()
			if pBar.wasCanceled():
				return

		pBar.close()
Ejemplo n.º 8
0
	def exportAbc(self, dccMesh, abcMesh, js, world=False, pBar=None):
		# export the data to alembic
		if dccMesh is None:
			dccMesh = self.mesh

		shapeDict = {i.name:i for i in self.simplex.shapes}

		shapeNames = js['shapes']
		if js['encodingVersion'] > 1:
			shapeNames = [i['name'] for i in shapeNames]
		shapes = [shapeDict[i] for i in shapeNames]

		schema = abcMesh.getSchema()

		if pBar is not None:
			pBar.show()
			pBar.setMaximum(len(shapes))
			spacerName = '_' * max(map(len, shapeNames))
			pBar.setLabelText('Exporting:\n{0}'.format(spacerName))
			QApplication.processEvents()

		for i, shape in enumerate(shapes):
			if pBar is not None:
				pBar.setLabelText('Exporting:\n{0}'.format(shape.name))
				pBar.setValue(i)
				QApplication.processEvents()
				if pBar.wasCanceled():
					return
			verts = mkSampleVertexPoints(self._shapes[shape.name])
			if self._uvs is not None:
				# Alembic doesn't allow for self._uvs=None for some reason
				abcSample = OPolyMeshSchemaSample(verts, self._faces, self._counts, self._uvs)
			else:
				abcSample = OPolyMeshSchemaSample(verts, self._faces, self._counts)
			schema.set(abcSample)
Ejemplo n.º 9
0
    def startDrag(self, o, e):
        if self._dragStart is None:
            self._dragStart = e.pos()
            dtop = QApplication.desktop()
            sn = dtop.screenNumber(o.mapToGlobal(e.pos()))
            self._screen = dtop.availableGeometry(sn)

        if abs(e.x() - self._dragStart.x()) > self.startSensitivity:
            self._dragType = self.DRAG_HORIZONTAL
        elif abs(e.y() - self._dragStart.y()) > self.startSensitivity:
            self._dragType = self.DRAG_VERTICAL

        if self._dragType:
            self._leftover = 0
            self._lastPos = e.pos()
            self._firstDrag = True

            self.dragPressed.emit()
            self.doOverrideCursor()

            if self.isSpinbox:
                if e.buttons() & self.dragButton:
                    # Send mouseRelease to spin buttons when dragging
                    # otherwise the spinbox will keep ticking.  @longClickFix
                    # There's gotta be a better way to do this :-/
                    mouseup = QMouseEvent(QEvent.MouseButtonRelease, e.pos(),
                                          self.dragButton, e.buttons(),
                                          e.modifiers())
                    QApplication.sendEvent(o, mouseup)
Ejemplo n.º 10
0
def testSliderTreeDisplay(smpxPath):
    simp = Simplex.buildSystemFromSmpx(smpxPath)

    redAttrs = set([
        u'lowerLipDepressor_X', u'stretcher_X', u'platysmaFlex_X',
        u'cheekRaiser_X', u'jawOpen', u'lidTightener_X', u'outerBrowRaiser_X',
        u'eyesClosed_X', u'cornerPuller_X', u'noseWrinkler_X', u'lipsBlow_X',
        u'cornerDepressor_X', u'funneler', u'browLateral_X',
        u'innerBrowRaiser_X', u'upperLipRaiser_X', u'chinRaiser',
        u'cheek_SuckBlow_X', u'pucker', u'eyeGaze_DownUp_X',
        u'eyeGaze_RightLeft_X', u'upperLidTweak_X', u'lowerLidTweak_X'
    ])
    greenAttrs = set([
        u'nasolabialDeepener_X', u'neckStretcher_X', u'lipsPressed_T',
        u'lipsPressed_B', u'throatCompress', u'lipsRolled_InOut_B',
        u'lipsRolled_InOut_T', u'sharpCornerPuller_X', u'dimpler_X',
        u'eyeBlink_X', u'scalpSlide_BackFwd', u'browDown_X',
        u'mouthSwing_RightLeft', u'sternoFlex_X', u'throatOpen'
    ])
    blueAttrs = set([
        u'adamsApple', u'noseSwing_RightLeft', u'nostrilCompress_X',
        u'jawThrust_BackFwd', u'eyesWide_X', u'lipsVerticalT_X',
        u'lipsVerticalB_X', u'earPull_X', u'lipsTighten_T', u'lipsTighten_B',
        u'lipsCompress_T', u'lipsCompress_B', u'lipsShift_RightLeft_B',
        u'lipsShift_RightLeft_T', u'lipsNarrowT_X', u'lipsNarrowB_X',
        u'jawSwing_RightLeft', u'nostril_SuckFlare_X', u'lipsCorner_DownUp_X',
        u'jawClench'
    ])
    greyAttrs = set([u'lipsTogether'])

    app = QApplication(sys.argv)
    #tv = ChannelTree()
    tv = QTreeView()
    model = ChannelTreeModel(simp, None)
    #delegate = ChannelBoxDelegate()

    #slideFilter = SlideFilter(tv.viewport())
    #slideFilter.slideButton = Qt.LeftButton
    #tv.viewport().installEventFilter(slideFilter)
    #slideFilter.slidePressed.connect(tv.slideStart)
    #slideFilter.slideReleased.connect(tv.slideStop)
    #slideFilter.slideTick.connect(tv.slideTick)

    #for g in simp.sliderGroups:
    #for item in g.items:
    #if item.name in redAttrs:
    #item.color = QColor(178, 103, 103)
    #elif item.name in greenAttrs:
    #item.color = QColor(90, 161, 27)
    #elif item.name in blueAttrs:
    #item.color = QColor(103, 141, 178)
    #elif item.name in greyAttrs:
    #item.color = QColor(130, 130, 130)

    tv.setModel(model)
    #tv.setItemDelegate(delegate)

    tv.show()
    sys.exit(app.exec_())
Ejemplo n.º 11
0
def exportUnsub(inPath, outPath, newFaces, kept, shapePrefix=None, pBar=None):
    ''' Export the unsubdivided simplex '''
    iarch = IArchive(str(inPath))  # because alembic hates unicode
    top = iarch.getTop()
    ixfo = IXform(top, top.children[0].getName())

    iprops = ixfo.getSchema().getUserProperties()
    iprop = iprops.getProperty("simplex")
    jsString = iprop.getValue()

    if shapePrefix is not None:
        d = json.loads(jsString)
        if d['encodingVersion'] > 1:
            for shape in d['shapes']:
                shape['name'] = shapePrefix + shape['name']
        else:
            d['shapes'] = [shapePrefix + i for i in d['shapes']]
        jsString = json.dumps(d)

    imesh = IPolyMesh(ixfo, ixfo.children[0].getName())

    verts = getSampleArray(imesh)
    verts = verts[:, kept]

    indices = []
    counts = []
    for f in newFaces:
        indices.extend(f)
        counts.append(len(f))

    abcCounts = mkArray(IntArray, counts)
    abcIndices = mkArray(IntArray, indices)

    # `False` for HDF5 `True` for Ogawa
    oarch = OArchive(str(outPath), False)
    oxfo = OXform(oarch.getTop(), ixfo.getName())
    oprops = oxfo.getSchema().getUserProperties()
    oprop = OStringProperty(oprops, "simplex")
    oprop.setValue(str(jsString))
    omesh = OPolyMesh(oxfo, imesh.getName())
    osch = omesh.getSchema()

    if pBar is not None:
        pBar.setValue(0)
        pBar.setMaximum(len(verts))
        pBar.setLabelText("Exporting Unsubdivided Shapes")
        QApplication.processEvents()

    for i, v in enumerate(verts):
        if pBar is not None:
            pBar.setValue(i)
            QApplication.processEvents()
        else:
            print "Exporting Unsubdivided Shape {0: <4}\r".format(i + 1),
        sample = OPolyMeshSchemaSample(mkSampleVertexPoints(v), abcIndices,
                                       abcCounts)
        osch.set(sample)
    if pBar is None:
        print "Exporting Unsubdivided Shape {0: <4}".format(len(verts))
Ejemplo n.º 12
0
def showTree(model):
    app = QApplication(sys.argv)
    tv = QTreeView()
    tv.setModel(model)
    expandRecursive(tv, model)
    tv.resizeColumnToContents(0)
    tv.show()
    sys.exit(app.exec_())
Ejemplo n.º 13
0
def _test():
	app = QApplication(sys.argv)
	path = r'C:\Users\tfox\Documents\GitHub\Simplex\scripts\SimplexUI\build\HeadMaleStandard_High_Unsplit.smpx'
	d = SimplexDialog()
	newSystem = Simplex.buildSystemFromSmpx(path, d.getCurrentObject(), sliderMul=1.0)
	d.setSystem(newSystem)

	d.show()
	sys.exit(app.exec_())
Ejemplo n.º 14
0
def buildFullShapes(simplex, shapeObjs, shapes, solver, restPts, pBar=None):
	'''
	Given shape inputs, build the full output shape from the deltas
	We use shapes here because a shape implies both the progression
	and the value of the inputs (with a little figuring)
	'''
	###########################################
	# Manipulate all the input lists and caches
	indexBySlider = {s: i for i, s in enumerate(simplex.sliders)}
	indexByShape = {s: i for i, s in enumerate(simplex.shapes)}
	floaters = set(simplex.getFloatingShapes())
	floatIdxs = set([indexByShape[s] for s in floaters])

	shapeDict = {}
	for item in itertools.chain(simplex.sliders, simplex.combos):
		for pair in item.prog.pairs:
			if not pair.shape.isRest:
				shapeDict[pair.shape] = (item, pair.value)

	######################
	# Actually do the work
	vecByShape = {} # store this for later use
	ptsByShape = {}

	if pBar is not None:
		pBar.setMaximum(len(shapeObjs))
		pBar.setValue(0)
		QApplication.processEvents()

	flatShapes = shapes.reshape((len(shapes), -1))
	for i, shape in enumerate(shapeObjs):
		if pBar is not None:
			pBar.setValue(i)
			QApplication.processEvents()
		else:
			print "Building {0} of {1}\r".format(i+1, len(shapeObjs)),

		item, value = shapeDict[shape]
		inVec = _buildSolverInputs(simplex, item, value, indexBySlider)
		outVec = solver.solve(inVec)
		if shape not in floaters:
			for fi in floatIdxs:
				outVec[fi] = 0.0
		outVec = np.array(outVec)
		outVec[np.where(np.isclose(outVec, 0))] = 0
		outVec[np.where(np.isclose(outVec, 1))] = 1
		vecByShape[shape] = outVec
		pts = np.dot(outVec, flatShapes)
		pts = pts.reshape((-1, 3))
		ptsByShape[shape] = pts + restPts
	if pBar is None:
		print

	return ptsByShape, vecByShape
Ejemplo n.º 15
0
    def toggleTree(self, index, expand):
        ''' Expand or collapse an entire sub-tree of an index '''
        # Separate function to deal with filtering capability
        if not index.isValid():
            return

        model = self.model()
        mods = QApplication.keyboardModifiers()
        thing = model.itemFromIndex(index)
        thing.expanded[id(self)] = expand

        if mods & (self.expandModifier | self.depthModifier):
            queue = [index]
            self.blockSignals(True)
            try:
                while queue:
                    idx = queue.pop()
                    thing = model.itemFromIndex(idx)
                    thing.expanded[id(self)] = expand
                    self.setExpanded(idx, expand)
                    if mods & self.depthModifier:
                        if isinstance(thing, Group):
                            continue
                    for i in xrange(model.rowCount(idx)):
                        child = model.index(i, 0, idx)
                        if child and child.isValid():
                            queue.append(child)
            finally:
                self.blockSignals(False)

        if expand:
            self.resizeColumns()
Ejemplo n.º 16
0
	def importSystemFromFile(self):
		if self._currentObject is None:
			impTypes = ['smpx']
		else:
			impTypes = ['smpx', 'json']

		if blurdev is None:
			pref = QSettings("Blur", "Simplex3")
			defaultPath = str(toPyObject(pref.value('systemImport', os.path.join(os.path.expanduser('~')))))
			path = self.fileDialog("Import Template", defaultPath, impTypes, save=False)
			if not path:
				return
			pref.setValue('systemImport', os.path.dirname(path))
			pref.sync()
		else:
			# Blur Prefs
			pref = blurdev.prefs.find('tools/simplex3')
			defaultPath = pref.restoreProperty('systemImport', os.path.join(os.path.expanduser('~')))
			path = self.fileDialog("Import Template", defaultPath, impTypes, save=False)
			if not path:
				return
			pref.recordProperty('systemImport', os.path.dirname(path))
			pref.save()

		pBar = QProgressDialog("Loading Shapes", "Cancel", 0, 100, self)
		pBar.show()
		QApplication.processEvents()

		# TODO: Come up with a better list of possibilites for loading
		# simplex files, and make the appropriate methods on the Simplex
		if path.endswith('.smpx'):
			newSystem = Simplex.buildSystemFromSmpx(path, self._currentObject, sliderMul=self._sliderMul, pBar=pBar)
		elif path.endswith('.json'):
			newSystem = Simplex.buildSystemFromJson(path, self._currentObject, sliderMul=self._sliderMul, pBar=pBar)
		
		with signalsBlocked(self.uiCurrentSystemCBOX):
			self.loadObject(newSystem.DCC.mesh)
			idx = self.uiCurrentSystemCBOX.findText(self._currentObjectName)
			if idx >= 0:
				self.uiCurrentSystemCBOX.setCurrentIndex(idx)
			else:
				self.uiCurrentSystemCBOX.addItem(newSystem.name)
				self.uiCurrentSystemCBOX.setCurrentIndex(self.uiCurrentSystemCBOX.count()-1)

		self.setSystem(newSystem)
		pBar.close()
Ejemplo n.º 17
0
def applyCorrectives(simplex, allShapePts, restPts, solver, shapes, refIdxs, references, pBar=None):
	'''
	Loop over the shapes and references, apply them, and return a new np.array
	of shape points

	simplex: Simplex system
	allShapePts: deltas per shape
	restPts: The rest point positions
	solver: The Python Simplex solver object
	shapes: The simplex shape objects we care about
	refIdxs: The reference index per shape
	references: A list of matrix-per-points
	'''
	# The rule of thumb is "THE SHAPE IS ALWAYS A DELTA"

	if pBar is not None:
		pBar.setLabelText("Inverting References")
		pBar.setValue(0)
		pBar.setMaximum(len(references))
		QApplication.processEvents()
	else:
		print "Inverting References"

	inverses = []
	for i, r in enumerate(references):
		if pBar is not None:
			pBar.setValue(i)
			QApplication.processEvents()
		inverses.append(invertAll(r))

	if pBar is not None:
		pBar.setLabelText("Extracting Uncorrected Shapes")
		QApplication.processEvents()
	else:
		print "Building Full Shapes"
	ptsByShape, vecByShape = buildFullShapes(simplex, shapes, allShapePts, solver, restPts, pBar)

	if pBar is not None:
		pBar.setLabelText("Correcting")
		QApplication.processEvents()
	else:
		print "Correcting"
	newPtsByShape = {}
	for shape, refIdx in zip(shapes, refIdxs):
		inv = inverses[refIdx]
		pts = ptsByShape[shape]
		newPts = applyReference(pts, inv)
		newPtsByShape[shape] = newPts

	newShapePts = collapseFullShapes(simplex, allShapePts, newPtsByShape, vecByShape, pBar)
	newShapePts = newShapePts + restPts[None, ...]

	return newShapePts
Ejemplo n.º 18
0
    def shapeConnectFromSelection(self):
        if self.simplex is None:
            return
        # make a dict of name:object
        sel = DCC.getSelectedObjects()
        selDict = {}
        for s in sel:
            name = DCC.getObjectName(s)
            if name.endswith("_Extract"):
                nn = name.rsplit("_Extract", 1)[0]
                selDict[nn] = s

        pairDict = {}
        for p in self.simplex.progs:
            for pp in p.pairs:
                pairDict[pp.shape.name] = pp

        # get all common names
        selKeys = set(selDict.iterkeys())
        pairKeys = set(pairDict.iterkeys())
        common = selKeys & pairKeys

        # get those items
        pairs = [pairDict[i] for i in common]

        # Set up the progress bar
        pBar = QProgressDialog("Connecting Shapes", "Cancel", 0, 100, self)
        pBar.setMaximum(len(pairs))

        # Do the extractions
        for pair in pairs:
            c = pair.prog.controller
            c.connectShape(pair.shape, delete=True)

            # ProgressBar
            pBar.setValue(pBar.value() + 1)
            pBar.setLabelText("Connecting:\n{0}".format(pair.shape.name))
            QApplication.processEvents()
            if pBar.wasCanceled():
                return

        pBar.close()
Ejemplo n.º 19
0
 def unifySelection(self):
     ''' Clear the selection if no modifiers are being held '''
     mods = QApplication.keyboardModifiers()
     if not mods & (Qt.ControlModifier | Qt.ShiftModifier):
         selModel = self.selectionModel()
         selModel.blockSignals(True)
         try:
             selModel.clearSelection()
         finally:
             selModel.blockSignals(False)
         self.viewport().update()
Ejemplo n.º 20
0
	def unifyComboSelection(self):
		''' Clear the selection of the slider tree when
		an item on the combo tree is selected '''
		mods = QApplication.keyboardModifiers()
		if not mods & (Qt.ControlModifier | Qt.ShiftModifier):
			sliderSelModel = self.uiSliderTREE.selectionModel()
			if not sliderSelModel:
				return
			with signalsBlocked(sliderSelModel):
				sliderSelModel.clearSelection()
			self.uiSliderTREE.viewport().update()
Ejemplo n.º 21
0
	def shapeConnectIndexes(self, indexes):
		pairs = coerceIndexToChildType(indexes, ProgPair)
		pairs = [i.model().itemFromIndex(i) for i in pairs]
		pairs = makeUnique([i for i in pairs if not i.shape.isRest])

		# Set up the progress bar
		pBar = QProgressDialog("Connecting Shapes", "Cancel", 0, 100, self)
		pBar.setMaximum(len(pairs))

		# Do the extractions
		for pair in pairs:
			c = pair.prog.controller
			c.connectShape(pair.shape, delete=True)

			# ProgressBar
			pBar.setValue(pBar.value() + 1)
			pBar.setLabelText("Extracting:\n{0}".format(pair.shape.name))
			QApplication.processEvents()
			if pBar.wasCanceled():
				return

		pBar.close()
Ejemplo n.º 22
0
def testNewChild(path):
    simp = buildDummySystem(path)
    model = SimplexModel(simp, None)
    model = SliderModel(model)
    model = SliderFilterModel(model)

    app = QApplication(sys.argv)

    topWid = QWidget()
    lay = QVBoxLayout(topWid)

    tv = QTreeView(topWid)

    btn = QPushButton('NEW', topWid)
    lay.addWidget(tv)
    lay.addWidget(btn)

    tv.setModel(model)
    topWid.show()

    expandRecursive(tv, model)
    tv.resizeColumnToContents(0)

    def newCallback():
        sel = tv.selectedIndexes()
        sel = [i for i in sel if i.column() == 0]
        items = [s.model().itemFromIndex(s) for s in sel]
        item = items[0]

        # TODO
        # find the child type of item
        # make a new one of those

        tv.model().invalidateFilter()

    btn.clicked.connect(newCallback)

    sys.exit(app.exec_())
Ejemplo n.º 23
0
    def doOverrideCursor(self):
        if self._overridden:
            return
        if self.dragCursor == self.CURSOR_BLANK:
            QApplication.setOverrideCursor(Qt.BlankCursor)
        elif self.dragCursor == self.CURSOR_ARROWS:
            if self._dragType == self.DRAG_VERTICAL:
                QApplication.setOverrideCursor(Qt.SizeVerCursor)
            elif self._dragType == self.DRAG_HORIZONTAL:
                QApplication.setOverrideCursor(Qt.SizeHorCursor)

        self._overridden = True
Ejemplo n.º 24
0
 def restoreOverrideCursor(self):
     if not self._overridden:
         return
     QApplication.restoreOverrideCursor()
     self._overridden = False
Ejemplo n.º 25
0
 def doOverrideCursor(self):
     if self._overridden:
         return
     QApplication.setOverrideCursor(self.slideCursor)
     self._overridden = True
Ejemplo n.º 26
0
def collapseFullShapes(simplex, allPts, ptsByShape, vecByShape, pBar=None):
	'''
	Given a set of shapes that are full-on shapes (not just deltas)
	Collapse them back into deltas in the simplex shape list
	'''
	#######################
	# Manipulate all the input lists and caches
	#indexBySlider = {s: i for i, s in enumerate(simplex.sliders)}
	indexByShape = {s: i for i, s in enumerate(simplex.shapes)}
	floaters = set(simplex.getFloatingShapes())
	#floatIdxs = set([indexByShape[s] for s in floaters])
	newPts = np.copy(allPts)

	# Order the combos by depth, and split out the floaters
	allDFirst = sorted(simplex.combos[:], key=lambda x: len(x.pairs))
	dFirst, dFloat = [], []
	for c in allDFirst:
		app = dFloat if c.isFloating() else dFirst
		app.append(c)

	# first do the sliders
	for item in simplex.sliders:
		for pair in item.prog.pairs:
			if pair.shape in ptsByShape:
				idx = indexByShape[pair.shape]
				newPts[idx] = ptsByShape[pair.shape]

	# Get the max number of iterations
	mxcount = 0
	for c in itertools.chain(dFirst, dFloat):
		for pair in c.prog.pairs:
			if pair.shape in ptsByShape:
				mxcount += 1

	if pBar is not None:
		pBar.setValue(0)
		pBar.setMaximum(mxcount)
		pBar.setLabelText("Building Corrected Deltas")
		QApplication.processEvents()

	# Then go through all the combos in order
	vcount = 0
	for c in itertools.chain(dFirst, dFloat):

		for pair in c.prog.pairs:
			if pair.shape in ptsByShape:
				if pBar is not None:
					pBar.setValue(vcount)
					QApplication.processEvents()
				else:
					print "Collapsing {0} of {1}\r".format(vcount + 1, mxcount),
				vcount += 1

				idx = indexByShape[pair.shape]
				outVec = vecByShape[pair.shape]
				outVec[idx] = 0.0 # turn off the influence of the current shape
				comboBase = np.dot(outVec, newPts.transpose((1, 0, 2)))
				comboSculpt = ptsByShape[pair.shape]
				newPts[idx] = comboSculpt - comboBase
	if pBar is None:
		print

	return newPts
Ejemplo n.º 27
0
def buildCorrectiveReferences(mesh, simplex, poses, sliders, pBar=None):
	'''
	Take correlated poses and sliders, and expand down the
	simplex combo tree, building references for each required shape

	Inputs:
		simplex <SimplexSystem> : A simplex system
		solver <PySimplex> : An instantiated simplex value solver
		poses <Prop/Value pair lists> : Different rig poses
		shapes <SimplexShapes> : Shape objects correlated to the poses
	'''
	# cache the pose search

	# Pre-cache the combo search
	allCombosBySliderValue = {}
	for c in simplex.combos:
		for p in c.pairs:
			allCombosBySliderValue.setdefault((p.slider, p.value), []).append(c)

	# This is only my subset set of downstreams
	# Get the downstreams by slider and value
	sliderValuesByCombo = {}
	for slider in sliders:
		for p in slider.prog.pairs:
			combos = allCombosBySliderValue.get((slider, p.value), [])
			for combo in combos:
				sliderValuesByCombo.setdefault(combo, []).append((slider, p.value))

	#out = []
	refCache = {}
	refs, shapes, refIdxs = [], [], []

	# get the slider outputs
	if pBar is not None:
		pBar.setLabelText("Building Shape References")
		pBar.setValue(0)
		mv = 0
		for slider in sliders:
			for p in slider.prog.pairs:
				if not p.shape.isRest:
					mv += 1
		pBar.setMaximum(mv)
		QApplication.processEvents()

	poseBySlider = {}
	for slider, pose in zip(sliders, poses):
		poseBySlider[slider] = pose
		for p in slider.prog.pairs:
			if not p.shape.isRest:
				if pBar is not None:
					pBar.setValue(pBar.value())
					QApplication.processEvents()
				cacheKey = frozenset([(slider, p.value)])
				if cacheKey in refCache:
					idx = refCache[cacheKey]
					refIdxs.append(idx)
				else:
					ref = getRefForPoses(mesh, [pose], p.value)
					refIdxs.append(len(refs))
					refCache[cacheKey] = len(refs)
					refs.append(ref)
				shapes.append(p.shape)

	# Get the combo outputs
	if pBar is not None:
		pBar.setLabelText("Building Combo References")
		pBar.setValue(0)
		mv = 0
		for combo in sliderValuesByCombo.iterkeys():
			for p in combo.prog.pairs:
				if not p.shape.isRest:
					mv += 1
		pBar.setMaximum(mv)
		QApplication.processEvents()

	for combo, sliderVals in sliderValuesByCombo.iteritems():
		#components = frozenset(sliderVals)
		poses = [poseBySlider[s] for s, _ in sliderVals]
		for p in combo.prog.pairs:
			if not p.shape.isRest:
				if pBar is not None:
					pBar.setValue(pBar.value())
					QApplication.processEvents()

				cacheKey = frozenset(sliderVals)
				if cacheKey in refCache:
					idx = refCache[cacheKey]
					refIdxs.append(idx)
				else:
					ref = getRefForPoses(mesh, poses, p.value)
					refIdxs.append(len(refs))
					refCache[cacheKey] = len(refs)
					refs.append(ref)
				shapes.append(p.shape)

	return np.array(refs), shapes, refIdxs
Ejemplo n.º 28
0
	def importObjFolder(self, folder):
		''' Import all objs from a user selected folder '''
		if not os.path.isdir(folder):
			QMessageBox.warning(self, 'Warning', 'Folder does not exist')
			return

		paths = os.listdir(folder)
		paths = [i for i in paths if i.endswith('.obj')]
		if not paths:
			QMessageBox.warning(self, 'Warning', 'Folder does not contain any .obj files')
			return

		shapeDict = {shape.name: shape for shape in self.simplex.shapes}

		inPairs = {}
		for path in paths:
			shapeName = os.path.splitext(os.path.basename(path))[0]
			shape = shapeDict.get(shapeName)
			if shape is not None:
				inPairs[shapeName] = path
			else:
				sfx = "_Extract"
				if shapeName.endswith(sfx):
					shapeName = shapeName[:-len(sfx)]
					shape = shapeDict.get(shapeName)
					if shape is not None:
						inPairs[shapeName] = path

		sliderMasters, comboMasters = {}, {}
		for masters in [self.simplex.sliders, self.simplex.combos]:
			for master in masters:
				for pp in master.prog.pairs:
					shape = shapeDict.get(pp.shape.name)
					if shape is not None:
						if shape.name in inPairs:
							if isinstance(master, Slider):
								sliderMasters[shape.name] = master
							if isinstance(master, Combo):
								comboMasters[shape.name] = master

		comboDepth = {}
		for k, v in comboMasters.iteritems():
			depth = len(v.pairs)
			comboDepth.setdefault(depth, {})[k] = v

		pBar = QProgressDialog("Loading from Mesh", "Cancel", 0, len(comboMasters) + len(sliderMasters), self)
		pBar.show()

		for shapeName, slider in sliderMasters.iteritems():
			pBar.setValue(pBar.value() + 1)
			pBar.setLabelText("Loading Obj :\n{0}".format(shapeName))
			QApplication.processEvents()
			if pBar.wasCanceled():
				return

			path = inPairs[shapeName]
			mesh = self.simplex.DCC.importObj(os.path.join(folder, path))

			shape = shapeDict[shapeName]
			self.simplex.DCC.connectShape(shape, mesh=mesh, live=False, delete=True)

		for depth in sorted(comboDepth.keys()):
			for shapeName, combo in comboDepth[depth].iteritems():
				pBar.setValue(pBar.value() + 1)
				pBar.setLabelText("Loading Obj :\n{0}".format(shapeName))
				QApplication.processEvents()
				if pBar.wasCanceled():
					return

				path = inPairs[shapeName]
				mesh = self.simplex.DCC.importObj(os.path.join(folder, path))
				shape = shapeDict[shapeName]
				self.simplex.DCC.connectComboShape(combo, shape, mesh=mesh, live=False, delete=True)

		pBar.close()