[Blender] реструктуризация на основе LCS #77

Closed
opened 2023-06-08 10:54:18 +03:00 by brothermechanic · 10 comments
brothermechanic commented 2023-06-08 10:54:18 +03:00 (Migrated from gitlab.com)

Разработать возможность самостоятельного импорта LCS в блендер сцену и возможность обновления LCS.
Переделать на импорт точек из FreeCAD.
После импорта LCS необходимо выполнить:

  • отпарентить LCS точки
  • перепарентить локатор-парент LCS и точку LCS_out к точке LCS_in
  • все LCS_in парентим к LCS_root
  • все локаторы без LCS парентим к LCS_root и перемещаем в отделную коллекцию
  • обнуляем трансформации LCS_root
Разработать возможность самостоятельного импорта LCS в блендер сцену и возможность обновления LCS. Переделать на импорт точек из FreeCAD. После импорта LCS необходимо выполнить: - отпарентить LCS точки - перепарентить локатор-парент LCS и точку LCS_out к точке LCS_in - все LCS_in парентим к LCS_root - все локаторы без LCS парентим к LCS_root и перемещаем в отделную коллекцию - обнуляем трансформации LCS_root
brothermechanic commented 2023-06-08 10:54:23 +03:00 (Migrated from gitlab.com)

assigned to @brothermechanic

assigned to @brothermechanic
brothermechanic commented 2023-06-08 11:06:12 +03:00 (Migrated from gitlab.com)

changed the description

changed the description
brothermechanic commented 2023-06-08 11:23:33 +03:00 (Migrated from gitlab.com)

changed the description

changed the description
brothermechanic commented 2023-06-08 11:23:43 +03:00 (Migrated from gitlab.com)

changed the description

changed the description
brothermechanic commented 2023-06-13 23:41:32 +03:00 (Migrated from gitlab.com)
# -*- coding: utf-8 -*-
"""
DESCRIPTION.
Reorganization and restructuring of assembly structure
based on LCS point objects.
"""
__version__ = "0.1"
import logging
import math

import bpy
from mathutils import Matrix

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)


def parenting(parent, child):
    """ Parenting child object to parent object. """
    child.parent = parent
    child.matrix_parent_inverse = parent.matrix_world.inverted()
    return child


def unparenting(child):
    """ Unarenting child object from parent object. """
    world_matrix = child.matrix_world.copy()
    child.parent = None
    child.matrix_world = world_matrix
    return child


def round_transforms(obj):
    """ Geting location of object and round it. """
    for idx, axis in enumerate(obj.location[:]):
        obj.location[idx] = round(axis, 5)
    return obj.location


def retree_by_lcs(lcs_objects, root_lcs):
    """ Organizing project structure based on LCS. """
    for lcs in lcs_objects:
        locator = lcs.parent
        if lcs.name.endswith('_in'):
            unparenting(lcs)
            round_transforms(lcs)
            if locator.parent:
                unparenting(locator)
            parenting(lcs, locator)
            parenting(root_lcs, lcs)
    for lcs in lcs_objects:
        if lcs.name.endswith('_out'):
            unparenting(lcs)
            round_transforms(lcs)
            parenting(
                lcs_objects[
                    lcs_objects.index(
                        bpy.data.objects['%s_in' % (lcs.name.split('_out')[0])]
                    )
                ],
                lcs)

    root_lcs.matrix_world = Matrix()
    return lcs_objects


def closest_lcs(lcs_objects):
    """ Finding closest outlet to inlet LCS. """
    target_dists = {}
    for target in lcs_objects:
        if target.name.endswith('_in'):
            dists = {}
            for lcs in lcs_objects:
                if lcs.name.endswith('_out'):
                    dist = math.dist(
                        target.matrix_world.translation, lcs.matrix_world.translation)
                    dists[lcs.name] = dist
            min_dist = min(dists.values())
            if min_dist < 0.01:
                min_lcs = [k for k, v in dists.items() if v == min_dist][0]
                target_dists[target.name] = min_lcs
    return target_dists


def lcs_constrainting(lcs_objects, root_lcs):
    """ Placing inlet right on outlet LCS. """
    closests = closest_lcs(lcs_objects)
    for lcs in lcs_objects:
        if lcs.name in closests:
            constraint = lcs.constraints.new(type='COPY_TRANSFORMS')
            constraint.target = bpy.data.objects[closests[lcs.name]]
        if lcs.name.endswith('_out'):
            constraint = lcs.constraints.new(type='COPY_TRANSFORMS')
            constraint.target = root_lcs
            constraint.enabled = False
    for lcs in lcs_objects:
        if len(lcs.constraints) == 0:
            constraint = lcs.constraints.new(type='COPY_TRANSFORMS')
            constraint.target = root_lcs
            constraint.enabled = False
    return lcs_objects


