Exemple #1
0
def createInertialFromDictionary(name, inertial):
    """Creates the Blender representation of a given intertial provided a dictionary.

    :param name: The intertials name.
    :param type: str
    :param inertial: The intertial you want to create in blender form.
    :type intertial: dict
    :return: bpy_types.Object -- the newly created blender inertial object.

    """
    # FIXME: this needs work to get rid of duplicate code
    bpy.ops.object.select_all(action='DESELECT')
    inert = bUtils.createPrimitive('inertial_' + name,
                                   'box', [0.06, 0.06, 0.06],
                                   player='inertial')
    inert.select = True
    bpy.ops.object.transform_apply(scale=True)
    for prop in inertial:
        if prop not in ['pose'] and inertial[prop] is not None:
            if not prop.startswith('$'):
                inert[prop] = inertial[prop]
            else:
                for tag in inertial[prop]:
                    inert[prop[1:] + '/' + tag] = inertial[prop][tag]
    inert.phobostype = 'inertial'
    assignMaterial(inert, 'phobos_inertial')
    return inert
Exemple #2
0
def createPrimitive(pname, ptype, psize, player=0, pmaterial=None, plocation=(0, 0, 0),
                    protation=(0, 0, 0), phobostype=None):
    """Generates the primitive specified by the input parameters

    Args:
      pname(str): The primitives new name.
      ptype(str): The new primitives type. Can be one of *box, sphere, cylinder, cone, disc*
      psize(float or list): The new primitives size. Depending on the ptype it can be either a single float or a tuple.
      player: The layer bitmask for the new blender object. (Default value = 0)
      pmaterial: The new primitives material. (Default value = None)
      plocation(tuple, optional): The new primitives location. (Default value = (0)
      protation(tuple): The new primitives rotation.
      phobostype(str): phobostype of object to be created
      0:

    Returns:
      bpy.types.Object - the new blender object.

    """
    # TODO: allow placing on currently active layer?
    try:
        n_layer = int(player)
    except ValueError:
        n_layer = defs.layerTypes[player]
    players = defLayers([n_layer])
    # the layer has to be active to prevent problems with object placement
    bpy.context.scene.layers[n_layer] = True
    if ptype == "box":
        bpy.ops.mesh.primitive_cube_add(layers=players, location=plocation, rotation=protation)
        obj = bpy.context.object
        obj.dimensions = psize
    if ptype == "sphere":
        bpy.ops.mesh.primitive_uv_sphere_add(size=psize, layers=players, location=plocation,
                                             rotation=protation)
    elif ptype == "cylinder":
        bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=psize[0], depth=psize[1],
                                            layers=players, location=plocation, rotation=protation)
    elif ptype == "cone":
        bpy.ops.mesh.primitive_cone_add(vertices=32, radius=psize[0], depth=psize[1], cap_end=True,
                                        layers=players, location=plocation, rotation=protation)
    elif ptype == 'disc':
        bpy.ops.mesh.primitive_circle_add(vertices=psize[1], radius=psize[0], fill_type='TRIFAN',
                                          location=plocation, rotation=protation, layers=players)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    obj = bpy.context.object
    if phobostype:
        obj.phobostype = phobostype
    nUtils.safelyName(obj, pname, phobostype)
    if pmaterial:
        materials.assignMaterial(obj, pmaterial)
    return obj
