ImprintEntity - утечка памяти (ObjectArx / C++) - Страница 2
| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > ImprintEntity - утечка памяти (ObjectArx / C++)

ImprintEntity - утечка памяти (ObjectArx / C++)

Ответ
Поиск в этой теме
Непрочитано 17.10.2014, 14:35
ImprintEntity - утечка памяти (ObjectArx / C++)
Glam Troll
 
прохраммист ObjectArx
 
Регистрация: 01.11.2010
Сообщений: 40

При интенсивном использовании (десятки тысяч вызовов подряд) метода AcDb3dSolid::imprintEntity обнаружил огромные утечки памяти. Причём, даже если тела не соприкасаются и в них не происходит никаких изменений. Например, если нарисовать 125 не контактирующих друг с другом кубиков и вызвать импринт для каждой пары из них, то занимаемая память увеличится более чем на 200 мегабайт, хотя абсолютно никакой полезной работы не совершилось. Вызовы acdbAcisDeleteModelerBulletins не только не помогают, но в ObjArx2015 этой функции вовсе нет. (разумеется, imprintEntity вызывается не просто так, а по очень веской причине и в рабочем документе содержится несколько тысяч тел, различным образом контактирующих друг с другом. В реальном документе утечки достигают 10-20 гигабайт и я страдаю).
Может кто-то сталкивался с такой проблемой и знает способы её решения?

P.S. В ADN уже вопрос написал, но мало ли когда они ответят, поэтому надежда на соо вообще и Александра Ривилиса в частности

Вот код примера, если хочется поэкспериментировать с косяком. Если делать imprintEntity не на оригинале, а на временном теле в памяти, то на размере утечек это никак не сказывается.
Код:
[Выделить все]
 
#include "StdAfx.h"
#include "resource.h"
#include <dbacis.h>
#include <vector>

#define OBJECT_ARX_VERSION 20

//-----------------------------------------------------------------------------
#define szRDS _RXST("TEST")

void ImprintAll();

//-----------------------------------------------------------------------------
//----- ObjectARX EntryPoint
class CMiniImpApp : public AcRxArxApp {

public:
	CMiniImpApp () : AcRxArxApp () {}

	virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
		// TODO: Load dependencies here

		// You *must* call On_kInitAppMsg here
		AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;

		// TODO: Add your initialization code here

		return (retCode) ;
	}

	virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
		// TODO: Add your code here

		// You *must* call On_kUnloadAppMsg here
		AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;

		// TODO: Unload dependencies here

		return (retCode) ;
	}

	virtual void RegisterServerComponents () {
	}


	static void CMiniImpApp_ImprintTest()
	{	ImprintAll();	}

} ;

//-----------------------------------------------------------------------------
IMPLEMENT_ARX_ENTRYPOINT(CMiniImpApp)

ACED_ARXCOMMAND_ENTRY_AUTO( CMiniImpApp, CMiniImpApp, _ImprintTest, ImprintTest, ACRX_CMD_NOINTERNALLOCK | ACRX_CMD_TRANSPARENT | ACRX_CMD_NOHISTORY, NULL );


void ImprintAll()
{
	ads_name ent0, ent1; 

	if( acdbEntNext(NULL, ent0) != RTNORM )
	{ 
		acdbFail(L"Drawing is empty\n"); 
		return; 
	}

	std::vector<AcDbObjectId> allSolids;

	Acad::ErrorStatus err( Acad::eOk );
	do
	{ 
		AcDbObjectId objId;
		err = acdbGetObjectId(objId, ent0);

		AcDbObjectPointer<AcDb3dSolid> object( objId, AcDb::kForRead, FALSE );
		if( object.openStatus() != Acad::eOk )
			continue;

	//	AcDb3dSolid * solid = new AcDb3dSolid;
	//	solid->copyFrom( object );

		allSolids.push_back( objId );

		ads_name_set(ent0, ent1);

	}
	while( acdbEntNext(ent1, ent0) == RTNORM ); 


	for( int i = 0; i < allSolids.size(); ++i )
	{
		AcDbObjectPointer<AcDb3dSolid> solid1( allSolids[i], AcDb::kForWrite, FALSE );

		for( int j = i; j < allSolids.size(); ++j )
		{
			if( i == j )
				continue;

			AcDbObjectPointer<AcDb3dSolid> solid2( allSolids[j], AcDb::kForWrite, FALSE );

			if( Acad::eOk == solid1->imprintEntity( solid2 ) )
			{
				solid2->imprintEntity( solid1 );
			}
		}
	}
}


Последний раз редактировалось Glam Troll, 17.10.2014 в 15:40. Причина: дополнил название темы
Просмотров: 7118
 
Непрочитано 26.10.2014, 15:16
#21
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Glam Troll Посмотреть сообщение
В реальной программе imprint делается только для тех тел, чьи габаритные контейнеры пересекаются (но это всё-равно тысячи вызовов).
Ну можно еще сократить количество вызовов imprintEntity если смотреть пересечение не габаритных контейнеров, а наличие взаимного пересечения AcBrFace пары тел.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 26.10.2014, 15:27
#22
Glam Troll

прохраммист ObjectArx
 
Регистрация: 01.11.2010
Сообщений: 40


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
пересечения AcBrFace пары тел.
Как я понимаю, придётся проверять пересечение каждой грани одного тела с каждой гранью второго. Утечку с импринтом я вычислил на чертеже из нескольких сотен деталей, по 2-3 тысячи граней в каждой. BREP там вообще страдает очень сильно, от таких моделей.

----- добавлено через ~2 мин. -----
Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Александр Ривилис
Offtop: Зарегистрировался на вашем сайте (по ссылке в подписи). Антибот у вас там впечатляющий... Нигде столь усиленной проверки не встречал.
Glam Troll вне форума  
 
