def addRig(human, rigfile): if not os.path.isfile(rigfile): rigfile = getpath.findFile(rigfile, searchPaths = [getpath.getSysDataPath(), getpath.getSysPath()]) if not os.path.isfile(rigfile): #log.error("Rig file %s does not exist.", mhclofile) #return raise RuntimeError('Rig file "%s" does not exist.' % rigfile) import skeleton if not human.getBaseSkeleton(): # TODO when starting in GUI mode, base skeleton will be loaded twice base_skel = skeleton.load(getpath.getSysDataPath('rigs/default.mhskel'), human.meshData) human.setBaseSkeleton(base_skel) referenceRig = human.getBaseSkeleton() # TODO update skeleton library when in gui mode skel = skeleton.load(rigfile, human.meshData) skel.autoBuildWeightReferences(referenceRig) vertexWeights = skel.getVertexWeights(referenceRig.getVertexWeights()) skel.addReferencePlanes(referenceRig) # Not strictly needed for the new way in which we determine bone normals human.setSkeleton(skel)
def addRig(human, rigfile): if not os.path.isfile(rigfile): rigfile = getpath.findFile( rigfile, searchPaths=[getpath.getSysDataPath(), getpath.getSysPath()]) if not os.path.isfile(rigfile): #log.error("Rig file %s does not exist.", mhclofile) #return raise RuntimeError('Rig file "%s" does not exist.' % rigfile) import skeleton if not human.getBaseSkeleton(): # TODO when starting in GUI mode, base skeleton will be loaded twice base_skel = skeleton.load( getpath.getSysDataPath('rigs/default.mhskel'), human.meshData) human.setBaseSkeleton(base_skel) referenceRig = human.getBaseSkeleton() # TODO update skeleton library when in gui mode skel = skeleton.load(rigfile, human.meshData) skel.autoBuildWeightReferences(referenceRig) vertexWeights = skel.getVertexWeights(referenceRig.getVertexWeights()) skel.addReferencePlanes( referenceRig ) # Not strictly needed for the new way in which we determine bone normals human.setSkeleton(skel)
def _load_pose_units(self): from collections import OrderedDict self.base_bvh = bvh.load( getpath.getSysDataPath('poseunits/face-poseunits.bvh'), allowTranslation="none") self.base_anim = self.base_bvh.createAnimationTrack( self.human.getBaseSkeleton(), name="Expression-Face-PoseUnits") poseunit_json = json.load(open( getpath.getSysDataPath('poseunits/face-poseunits.json'), 'r', encoding='utf-8'), object_pairs_hook=OrderedDict) self.poseunit_names = poseunit_json['framemapping'] log.message('unit pose frame count:%s', len(self.poseunit_names)) self.modifiers = dict( list(zip(self.poseunit_names, len(self.poseunit_names) * [0.0]))) self.base_poseunit = animation.PoseUnit( self.base_anim.name, self.base_anim.data[:self.base_anim.nBones * len(self.poseunit_names)], self.poseunit_names) self._load_gui()
def load(app): category = app.getCategory("Modelling") humanmodifier.loadModifiers(getpath.getSysDataPath("modifiers/modeling_modifiers.json"), app.selectedHuman) guimodifier.loadModifierTaskViews( getpath.getSysDataPath("modifiers/modeling_sliders.json"), app.selectedHuman, category )
def _load_pose_units(self): from collections import OrderedDict self.base_bvh = bvh.load( getpath.getSysDataPath('poseunits/face-poseunits.bvh'), allowTranslation="none") self.base_anim = self.base_bvh.createAnimationTrack( self.human.getBaseSkeleton(), name="Expression-Face-PoseUnits") poseunit_json = json.load(io.open( getpath.getSysDataPath('poseunits/face-poseunits.json'), 'r', encoding='utf-8'), object_pairs_hook=OrderedDict) self.poseunit_names = poseunit_json['framemapping'] if len(self.poseunit_names) != self.base_bvh.frameCount: self.base_anim = None raise RuntimeError( "Face units BVH has wrong number of frames (%s) while face-poseunits.json defines %s poses, they should be equal." % (self.base_bvh.frameCount, len(self.poseunit_names))) self.base_anim = animation.PoseUnit(self.base_anim.name, self.base_anim._data, self.poseunit_names) log.message('unit pose frame count:%s', len(self.poseunit_names)) # Store indexes of all bones affected by face unit poses, should be all face bones self.face_bone_idxs = sorted( list( set([ bIdx for l in self.base_anim.getAffectedBones() for bIdx in l ])))
def createFileChooser(self): """ Overwrite to do custom initialization of filechooser widget. """ #self.filechooser = self.addTopWidget(fc.FileChooser(self.paths, 'mhclo', 'thumb', mh.getSysDataPath(proxyName+'/notfound.thumb'))) notfoundIcon = self.getNotFoundIcon() if not os.path.isfile(notfoundIcon): notfoundIcon = getpath.getSysDataPath('notfound.thumb') if self.multiProxy: clearIcon = None else: clearIcon = self.getClearIcon() if not os.path.isfile(clearIcon): clearIcon = getpath.getSysDataPath('clear.thumb') self.filechooser = fc.IconListFileChooser( self.paths, self.getFileExtension(), 'thumb', notfoundIcon, clearIcon, name=self.label, multiSelect=self.multiProxy, noneItem=not self.multiProxy, stickyTags=gui3d.app.getSetting('makehumanTags')) self.addRightWidget(self.filechooser) self.filechooser.setIconSize(50, 50) self.filechooser.enableAutoRefresh(False) if not isinstance(self.getFileExtension(), str) and \ len(self.getFileExtension()) > 1: self.filechooser.mutexExtensions = True #self.addLeftWidget(self.filechooser.createSortBox()) if self.tagFilter: self.filechooser.setFileLoadHandler(fc.TaggedFileLoader(self)) self.addLeftWidget(self.filechooser.createTagFilter()) if self.descriptionWidget: descBox = self.addLeftWidget(gui.GroupBox('Description')) self.descrLbl = descBox.addWidget(gui.TextView('')) self.descrLbl.setSizePolicy(gui.QtWidgets.QSizePolicy.Ignored, gui.QtWidgets.QSizePolicy.Preferred) self.descrLbl.setWordWrap(True) @self.filechooser.mhEvent def onFileSelected(filename): self.proxyFileSelected(filename) if self.multiProxy: @self.filechooser.mhEvent def onFileDeselected(filename): self.proxyFileDeselected(filename) @self.filechooser.mhEvent def onDeselectAll(value): self.deselectAllProxies()
def _loadModifiers(human): """ Load modifiers from file. Set human to None to not assign them to a human. """ import humanmodifier modifiers = humanmodifier.loadModifiers(getpath.getSysDataPath('modifiers/modeling_modifiers.json'), human) modifiers.extend(humanmodifier.loadModifiers(getpath.getSysDataPath('modifiers/measurement_modifiers.json'), human)) return modifiers
def load(app): """ Plugin load function, needed by design. """ category = app.getCategory('Modelling') humanmodifier.loadModifiers(getpath.getSysDataPath('modifiers/measurement_modifiers.json'), app.selectedHuman) guimodifier.loadModifierTaskViews(getpath.getSysDataPath('modifiers/measurement_sliders.json'), app.selectedHuman, category, taskviewClass=MeasureTaskView)
def _loadModifiers(human): """ Load modifiers from file. Set human to None to not assign them to a human. """ import humanmodifier modifiers = humanmodifier.loadModifiers(getpath.getSysDataPath('modifiers/modeling_modifiers.json'), human) ## COMMENT - adds measurement modifiers - earlier 207 now 226 because of the extension modifiers.extend(humanmodifier.loadModifiers(getpath.getSysDataPath('modifiers/measurement_modifiers.json'), human)) return modifiers
def createFileChooser(self): """ Overwrite to do custom initialization of filechooser widget. """ # self.filechooser = self.addTopWidget(fc.FileChooser(self.paths, 'mhclo', 'thumb', mh.getSysDataPath(proxyName+'/notfound.thumb'))) notfoundIcon = self.getNotFoundIcon() if not os.path.isfile(notfoundIcon): notfoundIcon = getpath.getSysDataPath("notfound.thumb") if self.multiProxy: clearIcon = None else: clearIcon = self.getClearIcon() if not os.path.isfile(clearIcon): clearIcon = getpath.getSysDataPath("clear.thumb") self.filechooser = fc.IconListFileChooser( self.paths, self.getFileExtension(), "thumb", notfoundIcon, clearIcon, name=self.label, multiSelect=self.multiProxy, noneItem=not self.multiProxy, ) self.addRightWidget(self.filechooser) self.filechooser.setIconSize(50, 50) self.filechooser.enableAutoRefresh(False) if not isinstance(self.getFileExtension(), basestring) and len(self.getFileExtension()) > 1: self.filechooser.mutexExtensions = True # self.addLeftWidget(self.filechooser.createSortBox()) if self.tagFilter: self.filechooser.setFileLoadHandler(fc.TaggedFileLoader(self)) self.addLeftWidget(self.filechooser.createTagFilter()) if self.descriptionWidget: descBox = self.addLeftWidget(gui.GroupBox("Description")) self.descrLbl = descBox.addWidget(gui.TextView("")) self.descrLbl.setSizePolicy(gui.QtGui.QSizePolicy.Ignored, gui.QtGui.QSizePolicy.Preferred) self.descrLbl.setWordWrap(True) @self.filechooser.mhEvent def onFileSelected(filename): self.proxyFileSelected(filename) if self.multiProxy: @self.filechooser.mhEvent def onFileDeselected(filename): self.proxyFileDeselected(filename) @self.filechooser.mhEvent def onDeselectAll(value): self.deselectAllProxies()
def _listDataFiles(foldername, extensions, onlySysData=False, recursive=True): import getpath if onlySysData: paths = [getpath.getSysDataPath(foldername)] else: paths = [getpath.getDataPath(foldername), getpath.getSysDataPath(foldername)] return getpath.search(paths, extensions, recursive)
def load(app): category = app.getCategory('Modelling') humanmodifier.loadModifiers( getpath.getSysDataPath('modifiers/modeling_modifiers.json'), app.selectedHuman) guimodifier.loadModifierTaskViews( getpath.getSysDataPath('modifiers/modeling_sliders.json'), app.selectedHuman, category)
def getHuman(): with mhpath: thuman = Human( files3d.loadMesh(getpath.getSysDataPath("3dobjs/base.obj"), maxFaces=5)) humanmodifier.mods_loaded = False modifiers = humanmodifier.loadModifiers( getpath.getSysDataPath('modifiers/modeling_modifiers.json'), thuman) return thuman
def stripTargets(self, obj, action=-1): for targetName in universalBaseTargets: filename = os.path.join(gp.getSysDataPath('targets/macrodetails'), targetName) target = algos3d.getTarget(obj, filename) if target: target.apply(obj, action * 1.0 / len(universalBaseTargets)) for targetName in baseTargets: filename = os.path.join(gp.getSysDataPath('targets/macrodetails'), targetName) target = algos3d.getTarget(obj, filename) if target: target.apply(obj, action * 1.0 / len(baseTargets))
def get_blank_pose(): human = gui3d.app.selectedHuman base_bvh = bvh.load(getpath.getSysDataPath('poseunits/face-poseunits.bvh'), allowTranslation="none") base_anim = base_bvh.createAnimationTrack(human.getBaseSkeleton(), name="Expression-Face-PoseUnits") poseunit_json = json.load(open(getpath.getSysDataPath('poseunits/face-poseunits.json'),'rb'), object_pairs_hook=OrderedDict) # the names of the changeable facial expression features poseunit_names = poseunit_json['framemapping'] modifiers = dict(zip(poseunit_names, len(poseunit_names)*[0.0])) base_poseunit = animation.PoseUnit(base_anim.name, base_anim.data[:base_anim.nBones*len(poseunit_names)], poseunit_names) return modifiers, base_poseunit
def __init__(self, human): self.human = human self.skinCache = { 'caucasian' : image.Image(getSysDataPath('litspheres/skinmat_caucasian.png')), 'african' : image.Image(getSysDataPath('litspheres/skinmat_african.png')), 'asian' : image.Image(getSysDataPath('litspheres/skinmat_asian.png')) } self._previousEthnicState = [0, 0, 0] self._litsphereTexture = None self._diffuseColor = material.Color() self.checkUpdate()
def _listDataFiles(foldername, extensions, onlySysData=False, recursive=True): with mhpath: # sadly makehuman seems hardcoded if onlySysData: paths = [getpath.getSysDataPath(foldername)] else: paths = [getpath.getDataPath(foldername), getpath.getSysDataPath(foldername)] return list(getpath.search(paths, extensions, recursive))
def _loadModifiers(human): """ Load modifiers from file. Set human to None to not assign them to a human. """ import humanmodifier modifiers = humanmodifier.loadModifiers( getpath.getSysDataPath('modifiers/modeling_modifiers.json'), human) modifiers.extend( humanmodifier.loadModifiers( getpath.getSysDataPath('modifiers/measurement_modifiers.json'), human)) return modifiers
def setExpressionFromFile(self, mhposeFile): """Set the expression from a mhpose file""" if mhposeFile is None: # clear expression original_pose = self.getPoseAsAnimation() if original_pose and hasattr(original_pose, 'pose_backref'): original_pose = original_pose.pose_backref if original_pose is None: self.human.setActiveAnimation(None) else: if self.human.hasAnimation(original_pose.name): self.human.setActiveAnimation(original_pose.name) else: self.human.addAnimation(original_pose) self.human.setActiveAnimation(orgiginal_pose.name) if self.human.hasAnimation('expr-lib-pose'): self.human.removeAnimation('expr-lib-pose') else: # Assign expression base_bvh = bvh.load(getpath.getSysDataPath('poseunits/face-poseunits.bvh'), allowTranslation="none") base_anim = base_bvh.createAnimationTrack(self.human.getBaseSkeleton(), name="Expression-Face-PoseUnits") poseunit_json = json.load(open(getpath.getSysDataPath('poseunits/face-poseunits.json'), 'r', encoding='utf-8'), object_pairs_hook=OrderedDict) poseunit_names = poseunit_json['framemapping'] base_anim = animation.PoseUnit(base_anim.name, base_anim._data, poseunit_names) face_bone_idxs = sorted(list(set([bIdx for l in base_anim.getAffectedBones() for bIdx in l]))) new_pose = animation.poseFromUnitPose('expr-lib-pose', mhposeFile, base_anim) current_pose = self.getPoseAsAnimation() if current_pose is None: current_pose = new_pose current_pose.pose_backref = None else: if hasattr(current_pose,'pose_backref') and not current_pose.pose_backref is None: current_pose = current_pose.pose_backref org_pose = current_pose current_pose = animation.mixPoses(org_pose, new_pose, face_bone_idxs) current_pose.name = 'expr-lib-pose' self.human.addAnimation(current_pose) self.human.setActiveAnimation(current_pose.name) self.human.setPosed(True) self.human.refreshPose()
def _load_pose_units(self): from collections import OrderedDict self.base_bvh = bvh.load(getpath.getSysDataPath('poseunits/face-poseunits.bvh'), allowTranslation="none") self.base_anim = self.base_bvh.createAnimationTrack(self.human.getBaseSkeleton(), name="Expression-Face-PoseUnits") poseunit_json = json.load(open(getpath.getSysDataPath('poseunits/face-poseunits.json'),'rb'), object_pairs_hook=OrderedDict) self.poseunit_names = poseunit_json['framemapping'] log.message('unit pose frame count:%s', len(self.poseunit_names)) self.modifiers = dict(zip(self.poseunit_names, len(self.poseunit_names)*[0.0])) self.base_poseunit = animation.PoseUnit(self.base_anim.name, self.base_anim.data[:self.base_anim.nBones*len(self.poseunit_names)], self.poseunit_names) self._load_gui()
def _loadModifiers(human): """ Load modifiers from file. Set human to None to not assign them to a human. """ import humanmodifier modifiers = humanmodifier.loadModifiers( getpath.getSysDataPath('modifiers/modeling_modifiers.json'), human) ## COMMENT - adds measurement modifiers - earlier 207 now 226 because of the extension modifiers.extend( humanmodifier.loadModifiers( getpath.getSysDataPath('modifiers/measurement_modifiers.json'), human)) return modifiers
def getHuman(self): """Load a human model with modifiers.""" with self.mhpath: # maxFaces *uint* Number of faces per vertex (pole), None for default (min 4) human = Human( files3d.loadMesh(getpath.getSysDataPath("3dobjs/base.obj"), maxFaces=5)) # load modifiers onto human humanmodifier.mods_loaded = False modifiers = humanmodifier.loadModifiers( getpath.getSysDataPath('modifiers/modeling_modifiers.json'), human) return human
def createFileChooser(self): """ Overwrite to do custom initialization of filechooser widget. """ #self.filechooser = self.addTopWidget(fc.FileChooser(self.paths, 'mhclo', 'thumb', mh.getSysDataPath(proxyName+'/notfound.thumb'))) notfoundIcon = self.getNotFoundIcon() if not os.path.isfile(notfoundIcon): notfoundIcon = getpath.getSysDataPath('notfound.thumb') if self.multiProxy: clearIcon = None else: clearIcon = self.getClearIcon() if not os.path.isfile(clearIcon): clearIcon = getpath.getSysDataPath('clear.thumb') self.filechooser = fc.IconListFileChooser(self.paths, self.getFileExtension(), 'thumb', notfoundIcon, clearIcon, name=self.label, multiSelect=self.multiProxy, noneItem=not self.multiProxy) self.addRightWidget(self.filechooser) self.filechooser.setIconSize(50, 50) self.filechooser.enableAutoRefresh(False) if not isinstance(self.getFileExtension(), basestring) and \ len(self.getFileExtension()) > 1: self.filechooser.mutexExtensions = True #self.addLeftWidget(self.filechooser.createSortBox()) if self.tagFilter: self.filechooser.setFileLoadHandler(fc.TaggedFileLoader(self)) self.addLeftWidget(self.filechooser.createTagFilter()) @self.filechooser.mhEvent def onFileSelected(filename): self.proxyFileSelected(filename) if self.multiProxy: @self.filechooser.mhEvent def onFileDeselected(filename): self.proxyFileDeselected(filename) @self.filechooser.mhEvent def onDeselectAll(value): self.deselectAllProxies()
def _listDataFiles(foldername, extensions, onlySysData=False, recursive=True): import getpath if onlySysData: paths = [getpath.getSysDataPath(foldername)] else: paths = [ getpath.getDataPath(foldername), getpath.getSysDataPath(foldername) ] return getpath.search(paths, extensions, recursive)
def __init__(this, path): this.path = path + '/makehuman' this.syspath = ['.' + x for x in ('/', '/lib', '/apps', '/shared', '/apps/gui', '/core', '/plugins')] #cwd = os.getcwd() #syspath = sys.path os.chdir(this.path) sys.path += this.syspath if verbose: sys.stderr.write("Probing makehuman ...\n") import core import headless import getpath import humanmodifier import log ## uncomment to disable makehuman log #log.init() #core.G.app = headless.ConsoleApp() #this.human = core.G.app.selectedHuman modifierGroups = ('head', 'forehead', 'eyebrows', 'neck', 'nose', 'mouth', 'ears', 'chin', 'cheek', 'macrodetails', 'macrodetails-universal', 'macrodetails-proportions') proxyTypes = ('hair', 'eyebrows', 'eyelashes') modifiers = humanmodifier.loadModifiers(getpath.getSysDataPath('modifiers/modeling_modifiers.json'), None) modifiers = [x for x in modifiers if x.groupName in modifierGroups and x.fullName != 'macrodetails/Caucasian'] this.symmetricalModifiers = [x for x in modifiers if x.getSymmetrySide() is None] this.rightModifiers = [x for x in modifiers if x.getSymmetrySide() == 'r'] this.leftModifiers = [x for x in modifiers if x.getSymmetrySide() == 'l'] if verbose: sys.stderr.write("Found %i symmetrical facial features\n" % len(this.symmetricalModifiers)) sys.stderr.write("Found %i left facial features\n" % len(this.leftModifiers)) sys.stderr.write("Found %i right facial features\n" % len(this.rightModifiers)) this.proxies = {} for proxyType in proxyTypes: files = getpath.search([getpath.getDataPath(proxyType),getpath.getSysDataPath(proxyType)], ['.proxy', '.mhclo'], True) files = list(files) if verbose: sys.stderr.write("Found %i %s proxies\n" % (len(files), proxyType)) this.proxies[proxyType] = files skins = getpath.search([getpath.getDataPath('skins'),getpath.getSysDataPath('skins')], ['.mhmat'], True) this.skins = list(skins) if verbose: sys.stderr.write("Found %i skins\n" % len(this.skins))
def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Expressions') self.human = gui3d.app.selectedHuman # TODO defer loading to first onShow() bvhfile = bvh.load(getpath.getSysDataPath('poseunits/face-poseunits.bvh'), allowTranslation="none") self.base_bvh = bvhfile from collections import OrderedDict poseunit_json = json.load(open(getpath.getSysDataPath('poseunits/face-poseunits.json'),'rb'), object_pairs_hook=OrderedDict) self.poseunit_names = poseunit_json['framemapping'] self.sliders = [] self.modifiers = dict(zip(self.poseunit_names, len(self.poseunit_names)*[0.0]))
def update(self): caucasianWeight = self.human.getCaucasian() africanWeight = self.human.getAfrican() asianWeight = self.human.getAsian() blends = [] # Set litsphere texture if caucasianWeight > 0: blends.append( ('caucasian', caucasianWeight) ) if africanWeight > 0: blends.append( ('african', africanWeight) ) if asianWeight > 0: blends.append( ('asian', asianWeight) ) if len(blends) == 1: img = self.skinCache[blends[0][0]] img.markModified() else: img = image_operations.mix(self.skinCache[blends[0][0]], self.skinCache[blends[1][0]], blends[0][1], blends[1][1]) if len(blends) > 2: img = image_operations.mix(img, self.skinCache[blends[2][0]], 1.0, blends[2][1]) # Set parameter so the image can be referenced when material is written to file (and texture can be cached) img.sourcePath = getSysDataPath("litspheres/adaptive_skin_tone.png") self._litsphereTexture = img # Set diffuse color diffuse = asianWeight * asianColor + \ africanWeight * africanColor + \ caucasianWeight * caucasianColor self._diffuseColor = material.Color(diffuse)
def writeVersionFile(self, overrideVersionPath=None): path = overrideVersionPath if path is None: path = self.versionPath if path is None: path = getpath.getSysDataPath("VERSION") out = dict() if not self.currentShortCommit is None and not self.currentShortCommit == "UNKNOWN": out["currentShortCommit"] = self.currentShortCommit if not self.currentLongCommit is None and not self.currentLongCommit == "UNKNOWN": out["currentLongCommit"] = self.currentLongCommit if not self.currentBranch is None and not self.currentBranch == "UNKNOWN": out["currentBranch"] = self.currentBranch if not self.title is None and not self.title == "MakeHuman Community": out["title"] = self.title if not self.version is None: out["version"] = self.version if not self.isRelease is None: out["isRelease"] = self.isRelease with open(path, 'w', encoding='utf-8') as f: json.dump(out, f, sort_keys=True, indent=4)
def _checkForVersionFile(self): path = self.versionPath if path is None: path = getpath.getSysDataPath("VERSION") if os.path.exists(path): jsonin = None with open(path, 'r', encoding='utf-8') as f: jsonin = json.load(f) if not jsonin is None: if "currentShortCommit" in jsonin: self.currentShortCommit = jsonin["currentShortCommit"] if "currentLongCommit" in jsonin: self.currentLongCommit = jsonin["currentLongCommit"] if "currentBranch" in jsonin: self.currentBranch = jsonin["currentBranch"] if "title" in jsonin: self.title = jsonin["title"] if "version" in jsonin: self.version = jsonin["version"] if "isRelease" in jsonin: self.isRelease = jsonin["isRelease"]
def getProxies(self): """ Get the proxy list from the current state of the set human object. Proxy list will contain all proxy items such as proxy mesh and clothes, hair, eyes, genitals and cages. """ if not self.human: return {} proxies = {} for proxy in self.human.getProxies(): if proxy: name = self.goodName(proxy.name) proxies[name] = proxy if self.human.proxy: proxy = self.human.proxy name = self.goodName(proxy.name) proxies[name] = proxy if self.cage: import mh2proxy obj = G.app.selectedHuman filepath = getSysDataPath("cages/cage/cage.mhclo") proxy = mh2proxy.readProxyFile(obj, filepath, type="Cage") proxy.update(obj) proxies[name] = proxy return proxies
def getProxies(self): """ Get the proxy list from the current state of the set human object. Proxy list will contain all proxy items such as proxy mesh and clothes, hair, eyes, genitals and cages. """ if not self.human: return {} proxies = {} for pxy in self.human.getProxies(): if pxy: name = self.goodName(pxy.name) proxies[name] = pxy if self.human.proxy: pxy = self.human.proxy name = self.goodName(pxy.name) proxies[name] = pxy # TODO deprecated? is this going to be revived? if self.cage: import proxy human = G.app.selectedHuman filepath = getSysDataPath("cages/cage/cage.mhclo") pxy = proxy.loadProxy(human, filepath, type="Cage") pxy.update(human.meshData) proxies[name] = pxy return proxies
def get_hg_revision(): # Use the data/VERSION file if it exists. This is created and managed by build scripts import getpath versionFile = getpath.getSysDataPath("VERSION") if os.path.exists(versionFile): version_ = open(versionFile).read().strip() print("data/VERSION file detected using value from version file: %s" % version_, file=sys.stderr) os.environ['HGREVISION'] = str(version_.split(':')[0]) os.environ['HGNODEID'] = str(version_.split(':')[1]) os.environ['HGREVISION_SOURCE'] = "data/VERSION static revision data" elif not isBuild(): print("NO VERSION file detected, retrieving revision info from HG", file=sys.stderr) # Set HG rev in environment so it can be used elsewhere hgrev = get_hg_revision_1() print("Detected HG revision: r%s (%s)" % (hgrev[0], hgrev[1]), file=sys.stderr) else: # Don't bother trying to retrieve HG info for a build release, there should be a data/VERSION file os.environ['HGREVISION'] = "" os.environ['HGNODEID'] = "" os.environ['HGREVISION_SOURCE'] = "skipped for build" return (os.environ['HGREVISION'], os.environ['HGNODEID'])
def __init__(self, scale=1.0): import files3d import getpath module3d.Object3D.__init__(self, 'axis', 4) files3d.loadMesh(getpath.getSysDataPath('3dobjs/axis.obj'), maxFaces=4, obj=self) for fg_name in self.getFaceGroups(): if 'red' in fg_name.lower(): self.color[self.getVerticesForGroups([fg_name ])] = [255, 0, 0, 255] elif 'green' in fg_name.lower(): self.color[self.getVerticesForGroups([fg_name ])] = [0, 255, 0, 255] elif 'blue' in fg_name.lower(): self.color[self.getVerticesForGroups([fg_name ])] = [0, 0, 255, 255] self.markCoords(colr=True) self.sync_color() if scale != 1.0: self.coord[:] *= float(scale) self.markCoords(coor=True) self.sync_coord()
def __init__(self, mesh, hairObj=None, eyesObj=None, genitalsObj=None): guicommon.Object.__init__(self, mesh) self.hasWarpTargets = False self.MIN_AGE = 1.0 self.MAX_AGE = 90.0 self.MID_AGE = 25.0 self.mesh.setCameraProjection(0) self.mesh.setPickable(True) self.mesh.setShadeless(0) self.mesh.setCull(1) self.meshData = self.mesh self._staticFaceMask = None self.maskFaces() self._hairObj = hairObj self._hairProxy = None self._eyesObj = eyesObj self._eyesProxy = None self._genitalsObj = genitalsObj self._genitalsProxy = None self.eyebrowsObj = None self.eyebrowsProxy = None self.eyelashesObj = None self.eyelashesProxy = None self.teethObj = None self.teethProxy = None self.tongueObj = None self.tongueProxy = None self.clothesObjs = {} self.clothesProxies = {} self.targetsDetailStack = { } # All details targets applied, with their values self.symmetryModeEnabled = False self.setDefaultValues() self.bodyZones = [ 'l-eye', 'r-eye', 'jaw', 'nose', 'mouth', 'head', 'neck', 'torso', 'hip', 'pelvis', 'r-upperarm', 'l-upperarm', 'r-lowerarm', 'l-lowerarm', 'l-hand', 'r-hand', 'r-upperleg', 'l-upperleg', 'r-lowerleg', 'l-lowerleg', 'l-foot', 'r-foot', 'ear' ] self.material = material.fromFile( getSysDataPath('skins/default.mhmat')) self._defaultMaterial = material.Material().copyFrom(self.material) self._modifiers = dict() self._modifier_varMapping = dict( ) # Maps macro variable to the modifier group that modifies it self._modifier_dependencyMapping = dict( ) # Maps a macro variable to all the modifiers that depend on it self._modifier_groups = dict()
def refresh(self, keepSelections=True): if keepSelections: selections = self.getSelectedItems() if self.multiSelect: highLighted = self.getHighlightedItem() else: self.deselectAll() super(ListFileChooser, self).refresh() # Add None item if not self.multiSelect and self.noneItem: if not self.clearImage or not os.path.isfile(self.clearImage): if self.notFoundImage: ext = os.path.splitext(self.notFoundImage)[1] clearIcon = os.path.join(os.path.dirname(self.notFoundImage), 'clear'+ext) else: clearIcon = getpath.getSysDataPath('clear.thumb') else: clearIcon = self.clearImage self.addItem(None, "None", clearIcon, pos = 0) for listItem in self.children.getItems(): listItem.updateTooltip() if keepSelections: if self.multiSelect: self.setSelections(selections) self.setHighlightedItem(highLighted) elif len(selections) > 0: self.setSelection(selections[0])
def onShow(self, event): super(RenderTaskView, self).onShow(event) import getpath human = G.app.selectedHuman self.oldShader = human.material.shader human.material.shader = getpath.getSysDataPath(self.taskViewShader)
def _getFilePath(filename, folder = None): if not filename or not isinstance(filename, basestring): return filename # Ensure unix style path filename.replace('\\', '/') searchPaths = [] # Search within current folder if folder: searchPaths.append(folder) from getpath import findFile, getPath, getSysDataPath, getSysPath, getDataPath searchPaths.extend([getDataPath(), getSysDataPath(), getPath(), getSysPath()]) # Search in user / sys data, and user / sys root folders path = findFile(filename, searchPaths, strict=True) if path: return os.path.abspath(path) # Treat as absolute path or search relative to application path if os.path.isfile(filename): return os.path.abspath(filename) # Nothing found return os.path.normpath(filename)
def onShow(self, event): PoseModeTaskView.onShow(self, event) import getpath human = G.app.selectedHuman self.oldShader = human.material.shader human.material.shader = getpath.getSysDataPath(self.taskViewShader)
def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Pose') filecache.MetadataCacher.__init__(self, ['bvh'], 'pose_filecache.mhc') self.cache_format_version = '1c' # Bump cacher version for updated format of pose metadata self.human = G.app.selectedHuman self.currentPose = None self.bvh_bone_length = None self.bvh_root_translation = None self.sysDataPath = getpath.getSysDataPath('poses') self.userDataPath = getpath.getDataPath('poses') if not os.path.exists(self.userDataPath): os.makedirs(self.userDataPath) self.paths = [self.userDataPath, self.sysDataPath] self.filechooser = self.addRightWidget(fc.IconListFileChooser(self.paths, ['bvh'], 'thumb', mh.getSysDataPath('poses/notfound.thumb'), name='Pose', noneItem=True)) self.filechooser.setIconSize(50,50) self.filechooser.enableAutoRefresh(False) @self.filechooser.mhEvent def onFileSelected(filename): gui3d.app.do(PoseAction("Change pose", self, self.currentPose, filename)) self.filechooser.setFileLoadHandler(fc.TaggedFileLoader(self)) self.addLeftWidget(self.filechooser.createTagFilter()) self.skelObj = None
def _load_pose_units(self): from collections import OrderedDict self.base_bvh = bvh.load(getpath.getSysDataPath('poseunits/face-poseunits.bvh'), allowTranslation="none") self.base_anim = self.base_bvh.createAnimationTrack(self.human.getBaseSkeleton(), name="Expression-Face-PoseUnits") poseunit_json = json.load(open(getpath.getSysDataPath('poseunits/face-poseunits.json'),'rb'), object_pairs_hook=OrderedDict) self.poseunit_names = poseunit_json['framemapping'] if len(self.poseunit_names) != self.base_bvh.frameCount: self.base_anim = None raise RuntimeError("Face units BVH has wrong number of frames (%s) while face-poseunits.json defines %s poses, they should be equal." % (self.base_bvh.frameCount, len(self.poseunit_names))) self.base_anim = animation.PoseUnit(self.base_anim.name, self.base_anim._data, self.poseunit_names) log.message('unit pose frame count:%s', len(self.poseunit_names)) # Store indexes of all bones affected by face unit poses, should be all face bones self.face_bone_idxs = sorted(list(set([bIdx for l in self.base_anim.getAffectedBones() for bIdx in l])))
def set_theme(self, theme): """ Set the theme of the terminal and syntax highlighting. """ ipy_stylesheet_path = getpath.getSysDataPath('themes/%s_console.css' % theme) try: with open(ipy_stylesheet_path, 'r') as css_file: stylesheet = css_file.read() except IOError: # No file to load, use default theme stylesheet = styles.default_light_style_sheet # TODO not working yet (causes a crash for some reason) ''' # Try parsing pygments Style python class if available, and add it to CSS try: style_obj = load_pygments_style(theme) # Append syntax highlighting CSS to stylesheet stylesheet += "\n\n" + pygments_style_to_css(style_obj) # Use syntax highlighting defined in CSS stylesheet self.ipyConsole.syntax_style = "" except: # else use default syntax style self.ipyConsole.syntax_style = "monokai" ''' self.ipyConsole.syntax_style = "monokai" self.ipyConsole.style_sheet = stylesheet
def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Expressions') self.extension = 'mhpose' filecache.MetadataCacher.__init__(self, self.extension, 'expression_filecache.mhc') self.human = gui3d.app.selectedHuman self.selectedFile = None self.selectedPose = None self.face_bone_idxs = None self.base_bvh = None self.base_anim = None self._setting_pose = False self.sysDataPath = getpath.getSysDataPath('expressions') self.userPath = getpath.getDataPath('expressions') self.paths = [self.userPath, self.sysDataPath] if not os.path.exists(self.userPath): os.makedirs(self.userPath) self.filechooser = self.addRightWidget(fc.IconListFileChooser( \ self.paths, self.extension, 'thumb', name='Expression', notFoundImage = getpath.getSysDataPath('notfound.thumb'), noneItem = True, doNotRecurse = True)) self.filechooser.setIconSize(50,50) self.filechooser.enableAutoRefresh(False) @self.filechooser.mhEvent def onFileSelected(filename): if filename: msg = 'Load expression' else: msg = "Clear expression" gui3d.app.do(ExpressionAction(msg, self.selectedFile, filename, self)) self.filechooser.setFileLoadHandler(fc.TaggedFileLoader(self)) self.addLeftWidget(self.filechooser.createTagFilter())
def createFileChooser(self): """ Overwrite to do custom initialization of filechooser widget. """ #self.filechooser = self.addTopWidget(fc.FileChooser(self.paths, 'mhclo', 'thumb', mh.getSysDataPath(proxyName+'/notfound.thumb'))) notfoundIcon = self.getNotFoundIcon() if not os.path.isfile(notfoundIcon): notfoundIcon = getpath.getSysDataPath('notfound.thumb') if self.multiProxy: clearIcon = None else: clearIcon = self.getClearIcon() if not os.path.isfile(clearIcon): clearIcon = getpath.getSysDataPath('clear.thumb') self.filechooser = fc.IconListFileChooser(self.paths, self.getFileExtension(), 'thumb', notfoundIcon, clearIcon, name=self.label, multiSelect=self.multiProxy, noneItem = not self.multiProxy) self.addRightWidget(self.filechooser) self.filechooser.setIconSize(50,50) self.filechooser.enableAutoRefresh(False) if not isinstance(self.getFileExtension(), basestring) and \ len(self.getFileExtension()) > 1: self.filechooser.mutexExtensions = True #self.addLeftWidget(self.filechooser.createSortBox()) if self.tagFilter: self.filechooser.setFileLoadHandler(fc.TaggedFileLoader(self)) self.addLeftWidget(self.filechooser.createTagFilter()) @self.filechooser.mhEvent def onFileSelected(filename): self.proxyFileSelected(filename) if self.multiProxy: @self.filechooser.mhEvent def onFileDeselected(filename): self.proxyFileDeselected(filename) @self.filechooser.mhEvent def onDeselectAll(value): self.deselectAllProxies()
def getLanguages(): """ The languages available on this MH installation, by listing all .json files in the languages folder in user and system data path. """ langDirFiles = os.listdir(getSysDataPath('languages')) try: langDirFiles = langDirFiles + os.listdir(getDataPath('languages')) except: pass return ['english'] + [os.path.basename(filename).replace('.json', '') for filename in langDirFiles if filename.split(os.extsep)[-1] == "json"]
def addProxy(human, mhclofile, type): # TODO if eyes proxy is loaded, the one loaded by default should be removed if not os.path.isfile(mhclofile): mhclofile = getpath.findFile(mhclofile, searchPaths = [getpath.getDataPath(), getpath.getSysDataPath(), getpath.getPath(), getpath.getSysPath()]) if not os.path.isfile(mhclofile): #log.error("Proxy file %s does not exist (%s).", mhclofile, type) #return raise RuntimeError('Proxy file "%s" does not exist (%s).' % (mhclofile, type)) import proxy pxy = proxy.loadProxy(human, mhclofile, type=type.capitalize()) mesh,obj = pxy.loadMeshAndObject(human) if type == "proxymeshes": human.setProxy(pxy) return mesh,obj = pxy.loadMeshAndObject(human) if not mesh: raise RuntimeError('Failed to load proxy mesh "%s"', pxy.obj_file) def _adaptProxyToHuman(pxy, obj): mesh = obj.getSeedMesh() pxy.update(mesh) mesh.update() # Update subdivided mesh if smoothing is enabled if obj.isSubdivided(): obj.getSubdivisionMesh() _adaptProxyToHuman(pxy, obj) obj.setSubdivided(human.isSubdivided()) if type == "hair": human.hairProxy = pxy elif type == "eyes": human.eyesProxy = pxy elif type == "eyebrows": human.eyebrowsProxy = pxy elif type == "eyelashes": human.eyelashesProxy = pxy elif type == "teeth": human.teethProxy = pxy elif type == "tongue": human.tongueProxy = pxy elif type == "clothes": human.addClothesProxy(pxy) else: raise RuntimeError("Unknown proxy type: %s" % type)
def applyMaterial(matFile, obj): if not os.path.isfile(matFile): matFile = getpath.findFile(matFile, searchPaths = [getpath.getDataPath(), getpath.getSysDataPath(), getpath.getPath(), getpath.getSysPath()]) if not os.path.isfile(matFile): raise RuntimeError('Material file "%s" does not exist.', matFile) else: import material obj.material = material.fromFile( matFile )
def visualizeFaceMasks(self, enabled): import material import getpath if enabled: self.oldPxyMats = dict() xray_mat = material.fromFile(getpath.getSysDataPath('materials/xray.mhmat')) for pxy in self.human.getProxies(includeHumanProxy=False): self.oldPxyMats[pxy.uuid] = pxy.object.material.clone() pxy.object.material = xray_mat else: for pxy in self.human.getProxies(includeHumanProxy=False): if pxy.uuid in self.oldPxyMats: pxy.object.material = self.oldPxyMats[pxy.uuid]
def getModifierMapping(self): if self.modifier_mapping is None: self.modifier_mapping = dict() f = open(getpath.getSysDataPath('modifiers/mh_1-0_modifier_mapping.csv'), 'rb') csvreader = csv.reader(f, delimiter=',', quotechar='"') for r_idx, row in enumerate(csvreader): if r_idx == 0: # First line is header, drop it continue if row[0]: self.modifier_mapping[row[0]] = (row[1], bool(row[2])) f.close() return self.modifier_mapping
def dumpMissingStrings(self): if not self.language: return path = os.path.join(getSysDataPath("languages/"), self.language + ".missing") pathdir = os.path.dirname(path) if not os.path.isdir(pathdir): os.makedirs(pathdir) with open(path, 'wb') as f: for string in self.missingStrings: if self.language == "master": f.write('"%s": "%s",\n' % (string.replace('\n', '\\n').encode('utf8'), string.replace('\n', '\\n').encode('utf8'))) else: f.write('"%s": "",\n' % string.replace('\n', '\\n').encode('utf8'))
def setLanguage(self, lang): self.languageStrings = None path = os.path.join(getSysDataPath("languages/"), lang + ".json") if not os.path.isfile(path): return with open(path, 'rU') as f: try: self.languageStrings = json.loads(f.read()) except: log.error('Error in language file %s', lang, exc_info=True) self.languageStrings = None self.language = lang self.rtl = False if self.languageStrings and '__options__' in self.languageStrings: self.rtl = self.languageStrings['__options__'].get('rtl', False)
def __init__(self): super(FootPoseAdapter, self).__init__() self.human = G.app.selectedHuman self.selectedFile = None self.selectedPose = None self._setting_pose = False self.sysDataPath = getpath.getSysDataPath('special_poses/foot') self.userPath = getpath.getDataPath('special_poses/foot') self.paths = [self.userPath, self.sysDataPath] if not os.path.exists(self.userPath): os.makedirs(self.userPath) skel = self.human.getBaseSkeleton() self.affected_bone_idxs = [skel.getBone(bone_name).index for bone_name in FOOT_BONES]
def visualizeFaceMasks(self, enabled): import material import getpath if enabled: self.oldPxyMats = dict() xray_mat = material.fromFile(getpath.getSysDataPath('materials/xray.mhmat')) for pxy in self.human.getProxies(includeHumanProxy=False): print pxy.type if pxy.type == 'Eyes': # Don't X-ray the eyes, it looks weird continue self.oldPxyMats[pxy.uuid] = pxy.object.material.clone() pxy.object.material = xray_mat else: for pxy in self.human.getProxies(includeHumanProxy=False): if pxy.uuid in self.oldPxyMats: pxy.object.material = self.oldPxyMats[pxy.uuid]
def _load_binary(self, name): if Target.npzfile is None: try: npzname = getSysDataPath('targets.npz') # TODO duplicate path literal Target.npzdir = os.path.dirname(npzname) Target.npzfile = np.load(npzname) Target.npztime = os.path.getmtime(npzname) except: log.message('no compressed targets found') Target.npzfile = False if Target.npzfile == False: # Fallback to old .bin files per target # TODO remove this self._load_binary_files(name) else: # Load target from npz archive name = os.path.relpath(name, Target.npzdir) self._load_binary_archive(name)
def __init__(self, mesh): guicommon.Object.__init__(self, mesh) self.hasWarpTargets = False self.MIN_AGE = 1.0 self.MAX_AGE = 90.0 self.MID_AGE = 25.0 self.mesh.setCameraProjection(0) self.mesh.setPickable(True) self.setShadeless(0) self.setCull(1) self.meshData = self.mesh self.maskFaces() self._hairProxy = None self._eyesProxy = None self._genitalsProxy = None self.eyebrowsProxy = None self.eyelashesProxy = None self.teethProxy = None self.tongueProxy = None self.clothesProxies = {} self.targetsDetailStack = {} # All details targets applied, with their values self.symmetryModeEnabled = False self.setDefaultValues() self.bodyZones = ['l-eye','r-eye', 'jaw', 'nose', 'mouth', 'head', 'neck', 'torso', 'hip', 'pelvis', 'r-upperarm', 'l-upperarm', 'r-lowerarm', 'l-lowerarm', 'l-hand', 'r-hand', 'r-upperleg', 'l-upperleg', 'r-lowerleg', 'l-lowerleg', 'l-foot', 'r-foot', 'ear'] self.material = material.fromFile(getSysDataPath('skins/default.mhmat')) self._defaultMaterial = material.Material().copyFrom(self.material) self._modifiers = dict() self._modifier_varMapping = dict() # Maps macro variable to the modifier group that modifies it self._modifier_dependencyMapping = dict() # Maps a macro variable to all the modifiers that depend on it self._modifier_groups = dict() self._modifier_type_cache = dict() self.blockEthnicUpdates = False # When set to True, changes to race are not normalized automatically