def unlink_from_col(obj):
    """ Unlinking object from all collections. """
    for col in bpy.data.collections:
        if obj.name in col.objects:
            col.objects.unlink(obj)
    return obj


def part_collections(root_lcs, lcs_objects):
    """ Create LCS based hierarchy. """
    for lcs in root_lcs.children:
        lcs_col = bpy.data.collections.new(lcs.name.split('_in'))
        bpy.data.collections['Import Parts'].children.link(lcs_col)
        for obj in lcs.children_recursive:
            unlink_from_col(obj)
            lcs_col.objects.link(obj)
        if lcs not in lcs_objects:
            unlink_from_col(lcs)
            lcs_col.objects.link(lcs)
    return root_lcs.children


lcs_objects = bpy.data.collections['Import LCS'].objects

main_locator = [obj for obj in bpy.data.objects if not obj.parent][0]
root_lcs = [lcs for lcs in lcs_objects if lcs.name.endswith('_root')][0]
lcs_objects = [lcs for lcs in lcs_objects if lcs != root_lcs]
root_locator = root_lcs.parent
unparenting(root_lcs)
round_transforms(root_lcs)
unparenting(root_locator)
parenting(root_lcs, root_locator)
parenting(root_lcs, main_locator)

retree_by_lcs(lcs_objects, root_lcs)
lcs_constrainting(lcs_objects, root_lcs)

part_collections(root_lcs, lcs_objects)
bpy.data.collections.remove(bpy.data.collections['Import Hierarchy'])

```python # -*- coding: utf-8 -*- """ DESCRIPTION. Reorganization and restructuring of assembly structure based on LCS point objects. """ __version__ = "0.1" import logging import math import bpy from mathutils import Matrix logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) def parenting(parent, child): """ Parenting child object to parent object. """ child.parent = parent child.matrix_parent_inverse = parent.matrix_world.inverted() return child def unparenting(child): """ Unarenting child object from parent object. """ world_matrix = child.matrix_world.copy() child.parent = None child.matrix_world = world_matrix return child def round_transforms(obj): """ Geting location of object and round it. """ for idx, axis in enumerate(obj.location[:]): obj.location[idx] = round(axis, 5) return obj.location def retree_by_lcs(lcs_objects, root_lcs): """ Organizing project structure based on LCS. """ for lcs in lcs_objects: locator = lcs.parent if lcs.name.endswith('_in'): unparenting(lcs) round_transforms(lcs) if locator.parent: unparenting(locator) parenting(lcs, locator) parenting(root_lcs, lcs) for lcs in lcs_objects: if lcs.name.endswith('_out'): unparenting(lcs) round_transforms(lcs) parenting( lcs_objects[ lcs_objects.index( bpy.data.objects['%s_in' % (lcs.name.split('_out')[0])] ) ], lcs) root_lcs.matrix_world = Matrix() return lcs_objects def closest_lcs(lcs_objects): """ Finding closest outlet to inlet LCS. """ target_dists = {} for target in lcs_objects: if target.name.endswith('_in'): dists = {} for lcs in lcs_objects: if lcs.name.endswith('_out'): dist = math.dist( target.matrix_world.translation, lcs.matrix_world.translation) dists[lcs.name] = dist min_dist = min(dists.values()) if min_dist < 0.01: min_lcs = [k for k, v in dists.items() if v == min_dist][0] target_dists[target.name] = min_lcs return target_dists def lcs_constrainting(lcs_objects, root_lcs): """ Placing inlet right on outlet LCS. """ closests = closest_lcs(lcs_objects) for lcs in lcs_objects: if lcs.name in closests: constraint = lcs.constraints.new(type='COPY_TRANSFORMS') constraint.target = bpy.data.objects[closests[lcs.name]] if lcs.name.endswith('_out'): constraint = lcs.constraints.new(type='COPY_TRANSFORMS') constraint.target = root_lcs constraint.enabled = False for lcs in lcs_objects: if len(lcs.constraints) == 0: constraint = lcs.constraints.new(type='COPY_TRANSFORMS') constraint.target = root_lcs constraint.enabled = False return lcs_objects def unlink_from_col(obj): """ Unlinking object from all collections. """ for col in bpy.data.collections: if obj.name in col.objects: col.objects.unlink(obj) return obj def part_collections(root_lcs, lcs_objects): """ Create LCS based hierarchy. """ for lcs in root_lcs.children: lcs_col = bpy.data.collections.new(lcs.name.split('_in')) bpy.data.collections['Import Parts'].children.link(lcs_col) for obj in lcs.children_recursive: unlink_from_col(obj) lcs_col.objects.link(obj) if lcs not in lcs_objects: unlink_from_col(lcs) lcs_col.objects.link(lcs) return root_lcs.children lcs_objects = bpy.data.collections['Import LCS'].objects main_locator = [obj for obj in bpy.data.objects if not obj.parent][0] root_lcs = [lcs for lcs in lcs_objects if lcs.name.endswith('_root')][0] lcs_objects = [lcs for lcs in lcs_objects if lcs != root_lcs] root_locator = root_lcs.parent unparenting(root_lcs) round_transforms(root_lcs) unparenting(root_locator) parenting(root_lcs, root_locator) parenting(root_lcs, main_locator) retree_by_lcs(lcs_objects, root_lcs) lcs_constrainting(lcs_objects, root_lcs) part_collections(root_lcs, lcs_objects) bpy.data.collections.remove(bpy.data.collections['Import Hierarchy']) ```
brothermechanic commented 2023-06-14 09:53:11 +03:00 (Migrated from gitlab.com)
import bpy

