Trimesh,使两个网格对象合并在一起

huangapple go评论147阅读模式
英文:

Trimesh, Making two mesh objects merge with each other

问题

我有一个脚本,将两组网格放入一个列表中。当我想要导出结果时,我将所有对象加载到场景中,然后导出场景。一个组是倾斜的圆柱体,另一个组是竖直的圆柱体。

每个倾斜的圆柱体都被平移和变换,以使其指向下一个(最近的)竖直圆柱体,但由于某种原因,当最终场景被导出时,倾斜的圆柱体会出现在竖直的圆柱体下方。

存在的倾斜梁/支撑应该从每个圆柱体的顶部开始,然后移到下一个最近的圆柱体。

我如何使倾斜的圆柱体合并在一起,而不是出现在竖直圆柱体下方?

这是我的实现:

import trimesh
import numpy as np

connection_points = read_blue_points_file("blue_points.txt")
cylinders = []
beams = []
scene = trimesh.Scene()

# 按X坐标对数组进行排序
connection_points = connection_points[connection_points[:, 0].argsort()]
print(connection_points)

# 创建圆柱体
for point in connection_points:
    height = point[2]
    cylinder = trimesh.primitives.Cylinder(radius=0.5, height=height, transform=None, sections=32, mutable=True)
    cylinder.apply_translation((point[0], point[1], 0))
    cylinder.collide = False
    cylinders.append(cylinder)

for index, point in enumerate(connection_points):
    if index < len(connection_points) - 1:
        current_cylinder = point
        next_cylinder = connection_points[index + 1]

    Angle = find_angle_between_points(current_cylinder, next_cylinder)
    Direction = current_cylinder - next_cylinder

    rotation_matrix = trimesh.transformations.rotation_matrix(angle=Angle, direction=Direction)
    distance = distance_between_points(current_cylinder, next_cylinder)
    beam = trimesh.primitives.Cylinder(Radius=0.1, height=distance / 2, transform=rotation_matrix, Sections=32, mutable=True)
    beam.apply_translation(next_cylinder)
    beams.append(beam)
def read_blue_points_file(filename):
    """读取蓝点的文本文件,并返回点的数组。"""

    points = []
    with open(filename, "r") as f:
        for line in f:
            point = [float(x) for x in line.split(",")]
            points.append(point)

    return np.array(points)
def find_angle_between_points(point1, point2):
    # 计算两个向量之间的角度
    angle = np.arccos(np.dot(point1, point2) / (np.linalg.norm(point1) * np.linalg.norm(point2)))

    return math.degrees(angle)
# 输入两个XYZ点,返回两点之间的距离
def distance_between_points(point1, point2):

    # 将点转换为numpy数组。
    point1 = np.array(point1)
    point2 = np.array(point2)

    # 计算两点之间的差值。
    difference = np.subtract(point2, point1)

    # 计算差值向量的模。
    norm = np.linalg.norm(difference)

    # 返回距离。
    return norm

点列表的文本文件

当前结果

英文:

I have a script that places two sets of meshes into a list. When I want to export the result, I load all the objects into a scene and then I export the scene. One being a set of slanted cylinders, and the other a set of vertical cylinders.

Each slanted cylinder is translated and transformed so that it is pointing towards the next (closest) vertical cylinder, but for some reason when the final scene is exported the slanted cylinders appear below the vertical cylinders.

the slanted beams/braces that are present are supposed to start at the top of each cylinder and move across to the next closest cylinder.

**How can I make it so the slanted cylinders are merged together instead of appearing below the vertical cylinders? **

Here is my implementation;

import trimesh
import numpy as np

connection_points = read_blue_points_file(&quot;blue_points.txt&quot;)
cylinders = []
beams = []
scene = trimesh.Scene()

# Sort the array by the X coordinate
connection_points = connection_points[connection_points[:, 0].argsort()]
print(connection_points)

# Create Cylinders
for point in connection_points:
    height = point[2]
    cylinder = trimesh.primitives.Cylinder(radius=0.5, height=height, transform=None, sections=32, mutable=True)
    cylinder.apply_translation((point[0],point[1],0))
    cylinder.collide = False
    cylinders.append(cylinder)

