Esempio n. 1
0
    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)
Esempio n. 2
0
def loadObjFile(path, obj=None):
    """
    Parse and load a Wavefront OBJ file as mesh.
    Parser does not support normals, and assumes all objects should be smooth
    shaded. Use duplicate vertices for achieving hard edges.
    """
    if obj == None:
        name = os.path.splitext(os.path.basename(path))[0]
        obj = module3d.Object3D(name)

    objFile = open(path, 'rU', encoding="utf-8")

    fg = None
    mtl = None

    verts = []
    uvs = []
    fverts = []
    fuvs = []
    groups = []
    has_uv = False
    materials = {}
    faceGroups = {}

    for objData in objFile:

        lineData = objData.split()
        if len(lineData) > 0:

            command = lineData[0]

            # Vertex coordinate
            if command == 'v':
                verts.append((float(lineData[1]), float(lineData[2]),
                              float(lineData[3])))

            # Vertex texture (UV) coordinate
            elif command == 'vt':
                uvs.append((float(lineData[1]), float(lineData[2])))

            # Face definition (reference to vertex attributes)
            elif command == 'f':
                if not fg:
                    if 0 not in faceGroups:
                        faceGroups[0] = obj.createFaceGroup(
                            'default-dummy-group')
                    fg = faceGroups[0]

                uvIndices = []
                vIndices = []
                for faceData in lineData[1:]:
                    vInfo = faceData.split('/')
                    vIdx = int(vInfo[0]) - 1  # -1 because obj is 1 based list
                    vIndices.append(vIdx)

                    # If there are other data (uv, normals, etc)
                    if len(vInfo) > 1 and vInfo[1] != '':
                        uvIndex = int(
                            vInfo[1]) - 1  # -1 because obj is 1 based list
                        uvIndices.append(uvIndex)

                if len(vIndices) == 3:
                    vIndices.append(vIndices[0])
                fverts.append(tuple(vIndices))

                if len(uvIndices) > 0:
                    if len(uvIndices) == 3:
                        uvIndices.append(uvIndices[0])
                    has_uv = True
                if len(uvIndices) < 4:
                    uvIndices = [0, 0, 0, 0]
                fuvs.append(tuple(uvIndices))

                groups.append(fg.idx)

            elif command == 'g':
                fgName = lineData[1]
                if fgName not in faceGroups:
                    faceGroups[fgName] = obj.createFaceGroup(fgName)
                fg = faceGroups[fgName]

            elif command == 'usemtl':
                pass  # ignore materials

            elif command == 'o':

                obj.name = lineData[1]

    objFile.close()

    # Sanity check for loose vertices
    strayVerts = []
    referencedVerts = set([v for fvert in fverts for v in fvert])
    for vIdx in range(len(verts)):
        if vIdx not in referencedVerts:
            strayVerts.append(vIdx)
    if len(strayVerts) > 0:
        import log
        msg = "Error loading OBJ file %s: Contains loose vertices, not connected to a face (%s)"
        log.error(msg, path, strayVerts)
        raise RuntimeError(msg % (path, strayVerts))

    obj.setCoords(verts)
    obj.setUVs(uvs)
    obj.setFaces(fverts, fuvs if has_uv else None, groups)

    obj.calcNormals()
    obj.updateIndexBuffer()

    return obj
Esempio n. 3
0
    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'])
