#pragma hdrstop #include "DXFLoader.h" // DXFObjectÀÇ »ý¼ºÀÚ¿Í ¼Ò¸êÀÚ Á¤ÀÇ DXFObject::DXFObject() { _process = DXF_NULL; _dataText = NULL; _tokenText = new wslist(SEQUENCE); _unitBox = new wstree(REFERENCE); } DXFObject::~DXFObject() { if(_dataText) delete [] _dataText; _dataText = NULL; _tokenText->Destroy(); delete _tokenText; _unitBox->DestroyChild(); delete _unitBox; } // LoadDXFFile: ÆÄÀÏ À̸§À» ÀÎÀÚ·Î ¹Þ¾Æ µ¥ÀÌÅÍ ºÒ·¯¿À±â bool DXFObject::LoadDXFFile(const char* fileName) { // ÆÄÀÏ À̸§À» ÀÎÀÚ·Î ¹Þ¾Æ ¿­±â FILE* fp = NULL; fp = fopen(fileName, "r"); // ÆÄÀÏÀ» ¿­ ¼ö ¾ø´Â °æ¿ì ¿À·ù ó¸® if(fp == NULL) { this->_errorText = "DXF ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"; return false; } // ÆÄÀÏ »çÀÌÁî ¾ò±â fseek(fp, 0, SEEK_END); int filesize = ftell (fp); rewind (fp); // µ¥ÀÌÅÍ ¹öÆÛ ÃʱâÈ­ _dataText = new char[filesize + 1]; memset(_dataText, 0, filesize+1); _dataText[filesize] = EOF; // ÆÄÀÏ µ¥ÀÌÅ͸¦ ÀÐ¾î µ¥ÀÌÅÍ ÃßÃâ ÈÄ ÆÄÀÏ ´Ý±â fread(_dataText, sizeof(char), filesize, fp); fclose(fp); _process = DXF_LOAD; return true; } // ClearDXFFile: ÆÄÀÏ Á¤º¸¸¦ ÃʱâÈ­ void DXFObject::ClearDXFFile() { if(_dataText) delete [] _dataText; _dataText = NULL; // Token ¸®½ºÆ®¿¡ ÀÖ´Â ³»¿ëÀ» ¸ðµÎ »èÁ¦ _tokenText->Destroy(); // Unit ¸®½ºÆ®¿¡ ÀÖ´Â ³»¿ëÀ» ¸ðµÎ »èÁ¦ _unitBox->DestroyChild(); _process = DXF_NULL; } // AddNewToken: »õ·Î¿î ÅäÅ« ¹®ÀÚ¿­À» Ãß°¡ void DXFObject::AddNewToken(const char* text) { _tokenText->Insert((char*)text); } // SetCenter: Áß¾Ó ÁöÁ¡À» »õ·Î ¼³Á¤ void DXFObject::SetCenter(wstree* polyline, double centerX) { DXFVertex* current = 0; for(int i = polyline->Length()-1; i >= 0; i--) { current = (DXFVertex*)((*polyline)[i]->Get()); if(current->pointX <= centerX) { polyline->RemoveChild(current); polyline->CreateChildAt(0, current); } else return; } } // GetCurrentState: ÇöÀç ÁøÇà »óÅ °ªÀ» ¹Ýȯ DXFVALID DXFObject::GetCurrentState() { return _process; } // GetDataText: DXF ÆÄÀÏ ³»¿ëÀ» ¹Ýȯ char* DXFObject::GetDataText() { return _dataText; } // GetLastError: °¡Àå ÃÖ±ÙÀÇ Error¿¡ ´ëÇÑ ·Î±×¸¦ ¹Ýȯ char* DXFObject::GetLastError() { return _errorText; } // DXFObjectÀÇ »ý¼ºÀÚ¿Í ¼Ò¸êÀÚ Á¤ÀÇ DXFParser::DXFParser(DXFObject* object) { _object = object; _simplicity = -0.99; } DXFParser::~DXFParser() { if(_object) delete _object; _object = NULL; } // TrimText: ¾ÕµÚ °ø¹é ¹®ÀÚ¸¦ ¸ðµÎ Á¦°Å char* DXFParser::TrimText(const char* text) { int length = (int)strlen(text); int offset = 0; int limit = length; // ¾ÕÂÊ¿¡ ÀÖ´Â °ø¹é ¹®ÀÚ Á¦°ÅÇϵµ·Ï index ¼³Á¤ for(int i = 0; i < length; i++) { if(text[i] == ' ') offset++; else if(text[i] == '\t') offset++; else break; } // µÚÂÊ¿¡ ÀÖ´Â °ø¹é ¹®ÀÚ Á¦°ÅÇϵµ·Ï index ¼³Á¤ for(int i = length-1; i >= offset; i--) { if(text[i] == ' ') limit--; else if(text[i] == '\t') limit--; else break; } // »õ·Î¿î ¹®ÀÚ¿­À» »ý¼ºÇÏ¿© °ø¹é Á¦°ÅµÈ ¹®ÀÚ¿­ ´ëÀÔ char* trim = new char[limit-offset+1]; memset(trim, 0, (limit-offset+1)*sizeof(char)); for(int i = 0; i < limit-offset; i++) trim[i] = text[offset+i]; return trim; } // TrimVertex: ÀÏÁ¤ °¢µµ¸¦ ±âÁØÀ¸·Î vertex Á¤¸® void DXFParser::TrimVertex(wstree* polyline) { DXFVertex* prev = NULL; DXFVertex* now = NULL; DXFVertex* next = NULL; // 2Â÷¿ø vector ±¸Á¶Ã¼ Á¤ÀÇ struct Line { int x; int y; double length; }; Line u = { 0, 0, 0 }; Line v = { 0, 0, 0 }; // ¿¬¼ÓµÈ 3°³ÀÇ vertexÀÇ °¢µµ¿¡ µû¶ó Áß°£ vertex Á¦°Å for(int i = 0; i < polyline->CountChild(); i++) { // vertex°¡ ¾Æ´Ï¸é ¹«½Ã if(((DXFUnit*)(polyline->GetChild(i)->Get()))->unitType != DXFTYPE_VERTEX) continue; prev = now; now = next; next = (DXFVertex*)(polyline->GetChild(i)->Get()); // 3°³ÀÇ vertex °ªÀÌ ¸ðµÎ ÀÖ´Â °æ¿ì if(prev && now && next) { // 3°³ÀÇ vertex¸¦ µÎ °³ÀÇ 2Â÷¿ø vector·Î º¯È¯ u.x = prev->pointX - now->pointX; u.y = prev->pointY - now->pointY; v.x = next->pointX - now->pointX; v.y = next->pointY - now->pointY; u.length = sqrt(pow((double)u.x,2) + pow((double)u.y,2)); v.length = sqrt(pow((double)v.x,2) + pow((double)v.y,2)); // µÎ °³ÀÇ vector °¢µµ ºñ±³ ÈÄ ÇÊ¿äÇÑ °æ¿ì »èÁ¦ double cosine = ((u.x * v.x) + (u.y * v.y))/(u.length * v.length); if(cosine < _simplicity) { polyline->RemoveChild(polyline->GetChild(i-1)->Get()); i--; now = prev; prev = NULL; } } } } // SetBlockEnv: blockÀÇ À§Ä¡ Á¤º¸ ¹× Å©±â Á¤º¸ ÀúÀå void DXFParser::SetBlockEnv(wstree* block) { // ±âº»ÀûÀ¸·Î »ç¿ëÇÒ º¯¼öµé Á¤ÀÇ wstree* current = block; DXFVertex* vertex = 0; int minX = DXF_COORDINATE_MAX_X; int maxX = DXF_COORDINATE_MIN_X; int minY = DXF_COORDINATE_MAX_Y; int maxY = DXF_COORDINATE_MIN_Y; int bottomMinX = DXF_COORDINATE_MAX_Y; int bottomMaxX = DXF_COORDINATE_MIN_Y; // vertexµéÀ» µ¹¸ç X, Y¿¡ ´ëÇÑ ÃÖ´ë°ª°ú ÃÖ¼Ò°ª ã±â for(int i = 0; i < current->CountChild(); i++) { current = (*current)[i]; // vertex level loop for(int j = 0; j < current->CountChild(); j++) { current = (*current)[j]; vertex = (DXFVertex*)current->Get(); if(vertex->pointX > DXF_COORDINATE_MAX_X) vertex->pointX = DXF_COORDINATE_MAX_X; if(vertex->pointX < DXF_COORDINATE_MIN_X) vertex->pointX = DXF_COORDINATE_MIN_X; if(vertex->pointY > DXF_COORDINATE_MAX_Y) vertex->pointY = DXF_COORDINATE_MAX_Y; if(vertex->pointY < DXF_COORDINATE_MIN_Y) vertex->pointY = DXF_COORDINATE_MIN_Y; //¹Ø´ÜÀÇ left¿Í right ã±â if(vertex->pointY <= minY) { if(vertex->pointX < bottomMinX) bottomMinX = vertex->pointX; if(vertex->pointX > bottomMaxX) bottomMaxX = vertex->pointX; } if(vertex->pointX < minX) minX = vertex->pointX; if(vertex->pointX > maxX) maxX = vertex->pointX; if(vertex->pointY < minY) minY = vertex->pointY; if(vertex->pointY > maxY) maxY = vertex->pointY; current = current->GetParent(); } current = current->GetParent(); } // blockÀÇ À§Ä¡ ¹× Å©±â Á¤º¸ ÀúÀå DXFBlock* blockData = (DXFBlock*)current->Get(); blockData->blockX = minX; blockData->blockY = minY; blockData->width = maxX - minX; blockData->height = maxY - minY; blockData->bottomLeft = bottomMinX; blockData->bottomRight = bottomMaxX; blockData->centerX = (bottomMinX + bottomMaxX) / 2; } // SetSimplicity: DXF ÆÄÀÏÀÇ ´Ü¼øÈ­ µî±Þ ÁöÁ¤ void DXFParser::SetSimplicity(double value) { _simplicity = value; } // ParseDXFText: DXF ÆÄÀÏ ³»¿ëÀ» ÆÄ½Ì void DXFParser::ParseDXFText() { // ¿øº» µ¥ÀÌÅÍ¿¡ ´ëÇÑ Á¤º¸¸¦ °¡Á®¿È char* data = _object->GetDataText(); int length = (int)strlen(_object->GetDataText()); // parsing °á°ú token¿¡ ´ëÇÑ º¯¼ö int offset = 0; int count = 0; // parsing °úÁ¤À» ÅëÇØ data tokenize for(int i = 0; i < length; i++) { // tokenizeÇÒ ¹®ÀÚ°¡ µîÀåÇϸé Áö±Ý±îÁö ³»¿ëÀ» ÃßÃâ if(data[i] == DXF_PARSER_LINE_SPLITTER) { char* token = new char[count+1]; token[count] = 0; for(int j = offset; j < offset+count; j++) token[j-offset] = data[j]; _object->AddNewToken(TrimText(token)); delete [] token; // token Á¤º¸ ÃʱâÈ­ offset = i+1; count = 0; } else count++; } } // AnalyzeDXFText: DXF ÆÄÀÏ parsing °á°ú¸¦ ºÐ¼®ÇÏ¿© unitBox¿¡ ÀúÀå bool DXFParser::AnalyzeDXFText() { // DXF Unit °´Ã¼¸¦ ´ã´Â º¯¼ö ¼±¾ð DXFUnit* unit = NULL; // ÇöÀç 󸮵ǰí ÀÖ´Â group code Á¤º¸ int group = DXF_GROUP_S_NONE; // ÇöÀç 󸮵ǰí ÀÖ´Â ³»¿ëÀÌ commentÀÎÁö¿¡ ´ëÇÑ Á¤º¸ bool comment = false; // µ¥ÀÌÅ͸¦ Çü½Ä¿¡ µû¶ó ºÐ·ùÇÏ¿© DXF Unit ¸ñ·Ï¿¡ Ãß°¡ wstree* current = _object->GetUnits(); wstree* child = NULL; int polyLineID = 0; // blockÀÌ layer¿¡ Ãß°¡µÇ¾ú´ÂÁö ¿©ºÎ bool blockEnv = false; // Àӽà ·¹À̾î Ãß°¡ unit = new DXFLayer(); ((DXFLayer*)unit)->layerName = "0"; (*current) << unit; unit = NULL; for(int i = 0; i < _object->LengthToken(); i++) { char* token = _object->GetToken(i); // ÁÖ¼®ÀÎ °æ¿ì ¹«½ÃÇϵµ·Ï ó¸® //if((strlen(token) > 0) && (token[0] == '#')) continue; if(comment == true) { comment = false; continue; } else if(strcmp(token, "999") == 0) { comment = true; continue; } // group code ÀÎ½Ä Ã³¸® if(group == DXF_GROUP_S_NONE) group = strtol(token, 0, 10); // group value ÀÎ½Ä Ã³¸® else { if(strcmp(token, "TABLE") == 0) { unit = NULL; } else if(strcmp(token,"ENDTAB") == 0){ unit = NULL; } // »õ·Î¿î layer¿¡ ´ëÇÑ Ã³¸® else if(strcmp(token, "LAYER") == 0) { // ºÎ¸ð Æ®¸®°¡ 0ÀÌ ¾Æ´Ï¸é (ÇöÀç Æ®¸®°¡ root°¡ ¾Æ´Ï¸é) ¿À·ù if(current->GetParent() != 0) return false; // »õ·Î¿î layer¸¦ »ý¼ºÇÏ¿© unit box¿¡ Ãß°¡ unit = new DXFLayer(); (*current) << unit; polyLineID = 0; } // »õ·Î¿î block¿¡ ´ëÇÑ Ã³¸® else if(strcmp(token, "BLOCK") == 0) { unit = new DXFBlock(); blockEnv = true; } else if(strcmp(token, "ENDBLK") == 0) { // À̰÷¿¡¼­ blockÀÇ À§Ä¡ ¹× Å©±â Á¤º¸ ÀúÀå SetBlockEnv(current); // ±âÁ¸ Á¤º¸ ÃʱâÈ­ ¹× root·Î µ¹¾Æ°¨ if(blockEnv) current = current->GetParent()->GetParent(); else delete unit; unit = NULL; polyLineID = 0; } // »õ·Î¿î polyline¿¡ ´ëÇÑ Ã³¸® else if(strcmp(token, "POLYLINE") == 0) { // ºÎ¸ðÀÇ °ªÀÌ ¾øÀ¸¸é POLYLINE ¾øÀ½ if(current->Get() == NULL) continue; // ºÎ¸ð Æ®¸®°¡ blockÀÌ ¾Æ´Ï¸é ¿À·ù if(((DXFUnit*)(current->Get()))->unitType != DXFTYPE_BLOCK) return false; unit = new DXFPolyline(); ((DXFPolyline*)unit)->polylineID = polyLineID++; (*current) << unit; current = current->GetChild(current->CountChild() - 1); } else if(strcmp(token, "SEQEND") == 0 || strcmp(token, "ENDSEQ") == 0) { unit = NULL; // ÇÊ¿ä¾ø´Â vertexµéÀ» ¼±º°Çؼ­ Á¦°Å TrimVertex(current); current = current->GetParent(); } // »õ·Î¿î vertex¿¡ ´ëÇÑ Ã³¸® else if(strcmp(token, "VERTEX") == 0) { // ºÎ¸ðÀÇ °ªÀÌ ¾øÀ¸¸é VERTEX ¾øÀ½ if(current->Get() == NULL) continue; // ºÎ¸ð Æ®¸®°¡ polylineÀÌ ¾Æ´Ï¸é ¿À·ù if(((DXFUnit*)(current->Get()))->unitType != DXFTYPE_POLYLINE) return false; // »õ·Î¿î vertex¸¦ »ý¼ºÇÏ¿© unit box¿¡ Ãß°¡ unit = new DXFVertex(); (*current) << unit; } // value¿¡ ´ëÇÑ µ¥ÀÌÅÍ ÀԷ ó¸® else if(unit) { switch(unit->unitType) { // layer µ¥ÀÌÅÍ °ª °»½Å case DXFTYPE_LAYER: // layer À̸§ if(group == DXF_GROUP_S_NAME) ((DXFLayer*)unit)->layerName = token; break; // block µ¥ÀÌÅÍ °ª °»½Å case DXFTYPE_BLOCK: // layer À̸§ if(group == DXF_GROUP_S_LAYER_NAME) { for(int i = 0; i < current->CountChild(); i++) { child = current->GetChild(i); DXFLayer* layer = (DXFLayer*)child->Get(); // LAYER À̸§ÀÌ ¾øÀ¸¸é ¹«½Ã if(layer->layerName == 0) continue; // ÇöÀç child°¡ layerÀÎ °æ¿ì ÇØ´ç layer¿¡ blockÀ» Ãß°¡ if((layer->unitType == DXFTYPE_LAYER) && (strcmp(layer->layerName, token) == 0)) { // ºÎ¸ðÀÇ °ªÀÌ ¾øÀ¸¸é BLOCK ¾øÀ½ if(child->Get() == NULL) break; current = child; // ºÎ¸ð Æ®¸®°¡ layer°¡ ¾Æ´Ï¸é ¿À·ù if(((DXFUnit*)(current->Get()))->unitType != DXFTYPE_LAYER) return false; (*current) << unit; current = current->GetChild(current->CountChild() - 1); blockEnv = true; break; } } } // block À̸§ if(group == DXF_GROUP_S_NAME) ((DXFBlock*)unit)->blockName = token; break; // polyline µ¥ÀÌÅÍ °ª °»½Å case DXFTYPE_POLYLINE: if(group == DXF_GROUP_S_LAYER_NAME) ((DXFPolyline*)unit)->layerName = token; // vertex µ¥ÀÌÅÍ °ª °»½Å case DXFTYPE_VERTEX: // vertexÀÇ x ÁÂÇ¥ if(group == DXF_GROUP_F_PRIMARY_X) ((DXFVertex*)unit)->pointX = (int)strtol(token,0,10); // vertexÀÇ y ÁÂÇ¥ if(group == DXF_GROUP_F_PRIMARY_Y) ((DXFVertex*)unit)->pointY = (int)strtol(token,0,10); // vertexÀÇ z ÁÂÇ¥ if(group == DXF_GROUP_F_PRIMARY_Z) ((DXFVertex*)unit)->pointZ = (int)strtol(token,0,10); break; } } // group code¸¦ ´Ù½Ã Àеµ·Ï ó¸® group = DXF_GROUP_S_NONE; } } // blockÀÌ ¾øÀ¸¸é ¿À·ù current = _object->GetUnits(); int blockCount = 0; for(int i = 0; i < current->Length(); i++) { current = current->GetChild(i); // child°¡ blockÀÎÁö °Ë»ç /* for(int j = 0; j < current->Length(); j++) { current = current->GetChild(j); if(((DXFUnit*)current->Get())->unitType == DXFTYPE_BLOCK) blockCount++; current = current->GetParent(); } */ blockCount += current->Length(); current = current->GetParent(); } if(blockCount == 0) return false; return true; } #pragma package(smart_init)