Exemple #3
0
def createPrimitive(pname, ptype, psize, player=0, pmaterial="None", plocation=(0, 0, 0), protation=(0, 0, 0),
                    verbose=False):
    """Generates the primitive specified by the input parameters

    :param pname: The primitives new name.
    :type pname: str
    :param ptype: The new primitives type. Can be one of *box, sphere, cylinder, cone, disc*
    :type ptype: str
    :param psize: The new primitives size. Depending on the ptype it can be either a single float or a tuple.
    :type psize: float or list
    :param player: The layer bitmask for the new blender object.
    :param pmaterial: The new primitives material.
    :param plocation: The new primitives location.
    :type plocation: tuple
    :param protation: The new primitives rotation.
    :type protation: tuple
    :return: bpy.types.Object - the new blender object.

    """
    if verbose:
        log(ptype + psize, "INFO", "createPrimitive")
    try:
        # n_layer = bpy.context.scene.active_layer
        n_layer = int(player)
    except ValueError:
        n_layer = defs.layerTypes[player]
    players = defLayers([n_layer])
    bpy.context.scene.layers[n_layer] = True  # the layer has to be active to prevent problems with object placement
    if ptype == "box":
        bpy.ops.mesh.primitive_cube_add(layers=players, location=plocation, rotation=protation)
        obj = bpy.context.object
        obj.dimensions = psize
    if ptype == "sphere":
        bpy.ops.mesh.primitive_uv_sphere_add(size=psize, layers=players, location=plocation, rotation=protation)
    elif ptype == "cylinder":
        bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=psize[0], depth=psize[1], layers=players,
                                            location=plocation, rotation=protation)
    elif ptype == "cone":
        bpy.ops.mesh.primitive_cone_add(vertices=32, radius=psize[0], depth=psize[1], cap_end=True, layers=players,
                                        location=plocation, rotation=protation)
    elif ptype == 'disc':
        bpy.ops.mesh.primitive_circle_add(vertices=psize[1], radius=psize[0], fill_type='TRIFAN', location=plocation,
                                          rotation=protation, layers=players)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    obj = bpy.context.object
    obj.name = pname
    if pmaterial != 'None':
        materials.assignMaterial(obj, pmaterial)
    return obj
Exemple #4
0
def createGeometry(viscol, geomsrc):
    """Creates geometrical Blender object for visual or collision objects.

    :param viscol: The visual/collision dictionary element you want to create the geometry for.
    :type viscol: dict
    :param geomsrc: The new viscols phobostype.
    :type geomsrc: str

    """
    if 'geometry' not in viscol or viscol['geometry'] is {}:
        return None
    bpy.ops.object.select_all(action='DESELECT')
    geom = viscol['geometry']
    geomtype = geom['type']
    # create the Blender object
    if geomtype == 'mesh':
        bpy.context.scene.layers = bUtils.defLayers(defs.layerTypes[geomsrc])
        meshname = "".join(os.path.basename(geom["filename"]).split(".")[:-1])
        if not os.path.isfile(geom['filename']):
            log(geom['filename'] + " is no file. Object " + viscol['name'] +
                " will have empty mesh!", "ERROR")
            bpy.data.meshes.new(meshname)
        if meshname in bpy.data.meshes:
            log('Assigning copy of existing mesh ' + meshname + ' to ' + viscol['name'], 'INFO')
            bpy.ops.object.add(type='MESH')
            newgeom = bpy.context.object
            newgeom.data = bpy.data.meshes[meshname]
        else:
            log('Importing mesh for link element ' + viscol['name'], 'INFO')
            filetype = geom['filename'].split('.')[-1].lower()
            newgeom = meshes.importMesh(geom['filename'], filetype)
            newgeom.data.name = meshname
            if not newgeom:
                log('Failed to import mesh file ' + geom['filename'], 'ERROR')
                return
            # scale imported object
            if 'scale' in geom:
                sUtils.selectObjects((newgeom,), clear=True)
                newgeom.scale = geom['scale']
    else:
        if geomtype == 'box':
            dimensions = geom['size']
        elif geomtype == 'cylinder':
            dimensions = (geom['radius'], geom['length'])
        elif geomtype == 'sphere':
            dimensions = geom['radius']
        else:
            log("Could not determine geometry type of " + geomsrc + viscol['name']
                + '. Placing empty coordinate system.', "ERROR")
            bpy.ops.object.empty_add(type='PLAIN_AXES', radius=0.2)
            bpy.context.active_object.name = viscol['name']
            return None
        log('Creating primtive for obj ' + viscol['name'], 'INFO')
        newgeom = bUtils.createPrimitive(viscol['name'], geomtype, dimensions, player=geomsrc)
        newgeom.select = True
        bpy.ops.object.transform_apply(scale=True)

    # from here it's the same for both meshes and primitives
    newgeom.phobostype = geomsrc
    newgeom['geometry/type'] = geomtype
    if geomsrc == 'visual':
        try:
            if 'name' in viscol['material']:
                assignMaterial(newgeom, viscol['material']['name'])
            else:
                assignMaterial(newgeom, viscol['material'])
        except KeyError:
            log('No material for obj ' + viscol['name'], 'DEBUG')
    # FIXME: place empty coordinate system and return...what? Error handling of file import!
    for prop in viscol:
        if prop.startswith('$'):
            for tag in viscol[prop]:
                newgeom[prop[1:]+'/'+tag] = viscol[prop][tag]
    newgeom.name = viscol['name']
    newgeom[geomsrc+"/name"] = viscol['name']
    return newgeom