Esempio n. 4
0
def loadMesh(path, locX=0, locY=0, locZ=0, loadColors=1, maxFaces=None):
    """
    This function loads the specified mesh object into internal MakeHuman data 
    structures, and returns it. The loaded file should be in Wavefront OBJ 
    format.
    
    Parameters:
    -----------
   
    path:     
      *String*.  The file system path to the file containing the object to load.

    locX:
      *float* X location of loaded obj, default = 0

    locY:
      *float* Y location of loaded obj, default = 0

    locZ:
      *float* Z location of loaded obj, default = 0

    Note: loadColors is currently unused

    maxFaces:
      *uint* Number of faces per vertex (pole), None for default (min 4)
    """
    name = os.path.basename(path)
    obj = module3d.Object3D(name)
    if maxFaces:
        obj.MAX_FACES = maxFaces

    obj.path = path
    obj.x = locX
    obj.y = locY
    obj.z = locZ

    try:
        npzpath = os.path.splitext(path)[0] + '.npz'
        try:
            if not os.path.isfile(npzpath):
                log.message('compiled file missing: %s', npzpath)
                raise RuntimeError('compiled file missing: %s', npzpath)
            if os.path.isfile(path) and os.path.getmtime(
                    path) > os.path.getmtime(npzpath):
                log.message('compiled file out of date: %s', npzpath)
                raise RuntimeError('compiled file out of date: %s', npzpath)
            loadBinaryMesh(obj, npzpath)
        except Exception as e:
            showTrace = not isinstance(e, RuntimeError)
            log.warning("Problem loading binary mesh: %s",
                        e,
                        exc_info=showTrace)
            loadTextMesh(obj, path)
            if isSubPath(npzpath, getPath('')):
                # Only write compiled binary meshes to user data path
                try:
                    saveBinaryMesh(obj, npzpath)
                except StandardError:
                    log.notice('unable to save compiled mesh: %s', npzpath)
            else:
                log.debug('Not writing compiled meshes to system paths (%s).',
                          npzpath)
    except:
        log.error('Unable to load obj file: %s', path, exc_info=True)
        return False

    return obj
Esempio n. 5
0
def loadMesh(path, loadColors=1, maxFaces=None, obj=None):
    """
    This function loads the specified mesh object into internal MakeHuman data 
    structures, and returns it. The loaded file should be in Wavefront OBJ 
    format.
    
    Parameters:
    -----------
   
    path:     
      *String*.  The file system path to the file containing the object to load.

    Note: loadColors is currently unused

    maxFaces:
      *uint* Number of faces per vertex (pole), None for default (min 4)
    """
    if type(path) is bytes:
        path = path.decode('utf-8')
    log.debug("loadMesh in files3d received a raw path of %s", path)
    name = os.path.basename(path)
    if isinstance(name, bytes):
        name.decode('utf-8')
    log.debug("os.path.basename produce a name of: %s", name)
    log.debug("files3d loadMesh basename is %s", name)
    if obj is None:
        obj = module3d.Object3D(os.path.splitext(path)[0])
        log.message("obj name changed from None to %s",
                    module3d.Object3D(name))
    if maxFaces:
        obj.MAX_FACES = maxFaces

    obj.path = path

    try:
        import getpath
        path = getpath.getSysPath(path)
        log.message("Expanded path is found to be %s", path)
        npzpath = os.path.splitext(path)[0] + '.npz'

        log.debug("files3d loadMesh will attempt to load %s", npzpath)

        if not os.path.isfile(npzpath):
            log.message('compiled file missing: %s', npzpath)
            raise RuntimeError('compiled file missing: %s', npzpath)
        if os.path.isfile(
                path) and os.path.getmtime(path) > os.path.getmtime(npzpath):
            log.message('compiled file out of date: %s', npzpath)
            raise RuntimeError('compiled file out of date: %s', npzpath)
        loadBinaryMesh(obj, npzpath)

        log.message("files3d loadMesh attempting to load %s", npzpath)
        loadTextMesh(obj, path)
        if isSubPath(npzpath, getPath('')):
            # Only write compiled binary meshes to user data path
            saveBinaryMesh(obj, npzpath)
            log.debug('files3d just saved compiled mesh: %s', npzpath)
        else:
            log.debug("files3d using getpath('') could not find (%s).",
                      npzpath)
    except:
        log.error('Unable to load obj file: %s', path, exc_info=True)
        return False

    return obj