DWG -> Трёхмерная таблица - Страница 3
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > DWG -> Трёхмерная таблица

DWG -> Трёхмерная таблица

Ответ
Поиск в этой теме
Непрочитано 11.07.2010, 00:19
DWG -> Трёхмерная таблица
Lazerus
 
Регистрация: 11.07.2010
Сообщений: 24

Добрый вечер!

Ситуация следующая:

Необходимо привести DWG файл к трёхмерной таблице цветов, чтобы была возможность проходя по осям X, Y и Z считать цвет трёхмерной точки и, следовательно, понимать, что данная точка заполнена чем либо.

Скачал ARX для AutoCAD 2011, но разобраться так и не смог.
Пытался оттолкнуться от типа AcDbDatabase, но без результатно.
Просмотров: 13406
 
Непрочитано 19.07.2010, 18:21
#41
Александр Ривилис

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


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Думаю, что этот код должен выполняться, но выдаёт ошибку:
Не должен. Кто память под pEnt выделять будет?
Должно быть как минимум:
Код:
[Выделить все]
AcBrEntity *pEnt = new AcBrep();
Цитата:
Сообщение от Lazerus Посмотреть сообщение
Класс тёмного объекта AcDbSubDMesh, он был солидом, но я сгладил его. Если пытаюсь вбить его в pBrEnt возникает ошибка.
Ну это и понятно, т.к. я уже несколько раз писал, что только AcDb3dSolid, AcDbRegion и AcDbBody можно "подсовывать" BREP.
С AcDbSubDMesh я не работал, но заметил что у него есть метод AcDbSubDMesh::convertToSolid. Так что получи сначала AcDb3dSolid, а потом уже натравливай на него BREP.

Последний раз редактировалось Александр Ривилис, 19.07.2010 в 18:30.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 12:23
#42
Lazerus


 
Регистрация: 11.07.2010
Сообщений: 24


Вот, что я сделал вчера:
Код:
[Выделить все]
        AcBr::ErrorStatus err;
        AcGe::PointContainment ppp;
        AcGePoint3d pt3;
        int countIN  = 0;
        int countOUT = 0;
        int countON  = 0;
        int countERR = 0;
        for (int x = 0; x <= 0; x++)
            for (int y = 0; y <= 0; y++)
                for (int z = 0; z <= 0; z++)
                {
                    pt3.x = x;
                    pt3.y = y;
                    pt3.z = z;
                    err = ((AcBrBrep*)pBrEnt)->getPointContainment(pt3,ppp,pBrEnt);
                    switch(ppp)
                    {
                        case AcGe::kOutside   : countOUT++; break;
                        case AcGe::kInside    : countIN++ ; break;
                        case AcGe::kOnBoundary: countON++ ; break;
                        default: countERR++;
                    }
 
                }
 
        acutPrintf(_T("CountIN  = %d\n"),countIN );
        acutPrintf(_T("CountON  = %d\n"),countON );
        acutPrintf(_T("CountOUT = %d\n"),countOUT);
        acutPrintf(_T("CountERR = %d\n"),countERR);
Проблема вот в чём. При задании областей x, y, z вылетает ошибка. Насколько я нопимаю, функция getPointContainment влияет на объект через указатель pBrEnt. Что нужно сделать?
Lazerus вне форума  
 
Непрочитано 20.07.2010, 12:35
#43
Александр Ривилис

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


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Что нужно сделать?
Для начала изучить C++. Что это такое?
Код:
[Выделить все]
for (int x = 0; x <= 0; x++)
            for (int y = 0; y <= 0; y++)
                for (int z = 0; z <= 0; z++)
Когда пишешь, что возникает ошибка, будь добр ее приводить полностью.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 12:52
#44
Lazerus


 
Регистрация: 11.07.2010
Сообщений: 24


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Для начала изучить C++. Что это такое?
Код:
[Выделить все]
for (int x = 0; x <= 0; x++)
            for (int y = 0; y <= 0; y++)
                for (int z = 0; z <= 0; z++)
Когда пишешь, что возникает ошибка, будь добр ее приводить полностью.
Если я задам область, скажем, x от 0 до чего-либо, возникает ошибка:
Lazerus вне форума  
 
Непрочитано 20.07.2010, 12:54
#45
Александр Ривилис

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