Exemple #5
0
def createGeometry(viscol, geomsrc, linkobj=None):
    """Creates Blender object for visual or collision objects.
    Returns reference to new object or None if creation failed.

    Args:
      viscol(dict): visual/collision dictionary element
      geomsrc(str): new object's phobostype
      linkobj(bpy.types.Object): link object

    Returns:
      bpy.types.Object or None

    """
    if 'geometry' not in viscol or viscol['geometry'] is {}:
        return None
    bpy.ops.object.select_all(action='DESELECT')
    geom = viscol['geometry']
    # create the Blender object
    if geom['type'] == 'mesh':
        bpy.context.scene.layers = bUtils.defLayers(defs.layerTypes[geomsrc])
        meshname = "".join(os.path.basename(geom["filename"]).split(".")[:-1])
        if not os.path.isfile(geom['filename']):
            log(geom['filename'] + " is no file. Object " + viscol['name'] + " will have empty mesh!", "ERROR")
            #bpy.data.meshes.new(meshname)
            bpy.ops.object.add(type='MESH')
            newgeom = bpy.context.active_object
            nUtils.safelyName(newgeom, viscol['name'], phobostype=geomsrc)
        else:
            if meshname in bpy.data.meshes:
                log('Assigning copy of existing mesh ' + meshname + ' to ' + viscol['name'], 'INFO')
                bpy.ops.object.add(type='MESH')
                newgeom = bpy.context.object
                newgeom.data = bpy.data.meshes[meshname]
            else:
                log("Importing mesh for {0} element: '{1}".format(geomsrc, viscol['name']), 'INFO')
                filetype = geom['filename'].split('.')[-1].lower()
                newgeom = meshes.importMesh(geom['filename'], filetype)
                newgeom.data.name = meshname
                if not newgeom:
                    log('Failed to import mesh file ' + geom['filename'], 'ERROR')
                    return
            # scale imported object
            if 'scale' in geom:
                newgeom.scale = geom['scale']
    else:
        if geom['type'] == 'box':
            dimensions = geom['size']
        elif geom['type'] == 'cylinder':
            dimensions = (geom['radius'], geom['length'])
        elif geom['type'] == 'sphere':
            dimensions = geom['radius']
        else:
            log("Unknown geometry type of " + geomsrc + viscol['name']
                + '. Placing empty coordinate system.', "ERROR")
            bpy.ops.object.empty_add(type='PLAIN_AXES', radius=0.2)
            obj = bpy.context.object
            obj.phobostype = geomsrc
            nUtils.safelyName(bpy.context.active_object, viscol['name'], phobostype=geomsrc)
            return None
        log('Creating primtive for {0}: {1}'.format(geomsrc, viscol['name']), 'INFO')
        newgeom = bUtils.createPrimitive(viscol['name'], geom['type'], dimensions, phobostype=geomsrc)
        newgeom.select = True
        bpy.ops.object.transform_apply(scale=True)

    # from here it's the same for both meshes and primitives
    newgeom['geometry/type'] = geom['type']
    if geomsrc == 'visual':
        try:
            assignMaterial(newgeom, viscol['material'])
        except KeyError:
            log('No material for visual ' + viscol['name'], 'DEBUG')
    for prop in viscol:
        if prop.startswith('$'):
            for tag in viscol[prop]:
                newgeom[prop[1:]+'/'+tag] = viscol[prop][tag]
    nUtils.safelyName(newgeom, viscol['name'])
    newgeom[geomsrc+"/name"] = viscol['name']
    newgeom.phobostype = geomsrc

    # place geometric object relative to its parent link
    if linkobj:
        if 'pose' in viscol:
            log('Setting transformation of element: ' + viscol['name'], 'DEBUG')
            location = mathutils.Matrix.Translation(viscol['pose']['translation'])
            rotation = mathutils.Euler(tuple(viscol['pose']['rotation_euler']), 'XYZ').to_matrix().to_4x4()
        else:
            log('No pose in element: ' + viscol['name'], 'DEBUG')
            location = mathutils.Matrix.Identity(4)
            rotation = mathutils.Matrix.Identity(4)
        sUtils.selectObjects([newgeom, linkobj], True, 1)
        bpy.ops.object.parent_set(type='BONE_RELATIVE')
        newgeom.matrix_local = location * rotation
        if 'scale' in viscol['geometry']:
            newgeom.scale = mathutils.Vector(viscol['geometry']['scale'])
    return newgeom
