Forum

Author Topic: Selection of Model by elevation??  (Read 10304 times)

jwmm2

  • Newbie
  • *
  • Posts: 3
    • View Profile
Selection of Model by elevation??
« on: August 29, 2024, 08:29:16 PM »
Hi all

Is there a method for breaking down models by elevation? I have a 3D model of a seashore and I'm interested in measuring the seaweed composition at different tidal heights (e.g.  above 1m and below 2.5 m elevation). Is there such a way of  processing the model, so I only see the model portion within those elevations? Something like a gradual selection tool for this purpose would be ideal!

Many thanks

Joe

Darko

  • Full Member
  • ***
  • Posts: 146
    • View Profile
    • CADCOM
Re: Selection of Model by elevation??
« Reply #1 on: October 30, 2024, 03:12:21 PM »
Hello,
I have the same problem since my latest project is on the seashore I would like to select all the points with elevation lower than, let's say, -1m. Since the points are on the seafloor I would like to erase them.  Any idea?
Best,
Darko

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15403
    • View Profile
Re: Selection of Model by elevation??
« Reply #2 on: October 30, 2024, 03:27:32 PM »
Hello!

As a possible workaround I can suggest to adjust the bounding box so that it has its sides parallel to the XY plane, thus bottom side would define minimal altitude and top side - max desired altitude, after that you can duplicate the asset (be it mesh or point cloud) with Clip by Region option enabled.
Best regards,
Alexey Pasumansky,
Agisoft LLC

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15403
    • View Profile
Re: Selection of Model by elevation??
« Reply #3 on: October 30, 2024, 03:49:50 PM »
Below is the example of simple script that sets region parallel to XY plane and defines its top side to Max level and bottom - to Min level input by the user:
Code: [Select]
import Metashape

def cross(a, b):
"""
vector product of two vectors
"""
result = Metashape.Vector([a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y *b.x])
return result.normalized()

def get_min_max_region(chunk):

if not chunk.region:
return [None, None]

region = chunk.region
center = region.center
size = region.size
rotate = region.rot
T = chunk.transform.matrix
s = chunk.transform.scale
crs = chunk.crs

corners = [T.mulp(center + rotate * Metashape.Vector([size[0] * ((i & 1) - 0.5), 0.5 * size[1] * ((i & 2) - 1), 0.25 * size[2] * ((i & 4) - 2)])) for i in range(8)]

if chunk.crs:
corners = [chunk.crs.project(x) for x in list(corners)]

max_z = max([corner.z for corner in corners])
min_z = min([corner.z for corner in corners])

print("Estimating min&max Z values for region")
print(min_z, max_z)
return [min_z, max_z]

def set_region():

chunk = Metashape.app.document.chunk
z_min, z_max = get_min_max_region(chunk)

z_min = Metashape.app.getFloat("Specify MIN altitude value for region:", z_min)
z_max = Metashape.app.getFloat("Specify MAX altitude value for region:", z_max)

if z_min == z_max:
print("Z min = Z max, so no region correction applied")
return 0

if z_min > z_max:
z_min, z_max = z_max, z_min

region = chunk.region
center = region.center
size = region.size
rotate = region.rot
T = chunk.transform.matrix
s = chunk.transform.scale
crs = chunk.crs

corners = [T.mulp(center + rotate * Metashape.Vector([size[0] * ((i & 1) - 0.5), 0.5 * size[1] * ((i & 2) - 1), 0.25 * size[2] * ((i & 4) - 2)])) for i in range(8)]

if chunk.crs:
corners = [chunk.crs.project(x) for x in list(corners)]

for i in range(len(corners)):
corner = corners[i]
if i < 4:
corners[i] = Metashape.Vector([corner.x, corner.y, z_max])
else: #corner.z < z_min:
corners[i] = Metashape.Vector([corner.x, corner.y, z_min])

new_region = Metashape.Region()
if chunk.crs:
corners = [T.inv().mulp(crs.unproject(x)) for x in list(corners)]
else:
corners = [T.inv().mulp(x) for x in list(corners)]
new_center = (corners[0] + corners[-1]) / 2.
new_region.center = new_center

side1 = corners[0] - corners[2]
side2 = corners[0] - corners[1]
side1g = T.mulp(corners[0]) - T.mulp(corners[2])
side2g = T.mulp(corners[0]) - T.mulp(corners[1])
side3g = z_max - z_min
new_size = Metashape.Vector([side2g.norm()/s, side1g.norm()/s, side3g/s])
new_region.size = new_size

horizontal = side2
vertical = side1
normal = cross(vertical, horizontal)
horizontal = -cross(vertical, normal)
vertical = vertical.normalized()

R = Metashape.Matrix ([horizontal, vertical, -normal])
new_region.rot = R.t()
chunk.region = new_region
print("Region set to {:.3f} - {:.3f} Z range".format(z_min, z_max))

return 1

label = "Custom menu/Set min&&max Z for region"
Metashape.app.addMenuItem(label, set_region)
print("To execute this script press {}".format(label))
Best regards,
Alexey Pasumansky,
Agisoft LLC