Forum

Author Topic: Идея, как обойти ограничение ram  (Read 10955 times)

Leonid

  • Newbie
  • *
  • Posts: 3
    • View Profile
Идея, как обойти ограничение ram
« on: August 19, 2014, 07:35:15 PM »
У меня есть идея, как обойти ограничение памяти, при создании mesh,
так, у меня около 120 фото, при самом лучшем качестве создается 120млн частиц, считается это около 8 часов, ок, при создании же mesh всей моей памяти(32gb) не хватает даже на 1/10 сцены, и после 6 часов обработки таймер уходит в 60 часов
При этом если ограничить box просчета при создании mesh, чтобы памяти хватало, все считается очень даже неплохо
Так вот, идея такова, почему бы при создании mesh не сделать такую функцию просчета, при которой задается основной box модели, а потом этот box делится на некоторое количество частей(в зависимости от количества оперативной памяти)и каждый участок считается отдельно, при этом нет никакого ограничения на количество памяти, в конце же все куски mesh объединяются в один, при этом все считается из одного облака и не происходит никаких косяков, по моему очень удобно
все это можно сделать и ручками, экспортируя части в zbrush и объединить их там, но почему бы не сделать это в программе автоматически, при этом не нужно ждать создание частей, а можно просто пойти спать, как вам такая идея?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 10294
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #1 on: August 19, 2014, 08:24:28 PM »
Здравствуйте, Леонид,

Автоматизировать подобное разделение рабочей области и экспорт результата можно с помощью Python скриптов.
Проблемой могут стать области стыков, т.к. при подобном подходе допустимы тончайшие разрывы.

Однако, если Вам интересно, могу выслать пример подобного скрипта.
Best regards,
Alexey Pasumansky,
AgiSoft LLC

Leonid

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #2 on: August 19, 2014, 08:36:16 PM »
да, я тоже подумал насчет стыков, поэтому делаю легкий оверлап, возможно это будет полезной встроенной функцией для многих, да, если можно вышлите пример

Leonid

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #3 on: August 19, 2014, 08:44:47 PM »
ps ведь можно сделать тоже самое и для создания облака(с некоторой доработкой в области стыков), а эти две функции(создание облака и создание mesh) потребляют больше всего памяти, и это дает возможность считать большие проекты на машинах с небольшим количеством памяти без потери производительности

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 10294
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #4 on: August 25, 2014, 04:04:01 PM »
Добрый день, Леонид,

Вот пример скрипта, который разбивает исходную рабочую область на сетку N на M (задаётся в виде аргументов в соответствующей строке диалогового окна запуска скрипта). В принципе, такой подход можно расширить и на трёхмерный случай.

Обратите внимание, что исходный блок для данного скрипта должен содержать плотное облако.

Code: [Select]
## Splits active chunk into user defined grid of sub-chunks (images are kept but bounding box is split)
## after chunk being split, for every smaller chunk mesh is generated based on the dense cloud, then dense cloud is removed from smaller chunks

#arguments - X and Y grid sizes

#compatibility PhotoScan Professional 1.0.4

import PhotoScan
import sys

doc = PhotoScan.app.document
chunk = doc.activeChunk

def dist(v0, v1):
"""
Calculate distance between two points defined as vectors
"""
distance = (v1 - v0)
return distance.norm() #**2

partsX = 3   #parts of the model, 3 by default
partsY = 3
if len(sys.argv) == 2:   
parts = int(sys.argv[1])
partsX = partsY = parts
elif len(sys.argv) == 3:
partsX = int(sys.argv[1])
partsY = int(sys.argv[2])
print("Script started...")

region = chunk.region
r_center = region.center
r_rotate = region.rot
r_size = region.size

x_scale = r_size.x / partsX   
y_scale = r_size.y / partsY   
z_scale = r_size.z 

offset = r_center - r_rotate * r_size /2.

for j in range(1, partsY + 1):  #creating new chunks and adjusting bounding box
for i in range(1, partsX + 1):
new_chunk = chunk.copy()
new_chunk.label = "Chunk "+ str(i)+ "\\" + str(j)
new_chunk.model = None
doc.chunks.add(new_chunk)