for index, point in enumerate(connection_points):
    if index &lt; len(connection_points) - 1:
        current_cylinder = point
        next_cylinder = connection_points[index + 1]

    Angle = find_angle_between_points(current_cylinder, next_cylinder)
    Direction = current_cylinder - next_cylinder

    rotation_matrix = trimesh.transformations.rotation_matrix(angle = Angle , direction = Direction)
    distance = distance_between_points(current_cylinder, next_cylinder)
    beam = trimesh.primitives.Cylinder(Radius = 0.1, height = distance/2, transform=rotation_matrix, Sections=32, mutable=True)
    beam.apply_translation(next_cylinder)
    beams.append(beam)
        def read_blue_points_file(filename):
      &quot;&quot;&quot;Reads a text file of blue points and returns an array of points.&quot;&quot;&quot;
    
      points = []
      with open(filename, &quot;r&quot;) as f:
        for line in f:
          point = [float(x) for x in line.split(&quot;,&quot;)]
          points.append(point)
    
      return np.array(points)
def find_angle_between_points(point1, point2):
    # Calculate the angle between the two vectors
    angle = np.arccos(np.dot(point1, point2) / (np.linalg.norm(point1) * np.linalg.norm(point2)))

    return math.degrees(angle)
#input two XYZ points, return distance between points
def distance_between_points(point1, point2):

  # Convert the points to numpy arrays.
  point1 = np.array(point1)
  point2 = np.array(point2)

  # Calculate the difference between the two points.
  difference = np.subtract(point2, point1)

  # Calculate the norm of the difference vector.
  norm = np.linalg.norm(difference)

  # Return the distance.
  return norm

Text File of List of points

Current Result

答案1

得分: 0

以下是您提供的代码的翻译:

# 通过上述提到的调整,这是一些我用来检查的输出-请注意我可能已经垂直翻转它-但应足够帮助您使您的工作:

[![enter image description here][1]][1]

[1]: https://i.stack.imgur.com/xKpJz.png

更新后的代码如下

import trimesh
import numpy as np

# 输入两个XYZ点,返回点之间的距离
def distance_between_points(point1, point2):

    # 将点转换为numpy数组。
    point1 = np.array(point1)
    point2 = np.array(point2)

    # 计算两点之间的差值。
    difference = np.subtract(point2, point1)

    # 计算差值向量的范数。
    norm = np.linalg.norm(difference)

    # 返回距离。
    return norm

def find_angle_between_points(point1, point2):
    # 计算两个向量之间的角度

    print("P1 ", point1)
    print("P2 ", point2)

    angle = np.arccos(np.dot(point1, point2-point1) / (np.linalg.norm(point1) * np.linalg.norm(point2-point1)))
    print("NormP1 ", np.linalg.norm(point1))
    print("NormP2 ", np.linalg.norm(point2))

    return np.degrees(angle)

def read_blue_points_file(filename):
    """读取蓝色点的文本文件并返回点的数组。"""

    points = []
    with open(filename, "r") as f:
        for line in f:
            point = [float(x) for x in line.split(",")]
            points.append(point)

    return np.array(points)

def main():

    print("在主函数中")
    connection_points = read_blue_points_file("blue_points.txt")
    cylinders = []
    beams = []
    scene = trimesh.Scene()
    # 按X坐标对数组进行排序
    connection_points = connection_points[connection_points[:, 0].argsort()]
    print(connection_points)
    # 创建圆柱体
    for point in connection_points:
        height = point[2]
        cylinder = trimesh.primitives.Cylinder(radius=0.5, height=height, transform=None, sections=32, mutable=True)
        cylinder.apply_translation((point[0],point[1],height/2))
        cylinder.collide = False
        cylinders.append(cylinder)

    for index, point in enumerate(connection_points):
        if index < len(connection_points) - 1:
            current_cylinder = point
            next_cylinder = connection_points[index + 1]

            Angle = find_angle_between_points(current_cylinder, next_cylinder)
            Direction = current_cylinder - next_cylinder
            print("direction", Direction)
            print("angle ", Angle)

            rotation_matrix = trimesh.geometry.align_vectors([0, 0, 1], Direction, return_angle=False)

            print("旋转矩阵", rotation_matrix)
            distance = distance_between_points(current_cylinder, next_cylinder)
            print(distance)

            beam = trimesh.primitives.Cylinder(radius = 0.1, height = distance, transform=rotation_matrix, sections=32, mutable=True)

            beam.apply_translation(current_cylinder - Direction*0.5)
            beams.append(beam)

    scene.add_geometry(cylinders)
    scene.add_geometry(beams)
    scene.export("op.stl")