Приведи код полностью. И вставь чертеж (dwg-файл), на котором ставишь эксперименты.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 13:07
#46
Lazerus


 
Регистрация: 11.07.2010
Сообщений: 24


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Приведи код полностью. И вставь чертеж (dwg-файл), на котором ставишь эксперименты.
В файле brsample.cpp
Код:
[Выделить все]
#include"brsample_pch.h"//precompiled header
#ifdefined(_DEBUG) && !defined(AC_FULL_DEBUG)
#error _DEBUG should not be defined except in internal Adesk debug builds
#endif
#include"rxregsvc.h"
#include"aced.h"
#include"dbsymtb.h"
#include"adslib.h"
#include"dbents.h"
#include"tchar.h"
#include<axlock.h>
#include<dbobjptr.h>
#include<dbSubD.h>
 
 
void
readDwg()
{
    AcDbDatabase* pDatabase=new AcDbDatabase(false,false);
    AcAxDocLock docLock(pDatabase);
    if ( Acad::eOk != pDatabase->readDwgFile(_T("c:\\Drawing1.dwg") ) )
        return;
    Acad::ErrorStatus es;
 
    AcDbEntity *entObj; 
    AcDbBlockTable *pBlockTbl;
    AcDbBlockTableRecord *pBlockTableRecord;
    AcDbBlockTableRecordIterator *pBlockIterator;
    pDatabase->getBlockTable(pBlockTbl, AcDb::kForRead);
    pBlockTbl->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForRead);
    pBlockTbl->close();
    pBlockTableRecord->newIterator(pBlockIterator);
    AcGeIntArray osnapModes,geomIds;
    AcGePoint3dArray gripPoints; // your 3d points will be here
 
    for (; !pBlockIterator->done(); pBlockIterator->step())
    {
        es = pBlockIterator->getEntity(entObj,AcDb::kForRead);
        geomIds.removeAll();
        osnapModes.removeAll();
        gripPoints.removeAll();
        entObj->getGripPoints(gripPoints,osnapModes,geomIds);
 
        AcBrEntity* pBrEnt = new AcBrBrep();
        AcDbObjectIdArray objIdList;
        AcDb::SubentType subType = AcDb::kNullSubentType;
        AcDbFullSubentPath subPath;
        AcDb3dSolid  *pSolid = NULL;
        AcDbSubDMesh *sSolid = NULL;
        AcBr::ErrorStatus returnValue = AcBr::eOk;
        objIdList.append(entObj->objectId());
        if ((pSolid = AcDb3dSolid::cast(entObj)) != NULL) 
        {
            subPath = kNullSubent;
            subPath.objectIds() = objIdList;
        }
        else
            if ((sSolid = AcDbSubDMesh::cast(entObj)) != NULL) 
            {
                subPath = kNullSubent;
                subPath.objectIds() = objIdList;
                sSolid->convertToSolid(false,false,pSolid);
            }
        returnValue = ((AcBrBrep*)pBrEnt)->set((const AcDbEntity&)*pSolid);
        if (returnValue != AcBr::eOk) 
        {
            acutPrintf(ACRX_T("\n Error in AcBrEntity::set:"));
            acutPrintf(ACRX_T(" AutoCAD Error Code: %d\n"), returnValue);
            delete pBrEnt;
            //return false;
        }
 
        AcBr::ErrorStatus err;
        AcGe::PointContainment ppp;
        AcGePoint3d pt3;
        int countIN  = 0;
        int countOUT = 0;
        int countON  = 0;
        int countERR = 0;
        for (int x = 0; x <= 0; x++)
            for (int y = 0; y <= 0; y++)
                for (int z = 0; z <= 1; z++)
                {
                    pt3.x = x;
                    pt3.y = y;
                    pt3.z = z;
                    err = ((AcBrBrep*)pBrEnt)->getPointContainment(pt3,ppp,pBrEnt);
                    switch(ppp)
                    {
                        case AcGe::kOutside   : countOUT++; break;
                        case AcGe::kInside    : countIN++ ; break;
                        case AcGe::kOnBoundary: countON++ ; break;
                        default: countERR++;
                    }
 
                }
 
        acutPrintf(_T("CountIN  = %d\n"),countIN );
        acutPrintf(_T("CountON  = %d\n"),countON );
        acutPrintf(_T("CountOUT = %d\n"),countOUT);
        acutPrintf(_T("CountERR = %d\n"),countERR);
 
        acutPrintf(_T("classname: %s\n"),
            (entObj->isA())->name());
        acutPrintf(_T("END\n"));
        entObj->close();
    }
    pBlockTableRecord->close();
    delete pBlockIterator;
    delete pDatabase;
}
Вложения
Тип файла: dwg
DWG 2010
Drawing1.dwg (413.7 Кб, 864 просмотров)

Последний раз редактировалось Lazerus, 20.07.2010 в 13:19.
Lazerus вне форума  
 
Непрочитано 20.07.2010, 14:19
#47
Александр Ривилис

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