new_region = PhotoScan.Region()
new_rot = r_rotate
new_center = PhotoScan.Vector([(i - 0.5) * x_scale, (j - 0.5) * y_scale, 0.5 * z_scale])
new_center = offset + new_rot * new_center
new_size = PhotoScan.Vector([x_scale, y_scale, z_scale])
new_region.size = new_size
new_region.center = new_center
new_region.rot = new_rot

new_chunk.region = new_region

PhotoScan.app.update()
if new_chunk.dense_cloud:
new_chunk.buildModel("height field", "dense", interpolation = "enabled", faces = "high")
new_chunk.resetDepth()
new_chunk.dense_cloud = None #removing dense cloud

print("Script finished...")
PhotoScan.app.update()
Best regards,
Alexey Pasumansky,
AgiSoft LLC

umvas

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #5 on: November 24, 2014, 04:53:20 PM »
Добрый день, Леонид,

Вот пример скрипта, который разбивает исходную рабочую область на сетку N на M (задаётся в виде аргументов в соответствующей строке диалогового окна запуска скрипта). В принципе, такой подход можно расширить и на трёхмерный случай.

Обратите внимание, что исходный блок для данного скрипта должен содержать плотное облако.

Code: [Select]
## Splits active chunk into user defined grid of sub-chunks (images are kept but bounding box is split)
## after chunk being split, for every smaller chunk mesh is generated based on the dense cloud, then dense cloud is removed from smaller chunks

#arguments - X and Y grid sizes

#compatibility PhotoScan Professional 1.0.4

import PhotoScan
import sys

doc = PhotoScan.app.document
chunk = doc.activeChunk

def dist(v0, v1):
"""
Calculate distance between two points defined as vectors
"""
distance = (v1 - v0)
return distance.norm() #**2

partsX = 3   #parts of the model, 3 by default
partsY = 3
if len(sys.argv) == 2:   
parts = int(sys.argv[1])
partsX = partsY = parts
elif len(sys.argv) == 3:
partsX = int(sys.argv[1])
partsY = int(sys.argv[2])
print("Script started...")

region = chunk.region
r_center = region.center
r_rotate = region.rot
r_size = region.size

x_scale = r_size.x / partsX   
y_scale = r_size.y / partsY   
z_scale = r_size.z 

offset = r_center - r_rotate * r_size /2.

for j in range(1, partsY + 1):  #creating new chunks and adjusting bounding box
for i in range(1, partsX + 1):
new_chunk = chunk.copy()
new_chunk.label = "Chunk "+ str(i)+ "\\" + str(j)
new_chunk.model = None
doc.chunks.add(new_chunk)

new_region = PhotoScan.Region()
new_rot = r_rotate
new_center = PhotoScan.Vector([(i - 0.5) * x_scale, (j - 0.5) * y_scale, 0.5 * z_scale])
new_center = offset + new_rot * new_center
new_size = PhotoScan.Vector([x_scale, y_scale, z_scale])
new_region.size = new_size
new_region.center = new_center
new_region.rot = new_rot

new_chunk.region = new_region

PhotoScan.app.update()
if new_chunk.dense_cloud:
new_chunk.buildModel("height field", "dense", interpolation = "enabled", faces = "high")
new_chunk.resetDepth()
new_chunk.dense_cloud = None #removing dense cloud

print("Script finished...")
PhotoScan.app.update()


Очень полезный скрипт, но что дописать в скрипте, чтобы было небольшое перекрытие блоков а не разрывы на стыках?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 10294
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #6 on: November 24, 2014, 06:24:20 PM »
Добрый день,

Вы можете домножить new_size на какой-нибудь коэффициент, например:
Code: [Select]
new_region.size = new_size * 1.01
Best regards,
Alexey Pasumansky,
AgiSoft LLC

abnoksius

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #7 on: December 01, 2014, 04:10:47 PM »
Добрый день!
Спасибо за скрипт, очень пригодился, однако возникла проблема.
В версии 1.1.0 скрипт перестал срабатывать, выдает сообщение AttributeError: 'PhotoScan.Document' object has no attribute 'activeChunk'
Видимо что то поменялось в API?
« Last Edit: December 01, 2014, 04:23:32 PM by abnoksius »

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 10294
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #8 on: December 01, 2014, 07:32:27 PM »
Здравствуйте,

