Beispiel #1
0
def getInertiaRelevantObjects(link, selected_only=False):
    """Returns a list of visual and collision objects of a link.
    If name-pairs of visual and collision objects are detected,
    the one with the latest change-date is used. If this is not clear,
    visual objects are omitted in favor of collision objects. If the
    selected_only parameter is used, only the selected objects are considered.

    Args:
      link(bpy_types.Object): The link you want to gather the inertia relevant objects for.
      selected_only(bool, optional): return only relevant objects which are selected (Default value = False)

    Returns:
      list

    """
    objdict = {
        obj.name: obj
        for obj in sUtils.getImmediateChildren(link, ['visual', 'collision'],
                                               selected_only)
    }
    basenames = set()
    inertiaobjects = []
    for objname in objdict.keys():
        if 'mass' in objdict[objname]:
            if not objname.startswith('visual_') and not objname.startswith(
                    'collision_'):
                inertiaobjects.append(objdict[objname])
            else:
                basename = objname.replace(objdict[objname].phobostype + '_',
                                           '')
                if basename not in basenames:
                    basenames.add(basename)
                    collision = 'collision_'+basename if 'collision_'+basename in objdict.keys()\
                        and 'mass' in objdict['collision_'+basename] else None
                    visual = 'visual_'+basename if 'visual_'+basename in objdict.keys()\
                        and 'mass' in objdict['visual_'+basename] else None
                    if visual and collision:
                        try:
                            tv = gUtils.datetimeFromIso(
                                objdict[visual]['masschanged'])
                            tc = gUtils.datetimeFromIso(
                                objdict[collision]['masschanged'])
                            # if collision information is older than visual information
                            if tc < tv:
                                inertiaobjects.append(objdict[visual])
                            else:
                                inertiaobjects.append(objdict[collision])
                        # if masschanged not present in both
                        except KeyError:
                            inertiaobjects.append(objdict[collision])
                    else:
                        inertiaobjects.append(objdict[collision] if collision
                                              else objdict[visual])
    return inertiaobjects
Beispiel #2
0
    def execute(self, context):
        sourcelist = []
        targetlist = []
        processed = set()
        links = [obj.name for obj in bpy.context.selected_objects if obj.phobostype == 'link']
        t = datetime.now()
        objdict = {obj.name: obj for obj in bpy.data.objects if obj.phobostype in ['visual', 'collision']
                   and obj.parent.name in links}
        # gather all name bases of objects for which both visual and collision are present
        for obj in objdict.keys():
            basename = obj.replace(objdict[obj].phobostype + '_', '')
            if 'visual_' + basename in objdict.keys() and 'collision_' + basename in objdict.keys():
                processed.add(basename)
        # fill source and target lists for syncing
        for basename in processed:
            if self.synctype == "vtc":
                sourcelist.append('visual_' + basename)
                targetlist.append('collision_' + basename)
            elif self.synctype == "ctv":
                targetlist.append('visual_' + basename)
                sourcelist.append('collision_' + basename)
            else:  # latest to oldest
                try:
                    tv = generalUtils.datetimeFromIso(objdict['visual_' + basename]['masschanged'])
                    tc = generalUtils.datetimeFromIso(objdict['collision_' + basename]['masschanged'])
                    if tc < tv:  # if collision information is older than visual information
                        sourcelist.append('visual_' + basename)
                        targetlist.append('collision_' + basename)
                    else:
                        targetlist.append('visual_' + basename)
                        sourcelist.append('collision_' + basename)
                except KeyError:
                    print(basename, "has insufficient data for time-based synchronisation of masses.")
        # sync the mass values
        for i in range(len(sourcelist)):
            try:
                objdict[targetlist[i]]['mass'] = objdict[sourcelist[i]]['mass']
            except KeyError:
                print("No mass information in object", targetlist[i])
            if self.synctype != "vtc" and self.synctype != "ctv":
                objdict[targetlist[i]]['masschanged'] = objdict[sourcelist[i]]['masschanged']

        for linkname in links:
            masssum = 0.0
            link = bpy.data.objects[linkname]
            viscols = inertia.getInertiaRelevantObjects(link)
            for obj in viscols:
                masssum += obj['mass']
            link['mass'] = masssum
            link['masschanged'] = t.isoformat()
            if self.updateinertial:
                inertia.createInertials(link)
        return {'FINISHED'}
