def drawSkeleton(self): self._unloadSkeletonMesh() skel = self.human.getSkeleton() if not skel: return # Create a mesh from the user-selected skeleton in its current pose (so we use the base skeleton for actually posing) self.skelMesh = skeleton_drawing.meshFromSkeleton(skel, "Prism") self.skelMesh.name = self.skelMesh.name + '-skeletonDebug' self.skelMesh.priority = 100 self.skelMesh.setPickable(False) self.skelObj = self.addObject( gui3d.Object(self.skelMesh, self.human.getPosition())) self.skelObj.setShadeless(0) self.skelObj.setSolid(0) self.skelObj.setRotation(self.human.getRotation()) self.skelMesh.setVisibility(self.showBonesTggl.selected) self.axisMesh = skeleton_drawing.meshFromSkeleton(skel, "axis") self.axisMesh.name = self.axisMesh.name + '-axis-skeletonDebug' self.axisMesh.priority = 100 self.axisMesh.setPickable(False) self.axisObj = self.addObject( gui3d.Object(self.axisMesh, self.human.getPosition())) self.axisObj.material.ambientColor = [0.2, 0.2, 0.2] self.axisObj.material.configureShading(vertexColors=True) self.axisObj.material.depthless = True self.axisObj.setRotation(self.human.getRotation()) self.axisObj.setVisibility(self.showAxisTggl.selected) self.drawPlanes(skel) mh.redraw()
def drawSkeleton(self, skel): if self.skelObj: # Remove old skeleton mesh self.removeObject(self.skelObj) self.human.removeBoundMesh(self.skelObj.name) self.skelObj = None self.skelMesh = None self.selectedBone = None if not skel: return # Create a mesh from the skeleton in rest pose skel.setToRestPose( ) # Make sure skeleton is in rest pose when constructing the skeleton mesh self.skelMesh = skeleton_drawing.meshFromSkeleton(skel, "Prism") self.skelMesh.name = 'SkeletonMesh-poseLibrary' self.skelMesh.priority = 100 self.skelMesh.setPickable(False) self.skelObj = self.addObject( gui3d.Object(self.skelMesh, self.human.getPosition())) self.skelObj.setShadeless(0) self.skelObj.setSolid(0) self.skelObj.setRotation(self.human.getRotation()) # Add the skeleton mesh to the human AnimatedMesh so it animates together with the skeleton # The skeleton mesh is supposed to be constructed from the skeleton in rest and receives # rigid vertex-bone weights (for each vertex exactly one weight of 1 to one bone) mapping = skeleton_drawing.getVertBoneMapping(skel, self.skelMesh) self.human.addBoundMesh(self.skelMesh, mapping) # Store a reference to the skeleton mesh object for other plugins self.human.getSkeleton().object = self.skelObj mh.redraw()
def finishBuild(self, location): coord = [] faces = [] group = [] for name, p, f in self._data: fg = self.mesh.createFaceGroup(name) coord.append(p) faces.append(f) group.append(np.zeros(len(f), dtype=np.uint16) + fg.idx) del self._data self.coords = np.vstack(coord) log.debug("finishBuild: %d %d", len(coord), len(self.coords)) self.mesh.setCoords(self.coords) self.mesh.setUVs(np.zeros((1, 2), dtype=np.float32)) self.mesh.setFaces(np.vstack(faces), None, np.hstack(group)) self.mesh.setCameraProjection(0) self.mesh.setShadeless(0) self.mesh.setSolid(0) self.mesh.calcNormals() self.mesh.updateIndexBuffer() self.mesh.priority = 30 self.object = gui3d.app.addObject(gui3d.Object(location, self.mesh)) for fg in self.mesh.faceGroups: if not fg.parent: log.debug("finishBuild: %s %s", fg, fg.parent) halt return self.object
def drawJointHelpers(self): """ Draw the joint helpers from the basemesh that define the default or reference rig. """ if self.jointsObj: self.removeObject(self.jointsObj) self.jointsObj = None self.jointsMesh = None self.selectedJoint = None jointPositions = [] # TODO maybe define a getter for this list in the skeleton module jointGroupNames = [group.name for group in self.human.meshData.faceGroups if group.name.startswith("joint-")] if self.human.getSkeleton(): jointGroupNames += self.human.getSkeleton().joint_pos_idxs.keys() for groupName in jointGroupNames: jointPositions.append(self.human.getSkeleton().getJointPosition(groupName, self.human)) else: for groupName in jointGroupNames: jointPositions.append(skeleton._getHumanJointPosition(self.human, groupName)) self.jointsMesh = skeleton_drawing.meshFromJoints(jointPositions, jointGroupNames) self.jointsMesh.priority = 100 self.jointsMesh.setPickable(False) self.jointsObj = self.addObject( gui3d.Object(self.jointsMesh, self.human.getPosition()) ) self.jointsObj.setRotation(self.human.getRotation()) color = np.asarray([255, 255, 0, 255], dtype=np.uint8) self.jointsMesh.color[:] = color[None,:] self.jointsMesh.markCoords(colr=True) self.jointsMesh.sync_color() mh.redraw()
def drawSkeleton(self): self._unloadSkeletonMesh() skel = self.human.getSkeleton() if not skel: return # Create a mesh from the skeleton in rest pose skel.setToRestPose( ) # Make sure skeleton is in rest pose when constructing the skeleton mesh self.skelMesh = skeleton_drawing.meshFromSkeleton(skel, "Prism") self.skelMesh.name = self.skelMesh.name + '-skeletonDebug' self.skelMesh.priority = 100 self.skelMesh.setPickable(False) self.skelObj = self.addObject( gui3d.Object(self.skelMesh, self.human.getPosition())) self.skelObj.setShadeless(0) self.skelObj.setSolid(0) self.skelObj.setRotation(self.human.getRotation()) # Add the skeleton mesh to the human AnimatedMesh so it animates together with the skeleton # The skeleton mesh is supposed to be constructed from the skeleton in rest and receives # rigid vertex-bone weights (for each vertex exactly one weight of 1 to one bone) mapping = skeleton_drawing.getVertBoneMapping(skel, self.skelMesh) self.human.addBoundMesh(self.skelMesh, mapping) self.human.refreshPose() # Pose drawn skeleton if human is posed mh.redraw()
def loadBVHRig(self, bvhRig): global SPARSIFY # Draw BVH skeleton if it does not exist yet if not self.bvhMesh: self.bvhSkel = bvhRig.createSkeleton() self.bvhMesh = skeleton_drawing.meshFromSkeleton(self.bvhSkel, "Prism") self.bvhMesh.priority = 100 self.bvhMesh.setColor([0, 255, 0, 255]) self.bvhObj = self.addObject(gui3d.Object(self.human.getPosition(), self.bvhMesh) ) self.bvhObj.setRotation(self.human.getRotation()) # Get rigid weights for skeleton mesh boneWeights = skeleton_drawing.getVertBoneMapping(self.bvhSkel, self.bvhMesh) self.bvhAnimated = animation.AnimatedMesh(self.bvhSkel, self.bvhMesh, boneWeights) # Load animation to BVH rig animName = unicode(os.path.splitext(os.path.basename(bvhRig.filename))[0]) trivialMap = [bone.name for bone in self.bvhSkel.getBones()] animTrack = bvhRig.createAnimationTrack(trivialMap, animName) animTrack.interpolationType = 0 if animTrack.frameRate > 30: animTrack.sparsify(30) self.bvhAnimated.addAnimation(animTrack)
def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Censor') self.mouseBox = self.addLeftWidget(gui.GroupBox('Censor')) self.enableCensor = self.mouseBox.addWidget( gui.CheckBox("Enable", gui3d.app.settings.get('censor', False))) human = gui3d.app.selectedHuman self.breastVertices = human.mesh.getVerticesForGroups( ['l-torso-nipple', 'r-torso-nipple']) mesh = geometry3d.RectangleMesh(100, 100) self.breastCensorship = gui3d.app.addObject( gui3d.Object([0, 0, 9], mesh)) mesh.setColor([0, 0, 0, 255]) mesh.setPickable(False) mesh.setShadeless(True) mesh.setDepthless(True) mesh.priority = 80 self.genitalVertices = human.mesh.getVerticesForGroups( ['pelvis-genital-area']) mesh = geometry3d.RectangleMesh(100, 100) self.genitalCensorship = gui3d.app.addObject( gui3d.Object([0, 0, 9], mesh)) mesh.setColor([0, 0, 0, 255]) mesh.setPickable(False) mesh.setShadeless(True) mesh.setDepthless(True) mesh.priority = 80 if gui3d.app.settings.get('censor', False): self.updateCensor() else: self.breastCensorship.hide() self.genitalCensorship.hide() @self.enableCensor.mhEvent def onClicked(event): gui3d.app.settings['censor'] = self.enableCensor.selected if self.enableCensor.selected: self.updateCensor() self.breastCensorship.show() self.genitalCensorship.show() else: self.breastCensorship.hide() self.genitalCensorship.hide()
def loadGrid(self): if self.backplaneGrid: self.removeObject(self.backplaneGrid) if self.groundplaneGrid: self.removeObject(self.groundplaneGrid) offset = self.selectedHuman.getJointPosition('ground')[1] spacing = 1 if self.settings['units'] == 'metric' else 3.048 # Background grid gridSize = int(200/spacing) if gridSize % 2 != 0: gridSize += 1 if self.settings['units'] == 'metric': subgrids = 10 else: subgrids = 12 backGridMesh = geometry3d.GridMesh(gridSize, gridSize, spacing, offset = -10, plane = 0, subgrids = subgrids) backGridMesh.setMainColor(self.gridColor) backGridMesh.setSubColor(self.gridSubColor) backGridMesh.lockRotation = True backGridMesh.restrictVisibleToCamera = True backGridMesh.minSubgridZoom = (1.0/spacing) * float(subgrids)/5 self.backplaneGrid = gui3d.Object(backGridMesh) self.backplaneGrid.excludeFromProduction = True self.backplaneGrid.placeAtFeet = True self.backplaneGrid.setShadeless(1) #self.backplaneGrid.setPosition([0,offset,0]) self.addObject(self.backplaneGrid) # Ground grid gridSize = int(20/spacing) if gridSize % 2 != 0: gridSize += 1 groundGridMesh = geometry3d.GridMesh(gridSize, gridSize, spacing, offset = 0, plane = 1, subgrids = subgrids) groundGridMesh.setMainColor(self.gridColor) groundGridMesh.setSubColor(self.gridSubColor) groundGridMesh.minSubgridZoom = (1.0/spacing) * float(subgrids)/5 self.groundplaneGrid = gui3d.Object(groundGridMesh) self.groundplaneGrid.excludeFromProduction = True self.groundplaneGrid.placeAtFeet = True self.groundplaneGrid.setShadeless(1) #self.groundplaneGrid.setPosition([0,offset,0]) groundGridMesh.restrictVisibleAboveGround = True self.addObject(self.groundplaneGrid)
def drawSkeleton(self, skel): if self.skelObj: # Remove old skeleton mesh gui3d.app.removeObject(self.skelObj) self.skelObj = None self.skelMesh = None self.selectedBone = None # Create a mesh from the skeleton in rest pose skel.setToRestPose( ) # Make sure skeleton is in rest pose when constructing the skeleton mesh self.skelMesh = skeleton_drawing.meshFromSkeleton(skel, "Prism") self.skelMesh.priority = 100 self.skelMesh.setPickable(True) mh.updatePickingBuffer() self.skelObj = gui3d.app.addObject( gui3d.Object(self.human.getPosition(), self.skelMesh)) self.skelObj.setRotation(self.human.getRotation()) # Add the skeleton mesh to the human AnimatedMesh so it animates together with the skeleton # The skeleton mesh is supposed to be constructed from the skeleton in rest and receives # rigid vertex-bone weights (for each vertex exactly one weight of 1 to one bone) mapping = skeleton_drawing.getVertBoneMapping(skel, self.skelMesh) self.human.animated.addMesh(self.skelMesh, mapping) # Store a reference to the skeleton mesh object for other plugins self.human._skeleton.object = self.skelObj # Add event listeners to skeleton mesh for bone highlighting @self.skelObj.mhEvent def onMouseEntered(event): """ Event fired when mouse hovers over a skeleton mesh facegroup """ gui3d.TaskView.onMouseEntered(self, event) try: self.removeBoneHighlights() except: pass self.highlightBone(event.group.name) @self.skelObj.mhEvent def onMouseExited(event): """ Event fired when mouse hovers off of a skeleton mesh facegroup """ gui3d.TaskView.onMouseExited(self, event) try: self.removeBoneHighlights() except: pass # Highlight bone selected in bone explorer again for rdio in self.boneSelector: if rdio.selected: self.clearBoneWeights() self.highlightBone(str(rdio.text()))
def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Save') modelPath = mh.getPath('models') self.fileentry = self.addTopWidget(gui.FileEntryView('Save')) self.fileentry.setDirectory(modelPath) self.fileentry.setFilter('MakeHuman Models (*.mhm)') self.selection_width = 1.2 self.selection_height = 1.3 mesh = geometry3d.FrameMesh(self.selection_width, self.selection_height) mesh.move(-self.selection_width / 2, -self.selection_height / 2) self.selection = gui3d.app.addObject(gui3d.Object([0, 0, 9], mesh)) mesh.setColor([0, 0, 0, 255]) mesh.setPickable(False) mesh.setShadeless(True) mesh.setDepthless(True) mesh.priority = 90 self.selection.hide() @self.fileentry.mhEvent def onFileSelected(filename): if not filename.lower().endswith('.mhm'): filename += '.mhm' path = os.path.normpath(os.path.join(modelPath, filename)) dir, name = os.path.split(path) name, ext = os.path.splitext(name) if not os.path.exists(dir): os.makedirs(dir) # Save the thumbnail ((x0, y0, z0), (x1, y1, z1)) = self.selection.mesh.calcBBox() x0, y0, z0 = gui3d.app.guiCamera.convertToScreen(x0, y0, 0) x1, y1, z1 = gui3d.app.guiCamera.convertToScreen(x1, y1, 0) log.debug('grab rectangle: %d %d %d %d', x0, y0, x1, y1) mh.grabScreen(int(x0 + 1), int(y1 + 1), int(x1 - x0 - 1), int(y0 - y1 - 1), os.path.join(dir, name + '.thumb')) # Save the model human = gui3d.app.selectedHuman human.save(path, name) gui3d.app.modified = False #gui3d.app.clearUndoRedo() gui3d.app.setFilenameCaption(filename) gui3d.app.setFileModified(False) mh.changeCategory('Modelling')
def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Proportional editing', label='Edit') self.radius = 1.0 self.start = None self.center = None self.axis = None self.depth = None self.original = None self.normals = None self.weights = None self.verts = None self.faces = None self.smoothed = None self.converter = ValueConverter() value = self.converter.displayToData(self.radius) self.radiusSlider = self.addLeftWidget(gui.Slider(value, min=-5.0, max=3.0, label="Radius", valueConverter=self.converter)) self.clear = self.addLeftWidget(gui.Button("Clear")) self.modeBox = self.addLeftWidget(gui.GroupBox("Mode")) modes = [] self.grab = self.modeBox.addWidget(gui.RadioButton(modes, "Grab", selected=True)) self.norm = self.modeBox.addWidget(gui.RadioButton(modes, "Normal")) self.scalex = self.modeBox.addWidget(gui.RadioButton(modes, "Scale X")) self.scaley = self.modeBox.addWidget(gui.RadioButton(modes, "Scale Y")) self.scalez = self.modeBox.addWidget(gui.RadioButton(modes, "Scale Z")) self.rotate = self.modeBox.addWidget(gui.RadioButton(modes, "Rotate")) self.smooth = self.modeBox.addWidget(gui.RadioButton(modes, "Smooth")) self.buildCircle() self.updateRadius() self.circle = self.addObject(gui3d.Object(self.circleMesh)) @self.clear.mhEvent def onClicked(dummy): human = gui3d.app.selectedHuman targets = [] for name in human.targetsDetailStack.keys(): if isinstance(algos3d.getTarget(human, name), EditTarget): targets.append(name) gui3d.app.do(EditAction(human, targets, 0.0)) @self.radiusSlider.mhEvent def onChanging(value): self.radius = self.converter.dataToDisplay(value) self.updateRadius() @self.radiusSlider.mhEvent def onChange(value): self.radius = self.converter.dataToDisplay(value) self.updateRadius()
def drawSkeleton(self, skel): # Create a mesh from the skeleton in rest pose skel.setToRestPose() # Make sure skeleton is in rest pose when constructing the skeleton mesh self.skelMesh = skeleton_drawing.meshFromSkeleton(skel, "Prism") self.skelMesh.priority = 100 self.skelObj = self.addObject(gui3d.Object(self.human.getPosition(), self.skelMesh) ) self.skelObj.setRotation(self.human.getRotation()) # Add the skeleton mesh to the human AnimatedMesh so it animates together with the skeleton # The skeleton mesh is supposed to be constructed from the skeleton in rest and receives # rigid vertex-bone weights (for each vertex exactly one weight of 1 to one bone) mapping = skeleton_drawing.getVertBoneMapping(skel, self.skelMesh) self.animated.addMesh(self.skelMesh, mapping) self.setShowRig(self.showMHXRigTggl.selected)
def setHair(self, human, mhclo): self.filechooser.selectItem(mhclo) if human.hairObj: gui3d.app.removeObject(human.hairObj) human.hairObj = None human.hairProxy = None if os.path.basename(mhclo) == "clear.mhclo": return human.hairProxy = mh2proxy.readProxyFile(human.meshData, mhclo) human.hairProxy.type = 'Hair' if not human.hairProxy: log.error("Failed to load %s", mhclo) return obj = human.hairProxy.obj_file obj = os.path.join(obj[0], obj[1]) mesh = files3d.loadMesh(obj) if not mesh: log.error("Failed to load %s", obj) return if human.hairProxy.texture: (folder, name) = human.hairProxy.texture tex = os.path.join(folder, name) mesh.setTexture(tex) else: tex = obj.replace('.obj', '_texture.png') mesh.setTexture(tex) human.hairObj = gui3d.app.addObject(gui3d.Object(human.getPosition(), mesh)) human.hairObj.setRotation(human.getRotation()) human.hairObj.mesh.setCameraProjection(0) human.hairObj.mesh.setSolid(human.mesh.solid) if human.hairProxy.cull: human.hairObj.mesh.setCull(1) else: human.hairObj.mesh.setCull(None) human.hairObj.mesh.setTransparentPrimitives(len(human.hairObj.mesh.fvert)) human.hairObj.mesh.priority = 20 hairName = human.hairObj.mesh.name.split('.')[0] self.adaptHairToHuman(human) human.hairObj.setSubdivided(human.isSubdivided())
def drawBVHSkeleton(skeleton, human): bvhMesh = module3d.Object3D('bvhskeleton') bvhMesh.uvValues = [] bvhMesh.indexBuffer = [] _drawBVHJoint(skeleton.root, bvhMesh) bvhMesh.setCameraProjection(0) bvhMesh.setShadeless(0) bvhMesh.setSolid(0) bvhMesh.calcNormals() bvhMesh.updateIndexBuffer() bvhObject = gui3d.Object(aljabr.vadd(human.getPosition(), [0.0, 0.0, 0.0]), bvhMesh) bvhObject.setRotation(human.getRotation()) return bvhObject
def draw(self): skeletonMesh = module3d.Object3D('skeleton') skeletonMesh.uvValues = [] skeletonMesh.indexBuffer = [] self.root.draw(skeletonMesh) skeletonMesh.setCameraProjection(0) skeletonMesh.setShadeless(0) skeletonMesh.setSolid(0) skeletonMesh.calcNormals() skeletonMesh.updateIndexBuffer() skeletonObject = gui3d.Object( vadd(self.human.getPosition(), [0.0, 0.0, 0.0]), skeletonMesh) skeletonObject.mesh.setCameraProjection(0) skeletonObject.setRotation(self.human.getRotation()) return skeletonObject
def drawSkeleton(self): if self.skelObj: # Remove old skeleton mesh self.removeObject(self.skelObj) self.skelObj = None self.skelMesh = None skel = self.human.getSkeleton() if not skel: return # Create a mesh from the skeleton self.skelMesh = skeleton_drawing.meshFromSkeleton(skel, "Prism") self.skelMesh.priority = 100 self.skelMesh.setPickable(False) self.skelObj = self.addObject(gui3d.Object(self.skelMesh, self.human.getPosition()) ) self.skelObj.setShadeless(0) self.skelObj.setSolid(0) self.skelObj.setRotation(self.human.getRotation()) mh.redraw()
def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Background') self.human = gui3d.app.selectedHuman self.backgroundsFolder = mh.getPath('backgrounds') if not os.path.exists(self.backgroundsFolder): os.makedirs(self.backgroundsFolder) self.backgroundsFolders = [ mh.getSysDataPath('backgrounds'), self.backgroundsFolder ] self.extensions = ['bmp', 'png', 'tif', 'tiff', 'jpg', 'jpeg'] self.texture = mh.Texture() self.sides = { 'front': [0,0,0], 'back': [0,180,0], 'left': [0,-90,0], 'right': [0,90,0], 'top': [90,0,0], 'bottom': [-90,0,0], 'other': None } self.filenames = {} # Stores (filename, aspect) self.transformations = {} # Stores ((posX,posY), scaleY) for side in self.sides.keys(): self.filenames[side] = None self.transformations[side] = [(0.0, 0.0), 1.0] self.planeMeshes = dict() self.opacity = 40 for viewName, rot in self.sides.items(): if rot is not None: rv = [0, 0, 0] angle = 0.0 for r_idx, r in enumerate(rot): if r != 0: rv[r_idx] = 1 angle = math.radians(r) if angle == 0: m = None else: m = tm.rotation_matrix(-angle, rv) else: m = None mesh = geometry3d.RectangleMesh(20, 20, centered=True, rotation=m) mesh.name = "Background_%s" % viewName obj = gui3d.app.addObject(gui3d.Object(mesh, [0, 0, 0], visible=False)) obj.setShadeless(True) obj.setDepthless(True) #obj.placeAtFeet = True mesh.setCameraProjection(0) mesh.setColor([255, 255, 255, self.opacity*2.55]) mesh.setPickable(False) mesh.priority = -90 self.planeMeshes[viewName] = obj if viewName == 'other': obj.lockRotation = True @obj.mhEvent def onMouseDragged(event): if event.button in [mh.Buttons.LEFT_MASK, mh.Buttons.MIDDLE_MASK]: if mh.getKeyModifiers() & (mh.Modifiers.SHIFT): delta = 150.0 else: delta = 30.0 dx = float(event.dx)/delta dy = float(-event.dy)/delta self.moveBackground(dx, dy) elif event.button == mh.Buttons.RIGHT_MASK: if mh.getKeyModifiers() & (mh.Modifiers.SHIFT): delta = 500.0 else: delta = 100.0 scale = self.getBackgroundScale() scale += float(event.dy)/delta self.setBackgroundScale(scale) # Add icon to action toolbar self.backgroundImageToggle = gui.Action('background', 'Background', self.toggleBackground, toggle=True) gui3d.app.view_toolbar.addAction(self.backgroundImageToggle) gui3d.app.actions.background = self.backgroundImageToggle #self.filechooser = self.addTopWidget(fc.FileChooser(self.backgroundsFolders, self.extensions, None)) #self.addLeftWidget(self.filechooser.sortBox) self.filechooser = self.addRightWidget(fc.IconListFileChooser(self.backgroundsFolders, self.extensions, None, None, 'Background', noneItem=True)) self.filechooser.setIconSize(50,50) self.filechooser.enableAutoRefresh(False) #self.addLeftWidget(self.filechooser.createSortBox()) self.backgroundBox = self.addLeftWidget(gui.GroupBox('Side')) self.bgSettingsBox = self.addLeftWidget(gui.GroupBox('Background settings')) self.radioButtonGroup = [] for side in ['front', 'back', 'left', 'right', 'top', 'bottom', 'other']: radioBtn = self.backgroundBox.addWidget(gui.RadioButton(self.radioButtonGroup, label=side.capitalize(), selected=len(self.radioButtonGroup)==0)) radioBtn.side = side @radioBtn.mhEvent def onClicked(value): side = self.sides[self.getSelectedSideCheckbox()] if side: gui3d.app.axisView(side) self.refreshFileChooser() self.opacitySlider = self.bgSettingsBox.addWidget(gui.Slider(value=self.opacity, min=0,max=100, label = ["Opacity",": %d%%"])) self.dragButton = self.bgSettingsBox.addWidget(gui.CheckBox('Move && Resize')) self.foregroundTggl = self.bgSettingsBox.addWidget(gui.CheckBox("Show in foreground")) @self.opacitySlider.mhEvent def onChanging(value): for obj in self.planeMeshes.values(): obj.mesh.setColor([255, 255, 255, 2.55*value]) @self.opacitySlider.mhEvent def onChange(value): self.opacity = value for obj in self.planeMeshes.values(): obj.mesh.setColor([255, 255, 255, 2.55*value]) @self.foregroundTggl.mhEvent def onClicked(value): self.setShowBgInFront(self.foregroundTggl.selected) @self.filechooser.mhEvent def onFileSelected(filename): side = self.getSelectedSideCheckbox() if self.filenames[side]: oldBg = self.filenames[side][0] else: oldBg = None gui3d.app.do(BackgroundAction("Change background", self, side, oldBg, filename)) mh.redraw() @self.dragButton.mhEvent def onClicked(event): for obj in self.planeMeshes.values(): obj.mesh.setPickable(self.dragButton.selected) gui3d.app.selectedHuman.mesh.setPickable(not self.dragButton.selected) mh.redraw()
def __init__(self, category): # Setup GUI elements gui3d.TaskView.__init__(self, category, 'Actions') box = self.addLeftWidget(gui.GroupBox('Export')) self.rigButton = box.addWidget(FileSelectView('Load BVH')) self.rigButton.setDirectory(DATA_PATH) self.rigButton.setFilter('Biovision Motion Hierarchy (*.bvh)') self.exportButton = box.addWidget(gui.Button('Export animation')) self.exportAllButton = box.addWidget(gui.Button('Export all')) self.window = None @self.rigButton.mhEvent def onFilesSelected(filenames): if not self.skel: self.loadRig() loadFirst = (self.animationList.rowCount() == 0) for filename in filenames: if filename not in self.selectedBVHs: item = self.animationList.addItem(os.path.splitext(os.path.basename(filename))[0]) item.filename = filename self.selectedBVHs.add(filename) if loadFirst: self.loadAnimation(filenames[0]) @self.exportButton.mhEvent def onClicked(event): self.export() @self.exportAllButton.mhEvent def onClicked(event): self.exportAll() self.human = gui3d.app.selectedHuman self.humanChanged = False self.humanTransparent = False self.selectedBVHs = set() self.skel = None self.animated = None self.bvhAnimated = None self.skelMesh = None self.skelObj = None self.bvhMesh = None self.bvhObj = None self.timer = None self.currFrame = 0 self.anim = None self.bvhAnim = None self.oldHumanTransp = self.human.meshData.transparentPrimitives optionsBox = self.addLeftWidget(gui.GroupBox('Options')) self.kinectCamTggle = optionsBox.addWidget(gui.ToggleButton("Kinect camera")) self.kinectCamTggle.setSelected(True) self.useMHCamTggl = optionsBox.addWidget(gui.ToggleButton("Use camera pos")) self.useMHCamTggl.setSelected(False) mesh = BackPlane(20, 20, centered=True) self.bgPlane = self.addObject(gui3d.Object([0, 0, 0], mesh)) mesh.setColor([255, 255, 255, 255]) mesh.setShadeless(True) mesh.priority = -90 mesh = GroundPlane(20, 20, centered=True) self.groundPlane = self.addObject(gui3d.Object([0, 0, 0], mesh)) mesh.setColor([0, 0, 0, 255]) mesh.setShadeless(True) mesh.priority = -90 yOffset = self.getFeetOnGroundOffset() self.groundposSlider = optionsBox.addWidget(gui.Slider(value=int(yOffset), min=-125,max=125, label = "Ground Pos: %d")) self.groundposVal = int(yOffset) self.groundPlane.mesh.move(0,yOffset,0) @self.groundposSlider.mhEvent def onChanging(value): val = value - self.groundposVal self.groundPlane.mesh.move(0,val,0) self.groundposVal = self.groundposVal + val @self.groundposSlider.mhEvent def onChange(value): val = value - self.groundposVal self.groundPlane.mesh.move(0,val,0) self.groundposVal = self.groundposVal + val self.backposSlider = optionsBox.addWidget(gui.Slider(value=-9, min=-125,max=125, label = "Back Pos: %d")) self.backposVal = -9 @self.backposSlider.mhEvent def onChanging(value): val = value - self.backposVal self.bgPlane.mesh.move(0,0,val) self.backposVal = self.backposVal + val @self.backposSlider.mhEvent def onChange(value): val = value - self.backposVal self.bgPlane.mesh.move(0,0,val) self.backposVal = self.backposVal + val self.bgPlane.mesh.move(0,0,self.backposVal) displayBox = self.addRightWidget(gui.GroupBox('Display')) self.showHumanTggl = displayBox.addWidget(gui.ToggleButton("Show human")) @self.showHumanTggl.mhEvent def onClicked(event): if self.showHumanTggl.selected: self.human.show() else: self.human.hide() self.showHumanTggl.setSelected(True) self.showMHXRigTggl = displayBox.addWidget(gui.ToggleButton("Show human Rig")) @self.showMHXRigTggl.mhEvent def onClicked(event): self.setShowRig(self.showMHXRigTggl.selected) self.showMHXRigTggl.setSelected(True) self.showBVHRigTggl = displayBox.addWidget(gui.ToggleButton("Show BVH Rig")) @self.showBVHRigTggl.mhEvent def onClicked(event): self.setShowBVHRig(self.showBVHRigTggl.selected) self.showBVHRigTggl.setSelected(False) self.imageExported = False self.playbackBox = None self.playPause = None self.createPlaybackControl() animationListBox = self.addRightWidget(gui.GroupBox('BVHs')) self.animationList = animationListBox.addWidget(gui.ListView()) self.animationList.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.MinimumExpanding) self.animationList.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) @self.animationList.mhEvent def onClicked(item): self.loadAnimation(item.filename) self.removeAnimBtn = animationListBox.addWidget(gui.Button('Remove selected')) @self.removeAnimBtn.mhEvent def onClicked(item): print "remove clicked" if len(self.animationList.selectedItems()) > 0: print "taking action" item = self.animationList.selectedItems()[0] self.removeAnimation(item.filename)
def setClothes(self, human, filepath): if os.path.basename(filepath) == "clear.mhclo": for name,clo in human.clothesObjs.items(): gui3d.app.removeObject(clo) del human.clothesObjs[name] human.clothesProxies = {} self.clothesList = [] human.activeClothing = None self.updateFaceMasks(self.faceHidingTggl.selected) return if filepath not in self.cache: proxy = mh2proxy.readProxyFile(human.meshData, filepath) proxy.type = 'Clothes' self.cache[filepath] = proxy proxy.toggleEnabled = False else: proxy = self.cache[filepath] if not proxy: return uuid = proxy.getUuid() # TODO costumes should go in a separate library ''' # For loading costumes (sets of individual clothes) if proxy.clothings: t = 0 dt = 1.0/len(proxy.clothings) folder = os.path.dirname(filepath) for (pieceName, uuid) in proxy.clothings: gui3d.app.progress(t, text="Loading %s" % pieceName) t += dt piecePath = os.path.join(folder, pieceName+".mhclo") mhclo = exportutils.config.getExistingProxyFile(piecePath, uuid, "clothes") if mhclo: self.setClothes(human, mhclo) else: log.warning("Could not load clothing %s", pieceName) gui3d.app.progress(1, text="%s loaded" % proxy.name) # Load custom textures for (uuid, texPath) in proxy.textures: if not uuid in human.clothesObjs.keys(): log.warning("Cannot override texture for clothing piece with uuid %s!" % uuid) continue pieceProxy = human.clothesProxies[uuid] if not os.path.dirname(texPath): pieceProxy = human.clothesProxies[uuid] clothesPath = os.path.dirname(pieceProxy.file) texPath = os.path.join(clothesPath, texPath) log.debug("Overriding texture for clothpiece %s to %s", uuid, texPath) clo = human.clothesObjs[uuid] clo.mesh.setTexture(texPath) # Apply overridden transparency setting to pieces of a costume for (uuid, isTransparent) in proxy.transparencies.items(): if not uuid in human.clothesProxies.keys(): log.warning("Could not override transparency for object with uuid %s!" % uuid) continue clo = human.clothesObjs[uuid] log.debug("Overriding transparency setting for clothpiece %s to %s", uuid, bool(proxy.transparencies[uuid])) if proxy.transparencies[uuid]: clo.mesh.setTransparentPrimitives(len(clo.mesh.fvert)) else: clo.mesh.setTransparentPrimitives(0) return ''' #folder = os.path.dirname(filepath) (folder, name) = proxy.obj_file obj = os.path.join(folder, name) try: clo = human.clothesObjs[uuid] except: clo = None if clo: gui3d.app.removeObject(clo) del human.clothesObjs[uuid] self.clothesList.remove(uuid) if human.activeClothing == uuid: human.activeClothing = None proxy = human.clothesProxies[uuid] del human.clothesProxies[uuid] self.updateFaceMasks(self.faceHidingTggl.selected) self.filechooser.deselectItem(proxy.file) log.message("Removed clothing %s %s", proxy.name, uuid) return if obj not in self.meshCache: mesh = files3d.loadMesh(obj) self.meshCache[obj] = mesh else: mesh = self.meshCache[obj] if not mesh: log.error("Could not load mesh for clothing object %s", proxy.name) return if proxy.texture: (dir, name) = proxy.texture tex = os.path.join(folder, name) if not os.path.exists(tex): tex = os.path.join(self.systemClothes, "textures", name) mesh.setTexture(tex) clo = gui3d.app.addObject(gui3d.Object(human.getPosition(), mesh)) clo.setRotation(human.getRotation()) clo.mesh.setCameraProjection(0) clo.mesh.setSolid(human.mesh.solid) if proxy.cull: clo.mesh.setCull(1) else: clo.mesh.setCull(None) if proxy.transparent: clo.mesh.setTransparentPrimitives(len(clo.mesh.fvert)) else: clo.mesh.setTransparentPrimitives(0) clo.mesh.priority = 10 human.clothesObjs[uuid] = clo human.clothesProxies[uuid] = proxy human.activeClothing = uuid self.clothesList.append(uuid) # TODO Disabled until conflict with new filechooser is sorted out ''' for tag in proxy.tags: tag = tag.lower() # Allow only one piece of clothing per known tag if tag in KnownTags: try: oldUuids = self.taggedClothes[tag] except KeyError: oldUuids = [] newUuids = [] for oldUuid in oldUuids: if oldUuid == uuid: pass elif True: # TODO use parameter here try: oldClo = human.clothesObjs[oldUuid] except KeyError: continue gui3d.app.removeObject(oldClo) del human.clothesObjs[oldUuid] self.clothesList.remove(oldUuid) if human.activeClothing == oldUuid: human.activeClothing = None log.message("Removed clothing %s with known tag %s", oldUuid, tag) else: log.message("Kept clothing %s with known tag %s", oldUuid, tag) newUuids.append(oldUuid) newUuids.append(uuid) self.taggedClothes[tag] = newUuids ''' self.adaptClothesToHuman(human) clo.setSubdivided(human.isSubdivided()) #self.clothesButton.setTexture(obj.replace('.obj', '.png')) self.orderRenderQueue() self.updateFaceMasks(self.faceHidingTggl.selected)
def setClothes(self, human, filepath): if os.path.basename(filepath) == "clear.mhclo": for name,clo in human.clothesObjs.items(): gui3d.app.removeObject(clo) del human.clothesObjs[name] self.clothesList = [] human.activeClothing = None return proxy = mh2proxy.readProxyFile(human.meshData, filepath, False) if not proxy: return uuid = proxy.getUuid() # For loading costumes (sets of individual clothes) if proxy.clothings: t = 0 dt = 1.0/len(proxy.clothings) for (pieceName, uuid) in proxy.clothings: gui3d.app.progress(t, text="Loading %s" % pieceName) t += dt mhclo = export_config.getExistingProxyFile(pieceName+".mhclo", uuid, "clothes") if mhclo: self.setClothes(human, mhclo) else: log.warning("Could not load clothing %s", pieceName) gui3d.app.progress(1, text="%s loaded" % proxy.name) # Load custom textures for (uuid, texPath) in proxy.textures: if not uuid in human.clothesObjs.keys(): log.warning("Cannot override texture for clothing piece with uuid %s!" % uuid) continue pieceProxy = human.clothesProxies[uuid] if not os.path.dirname(texPath): pieceProxy = human.clothesProxies[uuid] clothesPath = os.path.dirname(pieceProxy.file) texPath = os.path.join(clothesPath, texPath) log.debug("Overriding texture for clothpiece %s to %s", uuid, texPath) clo = human.clothesObjs[uuid] clo.mesh.setTexture(texPath) # Apply overridden transparency setting to pieces of a costume for (uuid, isTransparent) in proxy.transparencies.items(): if not uuid in human.clothesProxies.keys(): log.warning("Could not override transparency for object with uuid %s!" % uuid) continue clo = human.clothesObjs[uuid] log.debug("Overriding transparency setting for clothpiece %s to %s", uuid, bool(proxy.transparencies[uuid])) if proxy.transparencies[uuid]: clo.mesh.setTransparentPrimitives(len(clo.mesh.faces)) else: clo.mesh.setTransparentPrimitives(0) return #folder = os.path.dirname(filepath) (folder, name) = proxy.obj_file obj = os.path.join(folder, name) try: clo = human.clothesObjs[uuid] except: clo = None if clo: gui3d.app.removeObject(clo) del human.clothesObjs[uuid] self.clothesList.remove(uuid) if human.activeClothing == uuid: human.activeClothing = None log.message("Removed clothing %s %s", proxy.name, uuid) return mesh = files3d.loadMesh(obj) if not mesh: log.error("Could not load mesh for clothing object %s", proxy.name) return if proxy.texture: (dir, name) = proxy.texture tex = os.path.join(folder, name) if not os.path.exists(tex): tex = os.path.join(self.systemClothes, "textures", name) mesh.setTexture(tex) else: pass clo = gui3d.app.addObject(gui3d.Object(human.getPosition(), mesh)) clo.setRotation(human.getRotation()) clo.mesh.setCameraProjection(0) clo.mesh.setSolid(human.mesh.solid) if proxy.cull: clo.mesh.setCull(1) else: clo.mesh.setCull(None) if proxy.transparent: clo.mesh.setTransparentPrimitives(len(clo.mesh.faces)) else: clo.mesh.setTransparentPrimitives(0) clo.mesh.priority = 10 human.clothesObjs[uuid] = clo human.clothesProxies[uuid] = proxy human.activeClothing = uuid self.clothesList.append(uuid) for tag in proxy.tags: tag = tag.lower() if tag in KnownTags: try: oldUuids = self.taggedClothes[tag] except KeyError: oldUuids = [] newUuids = [] for oldUuid in oldUuids: if oldUuid == uuid: pass elif True: try: oldClo = human.clothesObjs[oldUuid] except KeyError: continue log.message("Removed clothing %s", oldUuid) gui3d.app.removeObject(oldClo) del human.clothesObjs[oldUuid] self.clothesList.remove(oldUuid) if human.activeClothing == oldUuid: human.activeClothing = None else: log.message("Kept clothing %s", oldUuid) newUuids.append(oldUuid) newUuids.append(uuid) self.taggedClothes[tag] = newUuids self.adaptClothesToHuman(human) clo.setSubdivided(human.isSubdivided())
def drawJointHelpers(self): """ Draw the joint helpers from the basemesh that define the default or reference rig. """ if self.jointsObj: self.removeObject(self.jointsObj) self.jointsObj = None self.jointsMesh = None self.selectedJoint = None jointGroupNames = [ group.name for group in self.human.meshData.faceGroups if group.name.startswith("joint-") ] # TODO maybe define a getter for this list in the skeleton module jointPositions = [] for groupName in jointGroupNames: jointPositions.append( skeleton.getHumanJointPosition(self.human.meshData, groupName)) self.jointsMesh = skeleton_drawing.meshFromJoints( jointPositions, jointGroupNames) self.jointsMesh.priority = 100 self.jointsMesh.setPickable(True) mh.updatePickingBuffer() self.jointsObj = self.addObject( gui3d.Object(self.human.getPosition(), self.jointsMesh)) self.jointsObj.setRotation(self.human.getRotation()) color = np.asarray([255, 255, 0, 255], dtype=np.uint8) self.jointsMesh.color[:] = color[None, :] self.jointsMesh.markCoords(colr=True) self.jointsMesh.sync_color() # Add event listeners to joint mesh for joint highlighting @self.jointsObj.mhEvent def onMouseEntered(event): """ Event fired when mouse hovers over a joint mesh facegroup """ gui3d.TaskView.onMouseEntered(self, event) # Highlight joint self.selectedJoint = event.group setColorForFaceGroup(self.jointsMesh, self.selectedJoint.name, [216, 110, 39, 255]) gui3d.app.statusPersist(event.group.name) gui3d.app.redraw() @self.jointsObj.mhEvent def onMouseExited(event): """ Event fired when mouse hovers off of a joint mesh facegroup """ gui3d.TaskView.onMouseExited(self, event) # Disable highlight on joint if self.selectedJoint: setColorForFaceGroup(self.jointsMesh, self.selectedJoint.name, [255, 255, 0, 255]) gui3d.app.statusPersist('') gui3d.app.redraw()
def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Measure') self.ruler = Ruler() self.measureMesh = module3d.Object3D('measure', 2) self.measureMesh.createFaceGroup('measure') names = [] for n, v in self.ruler.Measures.items(): if len(v) % 2 != 0: names.append(n) if len(names) > 0: raise RuntimeError( "One or more measurement rulers contain an uneven number of vertex indices. It's required that they are pairs indicating the begin and end point of every line to draw. Rulers with uneven index count: %s" % ", ".join(names)) del names count = max([len(vertIdx) for vertIdx in self.ruler.Measures.values()]) self.measureMesh.setCoords(np.zeros((count, 3), dtype=np.float32)) self.measureMesh.setUVs(np.zeros((1, 2), dtype=np.float32)) self.measureMesh.setFaces(np.arange(count).reshape((-1, 2))) self.measureMesh.setCameraProjection(0) self.measureMesh.setShadeless(True) self.measureMesh.setDepthless(True) self.measureMesh.setColor([255, 255, 255, 255]) self.measureMesh.setPickable(0) self.measureMesh.updateIndexBuffer() self.measureMesh.priority = 50 self.measureObject = self.addObject(gui3d.Object(self.measureMesh)) measurements = [ ('neck', ['neckcirc', 'neckheight']), ('upperarm', ['upperarm', 'upperarmlenght']), ('lowerarm', ['lowerarmlenght', 'wrist']), ('torso', [ 'frontchest', 'bust', 'underbust', 'waist', 'napetowaist', 'waisttohip', 'shoulder' ]), ('hips', ['hips']), ('upperleg', ['upperlegheight', 'thighcirc']), ('lowerleg', ['lowerlegheight', 'calf']), ('ankle', ['ankle']), ] sliderLabel = { 'neckcirc': 'Neck circum', 'neckheight': 'Neck height', 'upperarm': 'Upper arm circum', 'upperarmlenght': 'Upperarm length', 'lowerarmlenght': 'Lowerarm length', 'wrist': 'Wrist circum', 'frontchest': 'Front chest dist', 'bust': 'Bust circum', 'underbust': 'Underbust circum', 'waist': 'Waist circum', 'napetowaist': 'Nape to waist', 'waisttohip': 'Waist to hip', 'shoulder': 'Shoulder dist', 'hips': 'Hips circum', 'upperlegheight': 'Upperleg height', 'thighcirc': 'Thigh circ.', 'lowerlegheight': 'Lowerleg height', 'calf': 'Calf circum', 'ankle': 'Ankle circum' } self.groupBoxes = {} self.radioButtons = [] self.sliders = [] self.active_slider = None self.modifiers = {} measureDataPath = mh.getSysDataPath("targets/measure/") self.categoryBox = self.addRightWidget(gui.GroupBox('Category')) self.groupBox = self.addLeftWidget(gui.StackedBox()) for name, subnames in measurements: # Create box box = self.groupBox.addWidget(gui.SliderBox(name.capitalize())) self.groupBoxes[name] = box # Create radiobutton box.radio = self.categoryBox.addWidget( GroupBoxRadioButton(self, self.radioButtons, name.capitalize(), box, selected=len(self.radioButtons) == 0)) # Create sliders for subname in subnames: # TODO use another modifier modifier = humanmodifier.Modifier( os.path.join(measureDataPath, "measure-%s-decrease.target" % subname), os.path.join(measureDataPath, "measure-%s-increase.target" % subname)) modifier.setHuman(gui3d.app.selectedHuman) self.modifiers[subname] = modifier slider = box.addWidget( MeasureSlider(sliderLabel[subname], self, subname, modifier)) self.sliders.append(slider) self.lastActive = None self.statsBox = self.addRightWidget(gui.GroupBox('Statistics')) self.height = self.statsBox.addWidget(gui.TextView('Height: ')) self.chest = self.statsBox.addWidget(gui.TextView('Chest: ')) self.waist = self.statsBox.addWidget(gui.TextView('Waist: ')) self.hips = self.statsBox.addWidget(gui.TextView('Hips: ')) ''' self.braBox = self.addRightWidget(gui.GroupBox('Brassiere size')) self.eu = self.braBox.addWidget(gui.TextView('EU: ')) self.jp = self.braBox.addWidget(gui.TextView('JP: ')) self.us = self.braBox.addWidget(gui.TextView('US: ')) self.uk = self.braBox.addWidget(gui.TextView('UK: ')) ''' self.groupBox.showWidget(self.groupBoxes['neck'])
def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Background') self.backgroundsFolder = os.path.join(mh.getPath(''), 'backgrounds') if not os.path.exists(self.backgroundsFolder): os.makedirs(self.backgroundsFolder) self.backgroundsFolders = [ os.path.join('data', 'backgrounds'), self.backgroundsFolder ] self.extensions = ['bmp', 'png', 'tif', 'tiff', 'jpg', 'jpeg', 'clear'] self.texture = mh.Texture() self.sides = { 'front': [0, 0, 0], 'back': [0, 180, 0], 'left': [0, 90, 0], 'right': [0, -90, 0], 'top': [90, 0, 0], 'bottom': [-90, 0, 0], 'other': None } self.filenames = {} # Stores (filename, aspect) self.transformations = {} # Stores ((posX,posY), scaleY) for side in self.sides.keys(): self.filenames[side] = None self.transformations[side] = [(0.0, 0.0), 1.0] mesh = geometry3d.RectangleMesh(20, 20, centered=True) self.backgroundImage = gui3d.app.addObject( gui3d.Object([0, 0, 1], mesh, visible=False)) self.backgroundImage.mesh.setCameraProjection(0) # Set to model camera self.opacity = 100 mesh.setColor([255, 255, 255, self.opacity]) mesh.setPickable(False) mesh.setShadeless(True) mesh.setDepthless(True) mesh.priority = -90 self.backgroundImageToggle = gui.Action('background', 'Background', self.toggleBackground, toggle=True) gui3d.app.main_toolbar.addAction(self.backgroundImageToggle) gui3d.app.actions.background = self.backgroundImageToggle #self.filechooser = self.addTopWidget(fc.FileChooser(self.backgroundsFolders, self.extensions, None)) #self.addLeftWidget(self.filechooser.sortBox) self.filechooser = self.addRightWidget( fc.IconListFileChooser(self.backgroundsFolders, self.extensions, None, None, 'Background')) self.filechooser.setIconSize(50, 50) self.addLeftWidget(self.filechooser.createSortBox()) self.backgroundBox = self.addLeftWidget(gui.GroupBox('Side')) self.bgSettingsBox = self.addLeftWidget( gui.GroupBox('Background settings')) self.radioButtonGroup = [] for side in [ 'front', 'back', 'left', 'right', 'top', 'bottom', 'other' ]: radioBtn = self.backgroundBox.addWidget( gui.RadioButton(self.radioButtonGroup, label=side.capitalize(), selected=len(self.radioButtonGroup) == 0)) radioBtn.side = side self.opacitySlider = self.bgSettingsBox.addWidget( gui.Slider(value=self.opacity, min=0, max=255, label="Opacity: %d")) self.foregroundTggl = self.bgSettingsBox.addWidget( gui.ToggleButton("Show in foreground")) @self.opacitySlider.mhEvent def onChanging(value): self.backgroundImage.mesh.setColor([255, 255, 255, value]) @self.opacitySlider.mhEvent def onChange(value): self.opacity = value self.backgroundImage.mesh.setColor([255, 255, 255, value]) @self.foregroundTggl.mhEvent def onClicked(value): self.setShowBgInFront(self.foregroundTggl.selected) @self.filechooser.mhEvent def onFileSelected(filename): side = self.getSelectedSideCheckbox() if os.path.splitext(filename)[1] == ".clear": filename = None if self.filenames[side]: oldBg = self.filenames[side][0] else: oldBg = None gui3d.app.do( BackgroundAction("Change background", self, side, oldBg, filename)) if self.sides[side]: gui3d.app.selectedHuman.setRotation(self.sides[side]) mh.redraw()
def drawPlanes(self, skel): def _get_face_count(skel): result = 0 for bone in skel.getBones(): if isinstance(bone.roll, list): result += len(bone.roll) else: result += 1 return result import module3d self.planesMesh = module3d.Object3D("SkeletonPlanesMesh", 3) facecount = _get_face_count(skel) vertcount = 3 * facecount faces = np.arange(vertcount, dtype=np.uint16).reshape((facecount, 3)) verts = np.zeros((vertcount, 3), dtype=np.float32) vcolors = 255 * np.ones((vertcount, 4), dtype=np.uint8) PLANE_COLORS = [[60, 230, 200], [220, 60, 230], [230, 180, 60], [230, 90, 60], [60, 230, 60], [60, 120, 230]] fgroups = np.zeros(len(faces), dtype=np.uint16) v_offset = 0 for bIdx, bone in enumerate(skel.getBones()): fg = self.planesMesh.createFaceGroup(bone.name) fgroups[bIdx:bIdx + 1] = np.repeat( np.array(fg.idx, dtype=np.uint16), 1) if isinstance(bone.roll, list): for p_idx, plane_name in enumerate(bone.roll): plane_name = bone.roll[0] plane_joints = bone.planes[plane_name] j1, j2, j3 = plane_joints in_rest = False p1 = skel.getJointPosition(j1, self.human, in_rest)[:3] * skel.scale p2 = skel.getJointPosition(j2, self.human, in_rest)[:3] * skel.scale p3 = skel.getJointPosition(j3, self.human, in_rest)[:3] * skel.scale verts[v_offset:v_offset + 3] = [p1, p2, p3] vcolors[v_offset:v_offset + 3, :3] = PLANE_COLORS[p_idx] fgroups[v_offset // 3] = fg.idx v_offset += 3 elif isinstance(bone.roll, str): plane_name = bone.roll plane_joints = bone.planes[plane_name] j1, j2, j3 = plane_joints in_rest = False p1 = skel.getJointPosition(j1, self.human, in_rest)[:3] * skel.scale p2 = skel.getJointPosition(j2, self.human, in_rest)[:3] * skel.scale p3 = skel.getJointPosition(j3, self.human, in_rest)[:3] * skel.scale verts[v_offset:v_offset + 3] = [p1, p2, p3] vcolors[v_offset:v_offset + 3, :3] = PLANE_COLORS[0] fgroups[v_offset // 3] = fg.idx v_offset += 3 else: p1 = p2 = p3 = [0.0, 0.0, 0.0] verts[v_offset:v_offset + 3] = [p1, p2, p3] vcolors[v_offset:v_offset + 3, :3] = [255, 0, 0] fgroups[v_offset // 3] = fg.idx v_offset += 3 self.planesMesh.setCoords(verts) self.planesMesh.setColor(vcolors) self.planesMesh.setUVs(np.zeros( (1, 2), dtype=np.float32)) # Set trivial UV coordinates self.planesMesh.setFaces(faces, None, fgroups) self.planesMesh.updateIndexBuffer() self.planesMesh.calcNormals() self.planesMesh.update() self.planesMesh.setCameraProjection(0) self.planesMesh.priority = 100 self.planesMesh.setPickable(False) self.planesObj = self.addObject( gui3d.Object(self.planesMesh, self.human.getPosition())) self.planesObj.setShadeless(0) self.planesObj.setSolid(0) self.planesObj.setRotation(self.human.getRotation()) self.planesObj.material.backfaceCull = False self.planesObj.setVisibility(self.showPlanesTggl.selected)
def selectProxy(self, mhclofile): """ Called when a new proxy has been selected. If this library selects only a single proxy, specifying None as mhclofile parameter will deselect the current proxy and set the selection to "none". If this library allows selecting multiple proxies, specifying None as mhclofile will have no effect. """ if not mhclofile: if self.multiProxy: return else: self.deselectProxy(None) return log.message('Selecting proxy file "%s" from %s library.', mhclofile, self.proxyName) human = self.human proxy = None mhcloId = getpath.canonicalPath(mhclofile) if mhcloId in self._proxyCache: proxy = self._proxyCache[mhcloId] if proxy.mtime < os.path.getmtime(mhclofile): proxy = None if not proxy: proxy = mh2proxy.readProxyFile(human.meshData, mhclofile, type=self.proxyName.capitalize()) self._proxyCache[mhcloId] = proxy if proxy.uuid in [p.uuid for p in self.getSelection()]: log.debug( "Proxy with UUID %s (%s) already loaded in %s library. Skipping.", proxy.uuid, proxy.file, self.proxyName) return if not self.multiProxy and self.isProxySelected(): # Deselect previously selected proxy self.deselectProxy(None, suppressSignal=True) mesh = files3d.loadMesh(proxy.obj_file, maxFaces=proxy.max_pole) if not mesh: log.error("Failed to load %s", proxy.obj_file) return self.filechooser.selectItem(mhclofile) mesh.material = proxy.material mesh.priority = proxy.z_depth # Set render order mesh.setCameraProjection(0) # Set to model camera mesh.setSolid( human.mesh.solid) # Set to wireframe if human is in wireframe obj = gui3d.Object(mesh, self.human.getPosition()) obj.setRotation(human.getRotation()) gui3d.app.addObject(obj) self.adaptProxyToHuman(proxy, obj) obj.setSubdivided( human.isSubdivided()) # Copy subdivided state of human # Add to selection self.selectedProxies.append(proxy) self.proxyObjects.append(obj) self.filechooser.selectItem(mhclofile) self.proxySelected(proxy, obj) self.signalChange()