Да, были некоторые изменения в API. Постараюсь завтра выложить скрипт для версии 1.1.0.
Best regards,
Alexey Pasumansky,
AgiSoft LLC

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 10294
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #9 on: December 03, 2014, 01:22:20 PM »
Новая версия скрипта для PhotoScan Pro 1.1.0:

Code: [Select]
## Splits active chunk into user defined grid of sub-chunks (images are kept but bounding box is split)
## after chunk being split, for every smaller chunk mesh is generated based on the dense cloud, then dense cloud is removed from smaller chunks

#arguments - X and Y grid sizes

#compatibility PhotoScan Professional 1.1.0

import PhotoScan
import sys

doc = PhotoScan.app.document
chunk = doc.chunk

def dist(v0, v1):
"""
Calculate distance between two points defined as vectors
"""
distance = (v1 - v0)
return distance.norm() #**2

partsX = 3   #parts of the model, 3 by default
partsY = 3
if len(sys.argv) == 2:   
parts = int(sys.argv[1])
partsX = partsY = parts
elif len(sys.argv) == 3:
partsX = int(sys.argv[1])
partsY = int(sys.argv[2])
print("Script started...")

region = chunk.region
r_center = region.center
r_rotate = region.rot
r_size = region.size

x_scale = r_size.x / partsX   
y_scale = r_size.y / partsY   
z_scale = r_size.z 

offset = r_center - r_rotate * r_size /2.

for j in range(1, partsY + 1):  #creating new chunks and adjusting bounding box
for i in range(1, partsX + 1):
new_chunk = chunk.copy()
new_chunk.label = "Chunk "+ str(i)+ "\\" + str(j)
new_chunk.model = None
doc.addChunk(new_chunk)

new_region = PhotoScan.Region()
new_rot = r_rotate
new_center = PhotoScan.Vector([(i - 0.5) * x_scale, (j - 0.5) * y_scale, 0.5 * z_scale])
new_center = offset + new_rot * new_center
new_size = PhotoScan.Vector([x_scale, y_scale, z_scale])
new_region.size = new_size
new_region.center = new_center
new_region.rot = new_rot

new_chunk.region = new_region

PhotoScan.app.update()
if new_chunk.dense_cloud:
new_chunk.buildModel(surface = PhotoScan.SurfaceType.HeightField, source = PhotoScan.PointsSource.DensePoints, interpolation = PhotoScan.Interpolation.EnabledInterpolation, face_count = PhotoScan.FaceCount.HighFaceCount)
#new_chunk.resetDepth()
new_chunk.dense_cloud = None #removing dense cloud

print("Script finished...")
PhotoScan.app.update()
Best regards,
Alexey Pasumansky,
AgiSoft LLC

abnoksius

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #10 on: December 03, 2014, 03:35:52 PM »
Выдает ошибку, "D:/chunk_divide.py", line 47, in <module>
    doc.addChunk(new_chunk)
TypeError: addChunk() takes no arguments (1 given)
>>>

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 10294
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #11 on: December 03, 2014, 03:43:41 PM »
Проверьте, пожалуйста, что у Вас установлен последний билд версии 1.1.0 - 1995.
Best regards,
Alexey Pasumansky,
AgiSoft LLC

abnoksius

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #12 on: December 03, 2014, 04:23:38 PM »
На билде 1995 все работает, спасибо большое!

umvas

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #13 on: May 19, 2015, 11:51:30 AM »
При разбивке на блоки, каждый из них при построении облака точек наращивает место в RAM. Логично было бы добавить в скрипте "Split in chunks.py" галочку "удалять облако точек"  после построения модели в блоке. Как удалить облако точек с помощью Python?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 10294
    • View Profile
Re: Идея, как обойти ограничение ram
« Reply #14 on: May 19, 2015, 11:57:54 AM »
Чтобы удалить облако точек через Python нужно присвоить ему значение None:

Code: [Select]
chunk.dense_cloud = None
Best regards,
Alexey Pasumansky,
AgiSoft LLC