Exemple #6
0
def createGeometry(viscol, geomsrc, linkobj=None):
    """Creates Blender object for visual or collision objects.
    
    If the creation fails, nothing is returned.
    
    These entries in the dictionary are mandatory:
    
    |   **geometry**:
    |       **type**: type of geometry (mesh, box, cylinder, sphere)
    
    Depending on the geometry type other values are required: `size`, `radius`, `length`
    
    These entries are optional:
    
    |   **geometry**:
    |       **scale**: scale for the new geometry
    |   **material**: material name to assign to the visual
    |   **pose**: specifies the placement of the new object relative to the optional linkobj
    |       **translation**: position vector for the new object
    |       **rotation_euler**: rotation for the new object
    
    Furthermore any generic properties, prepended by a ``$`` will be added as custom properties to
    the visual/collision object. E.g. ``$test/etc`` would be put to visual/test/etc for a visual
    object. However, these properties are extracted only in the first layer of hierarchy.

    Args:
      viscol(dict): visual/collision model dictionary representation
      geomsrc(str): phobostype of the new object
      linkobj(bpy.types.Object, optional): link object to attach the visual/collision object to
    (Default value = None)

    Returns:
      bpy.types.Object or None: the new geometry object or nothing

    """
    if 'geometry' not in viscol or viscol['geometry'] is {}:
        log("Could not create {}. Geometry information not defined!".format(geomsrc), 'ERROR')
        return None

    bpy.ops.object.select_all(action='DESELECT')
    geom = viscol['geometry']

    # create the Blender object
    if geom['type'] == 'mesh':
        bpy.context.scene.layers = bUtils.defLayers(defs.layerTypes[geomsrc])
        meshname = "".join(os.path.basename(geom["filename"]).split(".")[:-1])
        if not os.path.isfile(geom['filename']):
            log(
                "This path "
                + geom['filename']
                + " is no file. Object "
                + viscol['name']
                + " will have empty mesh!",
                'ERROR',
            )
            bpy.ops.object.add(type='MESH')
            newgeom = bpy.context.active_object
            nUtils.safelyName(newgeom, viscol['name'], phobostype=geomsrc)
        else:
            if meshname in bpy.data.meshes:
                log('Assigning copy of existing mesh ' + meshname + ' to ' + viscol['name'], 'INFO')
                bpy.ops.object.add(type='MESH')
                newgeom = bpy.context.object
                newgeom.data = bpy.data.meshes[meshname]
            else:
                log("Importing mesh for {0} element: '{1}".format(geomsrc, viscol['name']), 'INFO')
                filetype = geom['filename'].split('.')[-1].lower()
                newgeom = meshes.importMesh(geom['filename'], filetype)
                # bpy.data.meshes[newgeom].name = meshname
                if not newgeom:
                    log('Failed to import mesh file ' + geom['filename'], 'ERROR')
                    return
    else:
        if geom['type'] == 'box':
            dimensions = geom['size']
        elif geom['type'] == 'cylinder':
            dimensions = (geom['radius'], geom['length'])
        elif geom['type'] == 'sphere':
            dimensions = geom['radius']
        # TODO add support for heightmap, image, plane and polyline geometries (see sdf!)
        else:
            log(
                "Unknown geometry type of "
                + geomsrc
                + viscol['name']
                + '. Placing empty coordinate system.',
                "ERROR",
            )
            bpy.ops.object.empty_add(type='PLAIN_AXES', radius=0.2)
            obj = bpy.context.object
            obj.phobostype = geomsrc
            nUtils.safelyName(bpy.context.active_object, viscol['name'], phobostype=geomsrc)
            return None
        log("Creating primtive for {0}: {1}".format(geomsrc, viscol['name']), 'INFO')
        newgeom = bUtils.createPrimitive(
            viscol['name'], geom['type'], dimensions, phobostype=geomsrc
        )
        newgeom.select = True
        bpy.ops.object.transform_apply(scale=True)

    # from here it's the same for both meshes and primitives
    newgeom['geometry/type'] = geom['type']
    if geomsrc == 'visual':
        if 'material' in viscol:
            assignMaterial(newgeom, viscol['material'])
        else:
            log('No material for visual {}.'.format(viscol['name']), 'WARNING')

    # write generic custom properties
    for prop in viscol:
        if prop.startswith('$'):
            for tag in viscol[prop]:
                newgeom[prop[1:] + '/' + tag] = viscol[prop][tag]

    nUtils.safelyName(newgeom, viscol['name'])
    newgeom[geomsrc + '/name'] = viscol['name']
    newgeom.phobostype = geomsrc

    # place geometric object relative to its parent link
    if linkobj:
        if 'pose' in viscol:
            log("Setting transformation of element: " + viscol['name'], 'DEBUG')
            location = mathutils.Matrix.Translation(viscol['pose']['translation'])
            rotation = (
                mathutils.Euler(tuple(viscol['pose']['rotation_euler']), 'XYZ').to_matrix().to_4x4()
            )
        else:
            log("No pose in element: " + viscol['name'], 'DEBUG')
            location = mathutils.Matrix.Identity(4)
            rotation = mathutils.Matrix.Identity(4)
        eUtils.parentObjectsTo(newgeom, linkobj)
        newgeom.matrix_local = location * rotation

    # scale imported object
    if 'scale' in geom:
        newgeom.scale = geom['scale']

    # make object smooth
    eUtils.smoothen_surface(newgeom)

    return newgeom
