Forum

Author Topic: place markers in corners of bounding box  (Read 4842 times)

stephan

  • Full Member
  • ***
  • Posts: 129
    • View Profile
place markers in corners of bounding box
« on: October 22, 2021, 08:10:40 PM »
Hey there,

I'm trying to do something that should be simple, but I'm messing up and I can't figure out where...

The objective is this: to automatically place a marker in the corners of the bounding box, in order to export the GPS coordinates of the 8 corners.


My basic idea is this code below:

Code: [Select]
chunk = Metashape.app.document.chunk
center = chunk.region.center

size = chunk.region.size

corner0 = [chunk.region.center[0]-(0.5*chunk.region.size[0]),chunk.region.center[1]-(0.5*chunk.region.size[1]),chunk.region.center[2]-(0.5*chunk.region.size[2])]

chunk.addMarker(corner0)


I get the region size & center, then find a corner by removing half the size on each axis from the center... but this fails and places markers somewhere outside of my map. I have a feeling I'm doing something stupid here but I can't figure this out!

Any help would be much appreciated!

Cheers,
Stephan

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15168
    • View Profile
Re: place markers in corners of bounding box
« Reply #1 on: October 22, 2021, 09:19:46 PM »
Hello Stephan,

If the project is georeferenced you can use the following code to calculate the coordinates of the bounding box corners and place markers there:
Code: [Select]
chunk = Metashape.app.document.chunk
region = chunk.region
for i in range(8):   #finding bounding box corners
pos = Metashape.Vector([region.size.x * ((i & 1) - 0.5), 0.5 * region.size.y * ((i & 2) - 1), 0.25 * region.size.z * ((i & 4) - 2)])
pos = region.center + region.rot * pos  #coordinates in the internal coordinates
corner = chunk.addMarker()
corner.label = "corner " + str(i+1)
corner.reference.location = chunk.crs.project(chunk.transform.matrix.mulp(pos)) #coordinates in geographic/projected coordinates according to chunk.crs
corner.reference.enabled = True
« Last Edit: October 22, 2021, 09:29:30 PM by Alexey Pasumansky »
Best regards,
Alexey Pasumansky,
Agisoft LLC

stephan

  • Full Member
  • ***
  • Posts: 129
    • View Profile
Re: place markers in corners of bounding box
« Reply #2 on: October 22, 2021, 11:16:43 PM »
Awesome, thanks Alexey!

stephan

  • Full Member
  • ***
  • Posts: 129
    • View Profile
Re: place markers in corners of bounding box
« Reply #3 on: October 23, 2021, 11:31:41 AM »
Quick follow-up question: I'm trying to use these corner positions to import some geometry... is there a quick and easy way to import, for example, a cube.obj model that I have so that it is directly centered with it's 0,0,0 in the position of corner1 for example? Or do I need to create a whole new chunk with new coordinates?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15168
    • View Profile
Re: place markers in corners of bounding box
« Reply #4 on: October 23, 2021, 02:35:25 PM »
Hello Stephan,

You can import a cube of any size and then modify the coordinates of its vertices, so that every vertex has an offset from the desired marker of half cube's side in each direction. But you should recalculate the coordinates from geographic to internal chunk's system in order to calculate mesh vertex coordinates properly.
Best regards,
Alexey Pasumansky,
Agisoft LLC

stephan

  • Full Member
  • ***
  • Posts: 129
    • View Profile
Re: place markers in corners of bounding box
« Reply #5 on: October 23, 2021, 08:30:31 PM »
Hi Alexey,

This is exactly what I am trying to do, indeed! And that's where I'm getting stuck:I don't understand how to switch the coordinate system before importing an object and then set it back... I've been over all the API documentation and I think I just don't understand that bit  ;D

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15168
    • View Profile
Re: place markers in corners of bounding box
« Reply #6 on: October 26, 2021, 08:21:13 PM »
Hello Stephan,

I have updated the script, so that it creates now a cube mesh around each corner of the bounding box (size of the cube is currently defined in the script body in meters). The cubes are parallel to the bounding box sides.
Separate mesh models are created for each corner and in the end the merged mesh is created.

Code: [Select]
import Metashape, tempfile

def fake_obj(s):
output ="v {:.5f} -{:.5f} -{:.5f}\nv {:.5f} -{:.5f} {:.5f}\nv {:.5f} {:.5f} -{:.5f}\nv {:.5f} {:.5f} {:.5f}\nv -{:.5f} -{:.5f} -{:.5f}\nv -{:.5f} -{:.5f} {:.5f}\nv -{:.5f} {:.5f} -{:.5f}\nv -{:.5f} {:.5f} {:.5f}\nf 2 6 5\nf 7 8 4\nf 3 4 2\nf 4 8 6\nf 6 8 7\nf 1 5 7\nf 1 2 5\nf 3 7 4\nf 1 3 2\nf 2 4 6\nf 5 6 7\nf 3 1 7\n".format(s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)
return output