Непрочитано 27.10.2014, 00:23
#23
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от Glam Troll Посмотреть сообщение
То при использовании BREP, контактирующие грани должны совпадать.
Важны детали - что есть - должны совпадать?? Найти грани которые точно равны, пересекаются, одна грань полностью лежит внутри другой, частично и пр. Нарисуйте пример и укажите что нужно - если конечно видите в этом смысл. По моей практике, в большинстве случаев, все подобные "геометрические" задачи имеют "резервы" к упрощению (к усложнению алгоритма - но росту производительности).
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 27.10.2014, 06:48
#24
Glam Troll

прохраммист ObjectArx
 
Регистрация: 01.11.2010
Сообщений: 40


Цитата:
Сообщение от Дима_ Посмотреть сообщение
что есть - должны совпадать?
После того, как грани триангулируются, они представляются не параметрически, а при помощи треугольников. И необходимо, чтобы контактирующие грани были одинаково триангулированы (хотя бы по периметру).
Вот на картинке два параллелепипедовых кубика размером 100*100*20. И у них есть контактирующая поверхность площадью 50*50. Без импринта каждый кубик триангулируется независимо и совместить точки на контактирующей поверхности будет невозможно. А, если делать импринт, то на обоих телах появятся новые грани, которые в точности друг с другом совпадают и BREP обеспечивает их совместную триангуляцию.

контактирующая поверхность
Нажмите на изображение для увеличения
Название: Clipboard Image.png
Просмотров: 19
Размер:	7.9 Кб
ID:	137552

Она же, но с сеткой. Специально сетка крупная, чтобы хоть что-то увидеть
Нажмите на изображение для увеличения
Название: Clipboard Image (1).png
Просмотров: 36
Размер:	32.7 Кб
ID:	137553

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

Я даже рассматривал возможность использовать внешний триангулятор (благо выгрузка в SAT присутствует), только вот от импринта всё-равно избавиться никак не получается. Если из моего опуса что-то стало понятно или появилась светлая мысль, то буду очень благодарен.

Ну и причина необходимости совпадения сеток - таково требование генератора КЭ сетки. Иначе тетраэдры не будут совпадать и генерация сетки падает.
Glam Troll вне форума  
 
Непрочитано 27.10.2014, 09:08
#25
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


коротко - т.к. с телефона, вариант оптимизации каждого к каждому - копию каждого тела немного отмасштабировать относительно центра, чтоб касающиесия тела начали пересекаться, а затем последовательно объединять их все в одно тело, анализируя объем до и после - если ‘прирост‘ оказался меньше объема тела, значит оно заползает на какое либо из уже добавленных - то есть с ними надо будет проверить импринт, если прибавка к объему = объему тела -то его можно не проверять.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 27.10.2014, 09:20
#26
Glam Troll

прохраммист ObjectArx
 
Регистрация: 01.11.2010
Сообщений: 40


Цитата:
Сообщение от Дима_ Посмотреть сообщение
копию каждого тела немного отмасштабировать относительно центра,
Вот это кстати неплохая идея. Только не объединять в одно тело, а найти объём на пересечении тел (выполняется мгновенно даже на сложных телах). Вычисление объёма слишком трудозатратная операция. На сложных телах (особенно построенных лофтингом по сплайнам) может занимать часы или вообще вешать Автокад.
В принципе идея понятна. Можно будет отфильтровать тела, чьи габаритные контейнеры пересекаются, но контакта тел нет. Только от утечки памяти на импринтах, которые всё же есть, это не избавит.(
Glam Troll вне форума  
 
Непрочитано 27.10.2014, 21:23
#27
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от Glam Troll Посмотреть сообщение
Вычисление объёма слишком трудозатратная операция. На сложных телах (особенно построенных лофтингом по сплайнам) может занимать часы или вообще вешать Автокад.
Я с таким моделями еще не сталкивался, но в общем верю. По моей практике анализ через однократное сложение тел идет быстрее чем сверка каждого к каждому.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 28.10.2014, 15:22
#28
Glam Troll

прохраммист ObjectArx
 
Регистрация: 01.11.2010
Сообщений: 40


Цитата:
Сообщение от Дима_ Посмотреть сообщение
однократное сложение тел
Только вот эта проверка лишь сообщит о факте контакта, а вот с каким из уже сбуленных тел этот контакт происходит - неизвестно. Т.е. опять придётся проверять каждый с каждым. Но, хотя бы, можно отсечь заведомо не контактирующие тела, у которых габаритные контейнеры пересекаются.
В ADN утечки признали вроде, может хоть в 2016 каде поправят и будет мне счастье.
Glam Troll вне форума  
 
Непрочитано 28.10.2014, 22:50
#29
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Не совсем каждый к каждому - проверять только те которые "просигнализировали", к тем, которые уже проверены до него. До кучи - если есть ограничения по возможным вариантам взаиморасположения (они как правило есть - надо только посмотреть внимательно), вполне возможно что достаточно будет проделать ту-же процедуру сложения тел, но в обратном порядке.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > ImprintEntity - утечка памяти (ObjectArx / C++)

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как бороться с ошибкой выделения памяти ratkill SCAD 14 07.09.2015 16:20
VBA: утечка памяти при вставке блоков Mikha Программирование 13 03.04.2009 09:18
При запуске Lisp идет утечка памяти Name LISP 6 24.07.2007 14:36
Утечка памяти mental Программирование 2 22.02.2007 07:40
Лира 9.2 + 1 Гб оперативной памяти nikе Лира / Лира-САПР 3 28.01.2006 19:02