Exemple #7
0
def createGeometry(viscol, geomsrc, linkobj=None):
    """Creates Blender object for visual or collision objects.
    
    If the creation fails, nothing is returned.
    
    These entries in the dictionary are mandatory:
    
    |   **geometry**:
    |       **type**: type of geometry (mesh, box, cylinder, sphere)
    
    Depending on the geometry type other values are required: `size`, `radius`, `length`
    
    These entries are optional:
    
    |   **geometry**:
    |       **scale**: scale for the new geometry
    |   **material**: material name to assign to the visual
    |   **pose**: specifies the placement of the new object relative to the optional linkobj
    |       **translation**: position vector for the new object
    |       **rotation_euler**: rotation for the new object
    
    Furthermore any generic properties, prepended by a ``$`` will be added as custom properties to
    the visual/collision object. E.g. ``$test/etc`` would be put to visual/test/etc for a visual
    object. However, these properties are extracted only in the first layer of hierarchy.

    Args:
      viscol(dict): visual/collision model dictionary representation
      geomsrc(str): phobostype of the new object
      linkobj(bpy.types.Object, optional): link object to attach the visual/collision object to
    (Default value = None)

    Returns:
      bpy.types.Object or None: the new geometry object or nothing

    """
    if 'geometry' not in viscol or viscol['geometry'] is {}:
        log("Could not create {}. Geometry information not defined!".format(geomsrc), 'ERROR')
        return None

    bpy.ops.object.select_all(action='DESELECT')
    geom = viscol['geometry']

    # create the Blender object
    if geom['type'] == 'mesh':
        bpy.context.scene.layers = bUtils.defLayers(defs.layerTypes[geomsrc])
        meshname = "".join(os.path.basename(geom["filename"]).split(".")[:-1])
        if not os.path.isfile(geom['filename']):
            log(
                "This path "
                + geom['filename']
                + " is no file. Object "
                + viscol['name']
                + " will have empty mesh!",
                'ERROR',
            )
            bpy.ops.object.add(type='MESH')
            newgeom = bpy.context.active_object
            nUtils.safelyName(newgeom, viscol['name'], phobostype=geomsrc)
        else:
            if meshname in bpy.data.meshes:
                log('Assigning copy of existing mesh ' + meshname + ' to ' + viscol['name'], 'INFO')
                bpy.ops.object.add(type='MESH')
                newgeom = bpy.context.object
                newgeom.data = bpy.data.meshes[meshname]
            else:
                log("Importing mesh for {0} element: '{1}".format(geomsrc, viscol['name']), 'INFO')
                filetype = geom['filename'].split('.')[-1].lower()
                newgeom = meshes.importMesh(geom['filename'], filetype)
                # bpy.data.meshes[newgeom].name = meshname
                if not newgeom:
                    log('Failed to import mesh file ' + geom['filename'], 'ERROR')
                    return
    else:
        if geom['type'] == 'box':
            dimensions = geom['size']
        elif geom['type'] == 'cylinder':
            dimensions = (geom['radius'], geom['length'])
        elif geom['type'] == 'sphere':
            dimensions = geom['radius']
        # TODO add support for heightmap, image, plane and polyline geometries (see sdf!)
        else:
            log(
                "Unknown geometry type of "
                + geomsrc
                + viscol['name']
                + '. Placing empty coordinate system.',
                "ERROR",
            )
            bpy.ops.object.empty_add(type='PLAIN_AXES', radius=0.2)
            obj = bpy.context.object
            obj.phobostype = geomsrc
            nUtils.safelyName(bpy.context.active_object, viscol['name'], phobostype=geomsrc)
            return None
        log("Creating primtive for {0}: {1}".format(geomsrc, viscol['name']), 'INFO')
        newgeom = bUtils.createPrimitive(
            viscol['name'], geom['type'], dimensions, phobostype=geomsrc
        )
        newgeom.select = True
        bpy.ops.object.transform_apply(scale=True)

    # from here it's the same for both meshes and primitives
    newgeom['geometry/type'] = geom['type']
    if geomsrc == 'visual':
        if 'material' in viscol:
            assignMaterial(newgeom, viscol['material'])
        else:
            log('No material for visual {}.'.format(viscol['name']), 'WARNING')

    # write generic custom properties
    for prop in viscol:
        if prop.startswith('$'):
            for tag in viscol[prop]:
                newgeom[prop[1:] + '/' + tag] = viscol[prop][tag]

    nUtils.safelyName(newgeom, viscol['name'])
    newgeom[geomsrc + '/name'] = viscol['name']
    newgeom.phobostype = geomsrc

    # place geometric object relative to its parent link
    if linkobj:
        if 'pose' in viscol:
            log("Setting transformation of element: " + viscol['name'], 'DEBUG')
            location = mathutils.Matrix.Translation(viscol['pose']['translation'])
            rotation = (
                mathutils.Euler(tuple(viscol['pose']['rotation_euler']), 'XYZ').to_matrix().to_4x4()
            )
        else:
            log("No pose in element: " + viscol['name'], 'DEBUG')
            location = mathutils.Matrix.Identity(4)
            rotation = mathutils.Matrix.Identity(4)
        eUtils.parentObjectsTo(newgeom, linkobj)
        newgeom.matrix_local = location * rotation

    # scale imported object
    if 'scale' in geom:
        newgeom.scale = geom['scale']

    # make object smooth
    eUtils.smoothen_surface(newgeom)

    return newgeom
