python3dheight.obj

Print the coordinates of the highest point of an .obj file?


I have never worked on 3D objects with Python so I feel a bit lost.

I would like to know if it is possible to create a program that would detect the highest points of a 3D object (.obj format) and give their coordinates.

I had an idea about comparing each point of the 3D object and only returning the coordinates of the highest one.

I would appreciate any help, even by just telling me where to look at.


EDIT: I created a program that returns the maximum elevation of the object.

It works, but how could I make it return not only the maximum elevation of the highest point, but also its coordinates alongside the other axis?

As an example, it would return: the highest point is at 5.04 m. Its coordinates are (xxx, xxx, 5.04). Is there a way to print the coordinates of a given point?

EDIT 2: Here is my actual code. It returns the maximum height of a .obj. I would like it to return the 3-axis coordinates of the highest point.

Could it be possible to apply this code not to the entire object, but only to a part of it? (example: detect the highest point on z between a precise interval on the x and y axis?) I don't know how to work on coordinates with python

import sys

filename = 'test2.obj'  # sys.argv[1]

x, y, z = [], [], []

with open(filename) as f:
for line in f:
    line = line[:-1].split(' ')
    if line[0] == 'v':
        y.append(float(line[2]))

print('height max = ' + str(max(y)) +  ' m')

input()

Solution

  • EDIT 2: Here is my actual code. It returns the maximum height of a .obj. I would like it to return the 3-axis coordinates of the highest point.

    In your code you only append to the list y. You'll also need to append to the respective x and y lists. You could then find the index of the max value in the y list, and then index into the x and z lists with the same index.

    Keeping the x, y, and z values in separate lists is a bit cumbersome. Consider keeping them in a namedtuple. All you then need is a single list of these namedtuples.

    Consider this as your input file:

    v 10.307 4.083 4.905
    v 1.920 11.778 13.118
    v 7.883 17.747 0.258
    v 5.085 0.353 10.356
    v 8.999 9.146 8.047
    

    And the code:

    import sys
    from collections import namedtuple
    
    Point = namedtuple('Point', 'x y z')
    points = []
    filename = 'test2.obj'  # sys.argv[1]
    
    with open(filename) as f:
        for line in f:
            line = line[:-1].split(' ')
            if line[0] == 'v':
                x, y, z = map(float, line[1:])
                points.append(Point(x, y, z))
    
    highest_point = max(points, key=lambda point: point.z)
    print('Highest point on the z-axis:', highest_point)
    print(highest_point.x, highest_point.y, highest_point.z)
    

    Output:

    Highest point on the z-axis: Point(x=1.92, y=11.778, z=13.118)
    1.92 11.778 13.118
    

    max() takes a keyword argument key that allows you to, in this case, make the comparisons on the z attribute, instead of the Point namedtuple.

    Could it be possible to apply this code not to the entire object, but only to a part of it? (example: detect the highest point on z between a precise interval on the x and y axis?)

    Sure. Before finding the max point, filter the list so it only contains points within the interval. For example:

    filtered_points = []
    for point in points:
        if 9 > point.x > 3 and 10 > point.y > 5:
            filtered_points.append(point)
    
    highest_point = max(filtered_points, key=lambda point: point.z)
    print('Highest point on the z-axis between some interval on the x and y axis:', highest_point)
    

    Output:

    Highest point on the z-axis between some interval on the x and y axis: Point(x=8.999, y=9.146, z=8.04)