lcs_objects = bpy.data.collections['Import LCS'].objects

root_lcs = [lcs for lcs in lcs_objects if lcs.name.endswith('_root')][0]
lcs_objects = [lcs for lcs in lcs_objects if lcs != root_lcs]

for lcs in bpy.data.objects:
    if lcs.type != 'EMPTY':
        continue
    if not hasattr(lcs, 'constraints'):
        continue
    if not "Copy Transforms" in lcs.constraints:
        continue
    if lcs.constraints["Copy Transforms"].target != root_lcs:
        continue
    lcs.constraints["Copy Transforms"].enabled = True

render_col = bpy.data.collections.new('Render Parts')
bpy.context.scene.collection.children.link(render_col)
for lcs in lcs_objects:
    bpy.ops.object.select_all(action='DESELECT')
    bpy.ops.object.collection_instance_add(
        collection=lcs.name, location=(0, 0, 0), scale=(1, 1, 1))
    empty = bpy.context.object
    empty.empty_display_size = 0.1
    empty.name = ('%s_render' % lcs.name.split('_in')[0])
    bpy.context.scene.collection.objects.unlink(empty)
    render_col.objects.link(empty)
```python import bpy lcs_objects = bpy.data.collections['Import LCS'].objects root_lcs = [lcs for lcs in lcs_objects if lcs.name.endswith('_root')][0] lcs_objects = [lcs for lcs in lcs_objects if lcs != root_lcs] for lcs in bpy.data.objects: if lcs.type != 'EMPTY': continue if not hasattr(lcs, 'constraints'): continue if not "Copy Transforms" in lcs.constraints: continue if lcs.constraints["Copy Transforms"].target != root_lcs: continue lcs.constraints["Copy Transforms"].enabled = True render_col = bpy.data.collections.new('Render Parts') bpy.context.scene.collection.children.link(render_col) for lcs in lcs_objects: bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.collection_instance_add( collection=lcs.name, location=(0, 0, 0), scale=(1, 1, 1)) empty = bpy.context.object empty.empty_display_size = 0.1 empty.name = ('%s_render' % lcs.name.split('_in')[0]) bpy.context.scene.collection.objects.unlink(empty) render_col.objects.link(empty) ```
brothermechanic commented 2023-06-19 12:00:17 +03:00 (Migrated from gitlab.com)

marked this issue as related to #83

marked this issue as related to #83
brothermechanic commented 2023-06-19 12:01:21 +03:00 (Migrated from gitlab.com)

@movefasta
Готово! Структура на основе LCS точек!
Screenshot_20230619_115711

@movefasta Готово! Структура на основе LCS точек! ![Screenshot_20230619_115711](/uploads/eb6456dc4c96c3e1fa405453a05c5f7b/Screenshot_20230619_115711.jpg)
brothermechanic (Migrated from gitlab.com) closed this issue 2023-06-19 12:01:33 +03:00
brothermechanic commented 2023-06-19 12:02:03 +03:00 (Migrated from gitlab.com)

marked this issue as related to #67

marked this issue as related to #67
brothermechanic commented 2023-06-19 23:02:51 +03:00 (Migrated from gitlab.com)

mentioned in merge request !36

mentioned in merge request !36
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
robossembler/framework#77
No description provided.