Exemple #8
0
def createPrimitive(
    pname,
    ptype,
    psize,
    player=0,
    pmaterial=None,
    plocation=(0, 0, 0),
    protation=(0, 0, 0),
    phobostype=None,
):
    """Generates the primitive specified by the input parameters

    Args:
      pname(str): The primitives new name.
      ptype(str): The new primitives type. Can be one of *box, sphere, cylinder, cone, disc*
      psize(float or list): The new primitives size. Depending on the ptype it can be either a single float or a tuple.
      player: The layer bitmask for the new blender object. (Default value = 0)
      pmaterial: The new primitives material. (Default value = None)
      plocation(tuple, optional): The new primitives location. (Default value = (0)
      protation(tuple, optional): The new primitives rotation. (Default value = (0)
      phobostype(str, optional): phobostype of object to be created (Default value = None)
      0: 
      0): 

    Returns:
      : bpy.types.Object - the new blender object.

    """
    # TODO: allow placing on currently active layer?
    try:
        n_layer = int(player)
    except ValueError:
        n_layer = defs.layerTypes[player]
    players = defLayers([n_layer])
    # the layer has to be active to prevent problems with object placement
    bpy.context.scene.layers[n_layer] = True
    if ptype == "box":
        bpy.ops.mesh.primitive_cube_add(layers=players, location=plocation, rotation=protation)
        obj = bpy.context.object
        obj.dimensions = psize
    elif ptype == "sphere":
        bpy.ops.mesh.primitive_uv_sphere_add(
            size=psize, layers=players, location=plocation, rotation=protation
        )
    elif ptype == "cylinder":
        bpy.ops.mesh.primitive_cylinder_add(
            vertices=32,
            radius=psize[0],
            depth=psize[1],
            layers=players,
            location=plocation,
            rotation=protation,
            end_fill_type='TRIFAN',
        )
    elif ptype == "cone":
        bpy.ops.mesh.primitive_cone_add(
            vertices=32,
            radius=psize[0],
            depth=psize[1],
            cap_end=True,
            layers=players,
            location=plocation,
            rotation=protation,
            end_fill_type='TRIFAN',
        )
    elif ptype == 'disc':
        bpy.ops.mesh.primitive_circle_add(
            vertices=psize[1],
            radius=psize[0],
            fill_type='TRIFAN',
            location=plocation,
            rotation=protation,
            layers=players,
        )
    elif ptype == 'ico':
        bpy.ops.mesh.primitive_ico_sphere_add(
            size=psize, layers=players, location=plocation, rotation=protation
        )
    else:
        log("Primitive type not found: " + ptype + ". Adding default cube instead.", 'WARNING')
        bpy.ops.mesh.primitive_cube_add(layers=players, location=plocation, rotation=protation)
        obj = bpy.context.object
        obj.dimensions = psize

    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    obj = bpy.context.object
    if phobostype:
        obj.phobostype = phobostype
    nUtils.safelyName(obj, pname, phobostype)
    if pmaterial:
        materials.assignMaterial(obj, pmaterial)
    return obj