Замени
Код:
[Выделить все]
err = ((AcBrBrep*)pBrEnt)->getPointContainment(pt3,ppp,pBrEnt);
на
Код:
[Выделить все]
AcBrEntity* container = NULL;
err = ((AcBrBrep*)pBrEnt)->getPointContainment(pt3,ppp,container);
И попробуй это:
Код:
[Выделить все]
  static void TestBrepTESTBREP(void)
  {
    ads_name en; ads_point p;
    if (acedEntSel(L"\nВыберите 3DSOLID: ", en, p) != RTNORM) return;
    AcDbObjectId eId; acdbGetObjectId(eId,en);
    AcDbObjectPointer<AcDb3dSolid> p3dsolid(eId,AcDb::kForRead);
    if (p3dsolid.openStatus() == Acad::eNotThatKindOfClass) {
      acutPrintf(L"\nВыбран не 3DSOLID!!!"); return;
    } else if (p3dsolid.openStatus() != Acad::eOk) {
      acutPrintf(L"\nОшибка AcDbObjectPointer<AcDb3dSolid> p3dsolid(eId,AcDb::kForRead)"); return;
    }
    AcBr::ErrorStatus ebs;
    AcBrBrep* pBrEnt = new AcBrBrep();
    ebs = pBrEnt->set(*(p3dsolid.object()));
    if (ebs != AcBr::eOk) {
      acutPrintf(L"\nОшибка pBrEnt->set(p3dsolid.object()) = %d",ebs);
      delete pBrEnt;
      return;
    }
    AcBrEntity* container = NULL;
    int countIN  = 0, countOUT = 0, countON  = 0, countERR = 0;
    AcGeBoundBlock3d bb; 
    // Получаем габаритный параллелепипед
    ebs = pBrEnt->getBoundBlock(bb); 
    if (ebs != AcBr::eOk) {
      acutPrintf(L"\nОшибка pBrEnt->getBoundBlock(bb) = %d",ebs);
      delete pBrEnt;
      return;
    }
    for (int x = 0; x <= 100; ++x) {
       for (int y = 0; y <= 100; ++y) {     
          for (int z = 0; z <= 100; ++z) {     
            AcGe::PointContainment pc;
            AcGePoint3d p(x,y,z);
            if (bb.contains(p)) {
              ebs = pBrEnt->getPointContainment(p,pc,container);
              if (ebs != AcBr::eOk) {
                ++countERR;
              } else {
                countIN  += (pc == AcGe::kInside);
                countOUT += (pc == AcGe::kOutside);
                countON  += (pc == AcGe::kOnBoundary);
              }
            } else {
              ++countOUT;
            }
          }
       }
    }
    acutPrintf(L"\nCountIN  = %d",countIN );
    acutPrintf(L"\nCountON  = %d",countON );
    acutPrintf(L"\nCountOUT = %d",countOUT);
    acutPrintf(L"\nCountERR = %d",countERR);
    delete pBrEnt;
  }

Последний раз редактировалось Александр Ривилис, 20.07.2010 в 14:56.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 15:14
#48
Lazerus


 
Регистрация: 11.07.2010
Сообщений: 24


Огромное спасибо! Сейчас тестирую что получается при замене строки на Ваши две.

Чуть позже посмотрю, что делает предложенный Вами код.
Lazerus вне форума  
 
Непрочитано 20.07.2010, 15:30
#49
Александр Ривилис

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


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Чуть позже посмотрю, что делает предложенный Вами код.
Главная мысль моего кода - это предварительное получение габаритного параллелепипеда, и проверка в цикле точки на попадание в него. Если точка вне параллелепипеда, то нет смысла проверять getPointContainment, так как точка точно снаружи твердого тела. Операция по проверке находится ли точка внутри габаритного параллелепипеда на несколько порядков быстрее, чем getPointContainment.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 16:33
#50
Lazerus


 
Регистрация: 11.07.2010
Сообщений: 24


А если фигура является конусом или имеет другую форму?
Lazerus вне форума  
 
Непрочитано 20.07.2010, 16:40
#51
Александр Ривилис

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


Цитата:
Сообщение от Lazerus Посмотреть сообщение
А если фигура является конусом или имеет другую форму?
Это совершенно неважно. Самое главное, что BoundingBox всегда охватывает объект целиком и поэтому если точка не попадает в BoundingBox, то она гарантировано не попадает в объект. Обратное утверждение неверно.
Александр Ривилис вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > DWG -> Трёхмерная таблица



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
формат Corel'a -> dxf или dwg. Как? the_sun Прочее. Программное обеспечение 15 07.02.2013 15:10
Сконвертируйте пожалуйста CDW (версию не знаю) -> DWG 2006 vama Прочее. Программное обеспечение 1 22.10.2009 12:50
Пакетный перегон dxf -> dwg возможно ли ? bdfy AutoCAD 4 15.11.2006 21:41
Хороший конвертер DWG -> JPG solegs AutoCAD 15 09.12.2004 18:24
dwg 2005 -> dwg 2002. нужна программа Torero AutoCAD 5 22.09.2004 14:20