if __name__ == '__main__':
    main()

请注意,我已经将HTML标签进行了适当的翻译,以使代码更容易理解。如果您有任何其他疑问,请随时提出。

英文:

With the above mentioned tweaks, here's some output I used to check it- note I might have flipped it vertically- but should be enough for you to get yours working:

Trimesh,使两个网格对象合并在一起

Updated code as follows:

import trimesh
import numpy as np
#input two XYZ points, return distance between points
def distance_between_points(point1, point2):
# Convert the points to numpy arrays.
point1 = np.array(point1)
point2 = np.array(point2)
# Calculate the difference between the two points.
difference = np.subtract(point2, point1)
# Calculate the norm of the difference vector.
norm = np.linalg.norm(difference)
# Return the distance.
return norm
def find_angle_between_points(point1, point2):
# Calculate the angle between the two vectors
print(&quot;P1 &quot;, point1)
print(&quot;P2 &quot;, point2)
angle = np.arccos(np.dot(point1, point2-point1) / (np.linalg.norm(point1) * np.linalg.norm(point2-point1)))
print(&quot;NormP1 &quot;, np.linalg.norm(point1))
print(&quot;NormP2 &quot;, np.linalg.norm(point2))
return np.degrees(angle)
def read_blue_points_file(filename):
&quot;&quot;&quot;Reads a text file of blue points and returns an array of points.&quot;&quot;&quot;
points = []
with open(filename, &quot;r&quot;) as f:
for line in f:
point = [float(x) for x in line.split(&quot;,&quot;)]
points.append(point)
return np.array(points)
def main():
print(&quot;IN MAIN&quot;)
connection_points = read_blue_points_file(&quot;blue_points.txt&quot;)
cylinders = []
beams = []
scene = trimesh.Scene()
# Sort the array by the X coordinate
connection_points = connection_points[connection_points[:, 0].argsort()]
print(connection_points)
# Create Cylinders
for point in connection_points:
height = point[2]
cylinder = trimesh.primitives.Cylinder(radius=0.5, height=height, transform=None, sections=32, mutable=True)
cylinder.apply_translation((point[0],point[1],height/2))
cylinder.collide = False
cylinders.append(cylinder)
for index, point in enumerate(connection_points):
if index &lt; len(connection_points) - 1:
current_cylinder = point
next_cylinder = connection_points[index + 1]
Angle = find_angle_between_points(current_cylinder, next_cylinder)
Direction = current_cylinder - next_cylinder
print(&quot;direction&quot;, Direction)
print(&quot;angle &quot;, Angle)
rotation_matrix = trimesh.geometry.align_vectors([0, 0, 1], Direction, return_angle=False)
print(&quot;r matrix &quot;, rotation_matrix)
distance = distance_between_points(current_cylinder, next_cylinder)
print(distance)
beam = trimesh.primitives.Cylinder(radius = 0.1, height = distance, transform=rotation_matrix, sections=32, mutable=True)
beam.apply_translation(current_cylinder - Direction*0.5)
beams.append(beam)
scene.add_geometry(cylinders)
scene.add_geometry(beams)
scene.export(&quot;op.stl&quot;)
if __name__ == &#39;__main__&#39;:
main()

huangapple
  • 本文由 发表于 2023年6月16日 02:34:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76484583.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定