Exemple #9
0
def createGeometry(viscol, geomsrc):
    """Creates geometrical Blender object for visual or collision objects.

    :param viscol: The visual/collision dictionary element you want to create the geometry for.
    :type viscol: dict
    :param geomsrc: The new viscols phobostype.
    :type geomsrc: str

    """
    if 'geometry' not in viscol or viscol['geometry'] is {}:
        return None
    newgeom = None
    bpy.ops.object.select_all(action='DESELECT')
    geom = viscol['geometry']
    geomtype = geom['type']
    # create the Blender object
    if geomtype == 'mesh':
        # if hasattr(self, 'zipped') and self.zipped:
        #     if not os.path.isdir(os.path.join(self.tmp_path, tmp_dir_name)):
        #         os.mkdir(os.path.join(self.tmp_path, tmp_dir_name))
        #     archive = zipfile.ZipFile(self.filepath)
        #     archive.extract(geom['filename'], path=os.path.join(self.tmp_path, tmp_dir_name))
        #     geom_path = os.path.join(os.path.abspath(os.path.join(self.tmp_path, tmp_dir_name)), geom['filename'])
        # else:
        if 'sourcefilepath' in geom:
            geom_path = os.path.normpath(
                os.path.join(os.path.dirname(geom['sourcefilepath']),
                             geom['filename']))
            log('sourcefilepath: ' + geom_path, 'DEBUG', 'createGeometry')
        else:
            geom_path = geom['filename']
        # Remove 'urdf/package://{package_name}' to workaround the lack
        # of rospack here. This supposes that the urdf file is in the
        # urdf folder and that the meshes are in the meshes folder at
        # the same level as the urdf folder.
        if 'package://' in geom_path:
            geom_path = re.sub(r'(.*)urdf/package://([^/]+)/(.*)', '\\1\\3',
                               geom_path)

        bpy.context.scene.layers = bUtils.defLayers(defs.layerTypes[geomsrc])
        meshname = "".join(os.path.basename(geom["filename"]).split(".")[:-1])
        if not os.path.isfile(geom_path):
            log(
                geom_path + " is no file. Object " + viscol['name'] +
                " will have empty mesh!", "ERROR", "createGeometry")
            bpy.data.meshes.new(meshname)
        if meshname in bpy.data.meshes:
            log(
                'Assigning copy of existing mesh ' + meshname + ' to ' +
                viscol['name'], 'INFO', 'createGeometry')
            bpy.ops.object.add(type='MESH')
            newgeom = bpy.context.object
            newgeom.data = bpy.data.meshes[meshname]
        else:
            log('Importing mesh for link element ' + viscol['name'], 'INFO',
                'createGeometry')
            filetype = geom['filename'].split('.')[-1].lower()
            newgeom = meshes.importMesh(geom_path, filetype)
            newgeom.data.name = meshname
            if not newgeom:
                log('Failed to import mesh file ' + geom['filename'], 'ERROR',
                    'createGeometry')
                return
            # scale imported object
            if 'scale' in geom:
                sUtils.selectObjects((newgeom, ), clear=True)
                newgeom.scale = geom['scale']
    else:
        if geomtype == 'box':
            dimensions = geom['size']
        elif geomtype == 'cylinder':
            dimensions = (geom['radius'], geom['length'])
        elif geomtype == 'sphere':
            dimensions = geom['radius']
        else:
            log(
                "Could not determine geometry type of " + geomsrc +
                viscol['name'] + '. Placing empty coordinate system.', "ERROR")
            bpy.ops.object.empty_add(type='PLAIN_AXES', radius=0.2)
            bpy.context.active_object.name = viscol['name']
            return None
        log('Creating primitve for obj ' + viscol['name'], 'INFO',
            'createGeometry')
        newgeom = bUtils.createPrimitive(viscol['name'],
                                         geomtype,
                                         dimensions,
                                         player=geomsrc)
        newgeom.select = True
        bpy.ops.object.transform_apply(scale=True)

    # from here it's the same for both meshes and primitives
    newgeom.phobostype = geomsrc
    newgeom['geometry/type'] = geomtype
    if geomsrc == 'visual':
        try:
            if 'name' in viscol['material']:
                assignMaterial(newgeom, viscol['material']['name'])
            else:
                assignMaterial(newgeom, viscol['material'])
        except KeyError:
            log('No material for obj', viscol['name'], 'DEBUG',
                'createGeometry')
    #FIXME: place empty coordinate system and return...what? Error handling of file import!
    for prop in viscol:
        if prop.startswith('$'):
            for tag in viscol[prop]:
                newgeom[prop[1:] + '/' + tag] = viscol[prop][tag]
    newgeom.name = viscol['name']
    newgeom[geomsrc + "/name"] = viscol['name']
    return newgeom