def create_cube(chunk, center, side):
s = side / chunk.transform.scale
temp_obj = tempfile.NamedTemporaryFile(delete=False)
output = fake_obj(s)
temp_obj.write(output.encode("utf-8"))
temp_obj.close()
if chunk.model:
chunk.model = None
chunk.importModel(path = temp_obj.name, format = Metashape.ModelFormatOBJ, crs = Metashape.CoordinateSystem('LOCAL_CS["Local Coordinates (m)",LOCAL_DATUM["Local Datum",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]'))
for i in range(8):
vertex = chunk.model.vertices[i]
vertex.coord = chunk.region.rot * Metashape.Vector([s * ((i & 1) - 0.5), 0.5 * s * ((i & 2) - 1), 0.25 * s * ((i & 4) - 2)])  + center
return 1

chunk = Metashape.app.document.chunk
region = chunk.region
SIDE = 10 #meters in georeferenced coordinate system
models = []

for i in range(8):   #finding bounding box corners
pos = Metashape.Vector([region.size.x * ((i & 1) - 0.5), 0.5 * region.size.y * ((i & 2) - 1), 0.25 * region.size.z * ((i & 4) - 2)])
pos = region.center + region.rot * pos  #coordinates in the internal coordinates
corner = chunk.addMarker()
corner.label = "corner " + str(i+1)
corner.reference.location = chunk.crs.project(chunk.transform.matrix.mulp(pos)) #coordinates in geographic/projected coordinates according to chunk.crs
corner.reference.enabled = True
create_cube(chunk, pos, SIDE)
chunk.model.label = corner.label
models.append(chunk.model)
chunk.model = None
task = Metashape.Tasks.MergeAssets()
task.source_data = Metashape.ModelData
task.assets = models
task.apply(chunk)
chunk.model.label = "Merged cubes"
print("Script finished")
« Last Edit: October 26, 2021, 08:23:04 PM by Alexey Pasumansky »
Best regards,
Alexey Pasumansky,
Agisoft LLC

stephan

  • Full Member
  • ***
  • Posts: 129
    • View Profile
Re: place markers in corners of bounding box
« Reply #7 on: January 20, 2022, 01:53:20 PM »
Hello Stephan,

I have updated the script, so that it creates now a cube mesh around each corner of the bounding box (size of the cube is currently defined in the script body in meters). The cubes are parallel to the bounding box sides.
Separate mesh models are created for each corner and in the end the merged mesh is created.

Code: [Select]
import Metashape, tempfile

def fake_obj(s):
output ="v {:.5f} -{:.5f} -{:.5f}\nv {:.5f} -{:.5f} {:.5f}\nv {:.5f} {:.5f} -{:.5f}\nv {:.5f} {:.5f} {:.5f}\nv -{:.5f} -{:.5f} -{:.5f}\nv -{:.5f} -{:.5f} {:.5f}\nv -{:.5f} {:.5f} -{:.5f}\nv -{:.5f} {:.5f} {:.5f}\nf 2 6 5\nf 7 8 4\nf 3 4 2\nf 4 8 6\nf 6 8 7\nf 1 5 7\nf 1 2 5\nf 3 7 4\nf 1 3 2\nf 2 4 6\nf 5 6 7\nf 3 1 7\n".format(s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)
return output

def create_cube(chunk, center, side):
s = side / chunk.transform.scale
temp_obj = tempfile.NamedTemporaryFile(delete=False)
output = fake_obj(s)
temp_obj.write(output.encode("utf-8"))
temp_obj.close()
if chunk.model:
chunk.model = None
chunk.importModel(path = temp_obj.name, format = Metashape.ModelFormatOBJ, crs = Metashape.CoordinateSystem('LOCAL_CS["Local Coordinates (m)",LOCAL_DATUM["Local Datum",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]'))
for i in range(8):
vertex = chunk.model.vertices[i]
vertex.coord = chunk.region.rot * Metashape.Vector([s * ((i & 1) - 0.5), 0.5 * s * ((i & 2) - 1), 0.25 * s * ((i & 4) - 2)])  + center
return 1

chunk = Metashape.app.document.chunk
region = chunk.region
SIDE = 10 #meters in georeferenced coordinate system
models = []

for i in range(8):   #finding bounding box corners
pos = Metashape.Vector([region.size.x * ((i & 1) - 0.5), 0.5 * region.size.y * ((i & 2) - 1), 0.25 * region.size.z * ((i & 4) - 2)])
pos = region.center + region.rot * pos  #coordinates in the internal coordinates
corner = chunk.addMarker()
corner.label = "corner " + str(i+1)
corner.reference.location = chunk.crs.project(chunk.transform.matrix.mulp(pos)) #coordinates in geographic/projected coordinates according to chunk.crs
corner.reference.enabled = True
create_cube(chunk, pos, SIDE)
chunk.model.label = corner.label
models.append(chunk.model)
chunk.model = None
task = Metashape.Tasks.MergeAssets()
task.source_data = Metashape.ModelData
task.assets = models
task.apply(chunk)
chunk.model.label = "Merged cubes"
print("Script finished")

This is awesome, thanks Alexey I had missed this reply!