Beispiel #3
0
def getInertiaRelevantObjects(link):
    """Returns a list of visual and collision objects of a link.
    If name-pairs of visual and collision objects are detected,
    the one with the latest change-date is used. If this is not clear,
    visual objects are omitted in favor of collision objects.

    :param link: The link you want to gather the inertia relevant objects for.
    :type link: bpy_types.Object
    :return: list

    """
    objdict = {
        obj.name: obj
        for obj in selectionUtils.getImmediateChildren(link,
                                                       ['visual', 'collision'])
    }
    basenames = set()
    inertiaobjects = []
    for objname in objdict.keys():
        if 'mass' in objdict[objname]:
            if not objname.startswith('visual_') and not objname.startswith(
                    'collision_'):
                inertiaobjects.append(objdict[objname])
            else:
                basename = objname.replace(objdict[objname].phobostype + '_',
                                           '')
                if not basename in basenames:
                    basenames.add(basename)
                    collision = 'collision_'+basename if 'collision_'+basename in objdict.keys()\
                        and 'mass' in objdict['collision_'+basename] else None
                    visual = 'visual_'+basename if 'visual_'+basename in objdict.keys()\
                        and 'mass' in objdict['visual_'+basename] else None
                    if visual and collision:
                        try:
                            tv = generalUtils.datetimeFromIso(
                                objdict[visual]['masschanged'])
                            tc = generalUtils.datetimeFromIso(
                                objdict[collision]['masschanged'])
                            if tc < tv:  # if collision information is older than visual information
                                inertiaobjects.append(objdict[visual])
                            else:
                                inertiaobjects.append(objdict[collision])
                        except KeyError:  # if masschanged not present in both
                            inertiaobjects.append(objdict[collision])
                    else:
                        inertiaobjects.append(objdict[collision] if collision
                                              else objdict[visual])
    return inertiaobjects
Beispiel #4
0
def getInertiaRelevantObjects(link):
    """Returns a list of visual and collision objects of a link.
    If name-pairs of visual and collision objects are detected,
    the one with the latest change-date is used. If this is not clear,
    visual objects are omitted in favor of collision objects.

    :param link: The link you want to gather the inertia relevant objects for.
    :type link: Blender object.
    :return: list.

    """
    objdict = {obj.name: obj for obj in selectionUtils.getImmediateChildren(link, ['visual', 'collision'])}
    basenames = set()
    inertiaobjects = []
    for objname in objdict.keys():
        if 'mass' in objdict[objname]:
            if not objname.startswith('visual_') and not objname.startswith('collision_'):
                inertiaobjects.append(objdict[objname])
            else:
                basename = objname.replace(objdict[objname].phobostype + '_', '')
                if not basename in basenames:
                    basenames.add(basename)
                    collision = 'collision_'+basename if 'collision_'+basename in objdict.keys()\
                        and 'mass' in objdict['collision_'+basename] else None
                    visual = 'visual_'+basename if 'visual_'+basename in objdict.keys()\
                        and 'mass' in objdict['visual_'+basename] else None
                    if visual and collision:
                        try:
                            tv = generalUtils.datetimeFromIso(objdict[visual]['masschanged'])
                            tc = generalUtils.datetimeFromIso(objdict[collision]['masschanged'])
                            if tc < tv:  # if collision information is older than visual information
                                inertiaobjects.append(objdict[visual])
                            else:
                                inertiaobjects.append(objdict[collision])
                        except KeyError:  # if masschanged not present in both
                            inertiaobjects.append(objdict[collision])
                    else:
                        inertiaobjects.append(objdict[collision] if collision else objdict[visual])
    return inertiaobjects
Beispiel #5
0
    def execute(self, context):
        sourcelist = []
        targetlist = []
        processed = set()
        # FIXME NoneTypeError although objects are selected
        links = [
            obj.name for obj in context.selected_objects
            if obj.phobostype == 'link'
        ]
        t = datetime.now()
        objdict = {
            obj.name: obj
            for obj in bpy.data.objects
            if obj.phobostype in ['visual', 'collision']
            and obj.parent.name in links
        }

        # gather all name bases of objects for which both visual and collision are present
        for obj in objdict.keys():
            basename = obj.replace(objdict[obj].phobostype + '_', '')
            if 'visual_' + basename in objdict.keys(
            ) and 'collision_' + basename in objdict.keys():
                processed.add(basename)

        # fill source and target lists for syncing
        for basename in processed:
            if self.synctype == "vtc":
                sourcelist.append('visual_' + basename)
                targetlist.append('collision_' + basename)
            elif self.synctype == "ctv":
                targetlist.append('visual_' + basename)
                sourcelist.append('collision_' + basename)
            else:  # latest to oldest
                try:
                    tv = gUtils.datetimeFromIso(
                        objdict['visual_' + basename]['masschanged'])
                    tc = gUtils.datetimeFromIso(
                        objdict['collision_' + basename]['masschanged'])
                    if tc < tv:  # if collision information is older than visual information
                        sourcelist.append('visual_' + basename)
                        targetlist.append('collision_' + basename)
                    else:
                        targetlist.append('visual_' + basename)
                        sourcelist.append('collision_' + basename)
                except KeyError:
                    log(
                        basename + " has insufficient data for time-based" +
                        "synchronisation of masses.", "WARNING")

        # sync the mass values
        for i in range(len(sourcelist)):
            try:
                objdict[targetlist[i]]['mass'] = objdict[sourcelist[i]]['mass']
            except KeyError:
                log("No mass information in object " + targetlist[i],
                    "WARNING")
            if self.synctype != "vtc" and self.synctype != "ctv":
                objdict[targetlist[i]]['masschanged'] = objdict[
                    sourcelist[i]]['masschanged']

        # update inertials and sum masses for links
        for linkname in links:
            masssum = 0.0
            link = bpy.data.objects[linkname]
            viscols = inertia.getInertiaRelevantObjects(link)
            for obj in viscols:
                masssum += obj['mass']
            link['mass'] = masssum
            link['masschanged'] = t.isoformat()
            if self.updateinertial:
                inertia.createInertials(link)
        return {'FINISHED'}