Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
beer
Зарегистрирован: 01.02.2006 Сообщения: 215 Откуда: Москва
|
Добавлено: Пн Июл 02, 2012 3:33 pm Заголовок сообщения: Создание 3d элементов в 2d режиме |
|
|
Суть проблемы вот в чем. Если ACTIVEMODEL - двумерная то все функции по созданию элементов обрубают Z координату передаваемого массива точек в качестве исходных данных. А очень хочется в памяти создать трехмерную линию (работать просто с массивом точек не предлагать - не подойдет)
Ну я нашел только один вариант - надо либо найти в файле 3D модель (или создать) и переключиться на нее (активировать), сделать свое грязное дело, а потом прыгнуть обратно. Но это плохо тем что при таком переключении мигает экран и сбрасываются настройки видовых окон и почему-то прекращается работа текущего инструмента (короче грустно как-то).
Ну а второй вариант. Ту же 3d модель отобразить в каком-нибудь не используемом видовом окне и сделать текущим это видовое окно, опять же сделать свое грязное дело и закрыть его. Тут мерцаний поменьше да и побыстрее все, но по-моему как-то не аккуратненько.
Есть еще идеи как создать в памяти 3D элемент если активная модель двумерная? |
|
Вернуться к началу |
|
|
Leonid давно здесь сидим
Зарегистрирован: 28.01.2006 Сообщения: 598 Откуда: С.-Петербург
|
Добавлено: Вт Июл 03, 2012 2:32 pm Заголовок сообщения: |
|
|
Енту функцию не пробовал?
Код: | StatusInt mdlWorkDgn_openFile
(
DgnModelRefP* pModelRef ,
int* pFormat ,
BoolInt* pThreeD ,
char const* pName ,
MSWChar* pModelName ,
BoolInt readOnly
);
|
|
|
Вернуться к началу |
|
|
beer
Зарегистрирован: 01.02.2006 Сообщения: 215 Откуда: Москва
|
Добавлено: Чт Июл 05, 2012 7:50 am Заголовок сообщения: |
|
|
Так она же вроде не меняет ACTIVEMODEL
У меня ситуация такая. Основная модель у меня двумерная, к ней подключена трехмерная модель в которой находится Mesh. Я беру LineString из основной модели, из него строю новую сетку перпендикулярную плоскости XY а потом нахожу пересечение двух сеток с помощью mdlPop_elementDescrFromElementDescrIntersectionEdges
Ну так вот если ACTIVEMODEL (MASTERFILE что суть одно и тоже) двумерная то он мне и возвращает двумерную линию, где Z координаты у вершин равны нулю. А мне то как раз они и нужны (я так продольный профиль по трассе трою )
В MDL я нашел только одну функцию которая меняет ACTIVEMODEL - mdlModelRef_activateAndDisplay но она устраивает целое светопреставление в видовых окнах. А хочется сделать это втихую что бы было не заметно (имитация работы в фоне) |
|
Вернуться к началу |
|
|
Leonid давно здесь сидим
Зарегистрирован: 28.01.2006 Сообщения: 598 Откуда: С.-Петербург
|
Добавлено: Чт Июл 05, 2012 3:10 pm Заголовок сообщения: |
|
|
А зачем менять активную модель?
Насколько я понял, нужно тихо открыть какой-нибудь трехмерный файл (или модель) и делать там свои дела.
Так вот эта функция и открывает файл так что никто этого не заметит.
И с полученным пойнтером на модель трехмерного файла (DgnModelRefP* pModelRef) уже можно извращаться с трехмерными объектами сколько душе угодно
Главное не забыть его закрыть |
|
Вернуться к началу |
|
|
Leonid давно здесь сидим
Зарегистрирован: 28.01.2006 Сообщения: 598 Откуда: С.-Петербург
|
Добавлено: Чт Июл 05, 2012 5:17 pm Заголовок сообщения: |
|
|
Размести код вкратце, может больше ясности будет... |
|
Вернуться к началу |
|
|
beer
Зарегистрирован: 01.02.2006 Сообщения: 215 Откуда: Москва
|
Добавлено: Пт Июл 06, 2012 9:24 am Заголовок сообщения: |
|
|
Уф.... Много наверное получится. Хотя у меня наверное много не оптимально может хоть подскажете как оптимизировать
Код: |
// Mesh1 и Mesh2 - указатели на дескрипторы двух сеток
// MDL.Null = IntPtr.Zero - мне просто так захотелось
// destModel - модель основного файла хотя можно любую главное что бы рабочие единицы были те
internal static IntPtr GetInterSectionsFromMeshes(IntPtr Mesh1, IntPtr Mesh2, IntPtr destModel)
{
int ppResultDescr;
if (MDL.mdlPop_elementDescrFromElementDescrIntersectionEdges(out ppResultDescr, Mesh1, Mesh2, MDL.NULL, 1) != MDL.SUCCESS) return MDL.NULL;
double scaleFactor;
MDL.mdlCnv_UORToMaster(out scaleFactor, 1, destModel);
dgn.Transform3d tr;
MDL.mdlTMatrix_getIdentity(out tr);
MDL.mdlTMatrix_scale(out tr, ref tr, scaleFactor, scaleFactor, scaleFactor);
MDL.mdlElmdscr_transform(ppResultDescr.ToIntPtr(), ref tr);
return ppResultDescr.ToIntPtr();
}
|
И вся загвоздка происходит при вызове mdlPop_elementDescrFromElementDescrIntersectionEdges
Если ACTIVEMODEL - двумерная то и цепочка линий которую он возвращает тоже будет двумерная!!! В функцию не передается ни модель, ни файл. Вообще никак управлять фактически нельзя.
Я начитался уже на форуме бентли про такие фокусы стейшена. Как я понял что там писали то при создании элементов имеет значение т.н. контекст в котором находится стейшен и им управляет как раз текущая модель. Кстати можешь просто проверить на простой функции mdlLine_create в одном случае создается line_2d а в другом line_3d. Я наивно полагал что указание шаблона элемента поможет, ан нет он только настройки символики из него берет |
|
Вернуться к началу |
|
|
Leonid давно здесь сидим
Зарегистрирован: 28.01.2006 Сообщения: 598 Откуда: С.-Петербург
|
Добавлено: Пт Июл 06, 2012 1:32 pm Заголовок сообщения: |
|
|
beer писал(а): | Я беру LineString из основной модели... |
А конвертнуть его в трехмерный элемент не пробовал?
Код: | mdlElmdscr_convertTo3D(...) |
|
|
Вернуться к началу |
|
|
beer
Зарегистрирован: 01.02.2006 Сообщения: 215 Откуда: Москва
|
Добавлено: Пн Июл 09, 2012 10:25 am Заголовок сообщения: |
|
|
Эх... ведь знал что код надо полностью приводить. Сам LineString на прямую никуда не передается. Я из него Mesh строю вот таким образом:
Код: |
internal static IntPtr CreateProjectingMesh(dgn.LineElement sourseLine, dgn.Element sourseMesh)
{
if (!((sourseLine.Type == Bentley.Interop.MicroStationDGN.MsdElementType.Line ||
sourseLine.Type == Bentley.Interop.MicroStationDGN.MsdElementType.LineString)
&& sourseMesh.Type == Bentley.Interop.MicroStationDGN.MsdElementType.MeshHeader)) return IntPtr.Zero;
dgn.Range3d meshRange = sourseMesh.Range;
dgn.Point3d[] projectMeshPnts = new dgn.Point3d[sourseLine.VerticesCount * 2];
int[] projectMeshFaces = new int[(sourseLine.VerticesCount - 1) * 4];
for (int i = 0; i < sourseLine.VerticesCount; i++)
{
projectMeshPnts[i * 2] = sourseLine.get_Vertex(i + 1);
projectMeshPnts[i * 2 + 1] = projectMeshPnts[i * 2];
projectMeshPnts[i * 2].Z = meshRange.Low.Z;
projectMeshPnts[i * 2 + 1].Z = meshRange.High.Z;
if (i < sourseLine.VerticesCount - 1)
{
projectMeshFaces[i * 4] = i * 2 + 1;
projectMeshFaces[i * 4 + 1] = i * 2 + 2;
projectMeshFaces[i * 4 + 2] = i * 2 + 4;
projectMeshFaces[i * 4 + 3] = i * 2 + 3;
}
}
IntPtr ppMeshEl;
if (MDL.mdlMesh_newPolyface(out ppMeshEl, MDL.NULL, ref projectMeshFaces[0], 4, (sourseLine.VerticesCount - 1), ref projectMeshPnts[0], sourseLine.VerticesCount * 2) != MDL.SUCCESS) return MDL.NULL;
return ppMeshEl;
}
|
так что переведу его в 3D или нет разницы никакой |
|
Вернуться к началу |
|
|
Leonid давно здесь сидим
Зарегистрирован: 28.01.2006 Сообщения: 598 Откуда: С.-Петербург
|
Добавлено: Сб Июл 14, 2012 10:45 pm Заголовок сообщения: |
|
|
beer писал(а): |
Я начитался уже на форуме бентли про такие фокусы стейшена. Как я понял что там писали то при создании элементов имеет значение т.н. контекст |
ДА уж, тоже почитал... Но в свое работе пока сталкивался только с переходом из 3D в 2D, а не наоборот... проблем не было
Ну что ж... бубен - это наше всё |
|
Вернуться к началу |
|
|
beer
Зарегистрирован: 01.02.2006 Сообщения: 215 Откуда: Москва
|
Добавлено: Пн Июл 16, 2012 10:13 am Заголовок сообщения: |
|
|
Ну как бы надежда на изменения есть. Я все никак не могу найти ветку на форуме Бентли где это все активно обсуждалось. Но я помню что кто-то из Бентли сказал что у них типа есть планах сделать возможность самому задавать в каком контексте будет создаваться элемент, но когда это будет реализовано не спрашивайте.
Так что ждем-с |
|
Вернуться к началу |
|
|
|