BOOL __stdcall ImportDXFFile(const TCHAR* lpszFileName, Painter* painter, Layers* layers, Blocks* blocks) { layers->clearLayers(); blocks->clear(); Draw_Dxf* creationClass = CreateDraw_Dxf(painter,layers,blocks); DL_Dxf* dxf = CreateDL_Dxf(); #ifdef UNICODE char str[MAX_PATH]; WideCharToMultiByte(CP_ACP,0,(TCHAR*)lpszFileName,-1,str,MAX_PATH,NULL,NULL); std::string strFileName(str); #else std::string strFileName(lpszFileName); #endif if (!dxf->in(strFileName.c_str(), creationClass)) { // if file open failed DestroyDL_Dxf(dxf); DestroyDraw_Dxf(creationClass); return false; } blocks->regen(); layers->regen(); DestroyDL_Dxf(dxf); DestroyDraw_Dxf(creationClass); return true; }
TEST_F(TestDrawing, TestFromParsedDrawing) { ParseDXF parser; DL_Dxf dxf; dxf.in("test_shape.dxf", &parser); Drawing const& drawing(parser.GetDrawing()); drawing.Print(std::cout); std::cout << std::endl; double yCenter = (2.51892L-0.518918L)/2+0.518918L; double xCenter = (3.35231L-1.35231L)/2+1.35231L; std::list<double> collissions; Line line1(xCenter, 0, xCenter, 10); drawing.GetCollissions(line1, collissions); collissions.sort(); ASSERT_EQ(2u, collissions.size()); pt center = drawing.GetCenter(); EXPECT_TRUE(center.y<=(yCenter+0.001)) << "Expected=" << yCenter << " Actual =" << center.y; EXPECT_TRUE(center.y>=(yCenter-0.001)) << "Expected=" << yCenter << " Actual =" << center.y; EXPECT_TRUE(center.x<=(xCenter+0.001)) << "Expected=" << xCenter << " Actual =" << center.x; EXPECT_TRUE(center.x>=(xCenter-0.001)) << "Expected=" << xCenter << " Actual =" << center.x; }
void InputFormatDXF::readFeaturesInto(OutputFormat * outputHandler) { // Pull in actual data now... this->output = outputHandler; DL_Dxf * getData = new DL_Dxf(); if (!getData->in(this->filename, this)) { fprintf(stderr, "Could not retrieve data from input file.\n"); delete getData; exit(1); } // Clean up any hanging polylines: this->finishPendingPolyline(); if (this->filename) { delete this->filename; this->filename = NULL; } if (this->insertionReceiver) { delete this->insertionReceiver; this->insertionReceiver = NULL; } // Don't delete output format - caller can do that this->output = NULL; delete getData; }
void input(std::string filename) { DL_Dxf dxf; if (!dxf.in(filename, this)) { std::cerr << "Unable to open input file '" << filename << "'\n"; exit(1); } }
void testWriting() { DL_Dxf* dxf = new DL_Dxf(); DL_Codes::version exportVersion = DL_Codes::AC1015; DL_WriterA* dw = dxf->out("myfile.dxf", exportVersion); if (dw==NULL) { printf("Cannot open file 'myfile.dxf' \ for writing."); // abort function e.g. with return }
void testReading(char* file) { // Load DXF file into memory: std::cout << "Reading file " << file << "...\n"; Test_CreationClass* creationClass = new Test_CreationClass(); DL_Dxf* dxf = new DL_Dxf(); if (!dxf->in(file, creationClass)) { // if file open failed std::cerr << file << " could not be opened.\n"; return; } delete dxf; delete creationClass; }
DXFReader::DXFReader(tModel *m, QString fileName) : model(m) { DL_Dxf dxf; activeElement = NULL; subLayer = NULL; if (!dxf.in(fileName.toStdString(), this)) { // std::cerr << "drawing.dxf could not be opened.\n"; } }
InputFormatDXF::InputFormatDXF(const char * inputFilename) { // Get the insertions / blocks - so that we know what offsets to use as we encounter these blocks: DL_Dxf * fetchInsertions = new DL_Dxf(); this->insertionReceiver = new GetInsertions(); if (!fetchInsertions->in(inputFilename, this->insertionReceiver)) { fprintf(stderr, "Could not retrieve insertion blocks from input file.\n"); delete fetchInsertions; exit(1); } delete fetchInsertions; fetchInsertions = NULL; this->filename = new char[strlen(inputFilename)]; strcpy(this->filename, inputFilename); this->currentBlockX = 0; this->currentBlockY = 0; }
dxfbezier2linesClass::dxfbezier2linesClass(string file_name, int st, double textLengte) { n=0; res = 50000; text_lengte = textLengte; //strcpy(file,file_name); aantal_punten = st; char *cstr = new char[file_name.length() + 1]; strcpy(cstr, file_name .c_str()); DL_Dxf* dxf = new DL_Dxf(); if (!dxf->in(cstr, this)) // if file open failed { std::cerr << file_name << " could not be opened.\n"; exit(1); } delete dxf; calcLine(); Scale(); // char* file="twee.dxf" }
/* * @brief Main function for DXFLib test program. * * @param argc Number of delimited items on command line, * including program name. * @param argv Pointer to array of command line items * * @retval 0 if missing input file argument or * file couldn't be opened * @retval 1 if file opened */ int main(int argc, char** argv) { // Check given arguments: if (argc<2) { usage(); return 0; } //DL_Dxf::test(); // Load DXF file into memory: std::cout << "Reading file " << argv[1] << "...\n"; Test_CreationClass creationClass; DL_Dxf dxf; if (!dxf.in(argv[1], &creationClass)) { // if file open failed std::cerr << argv[1] << " could not be opened.\n"; return 0; } return 1; // file could be opened }
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct_) { #ifdef _TEST_CODE CDxfParserEx* creationClass = new CDxfParserEx(); DL_Dxf* dxf = new DL_Dxf(); if (!dxf->in("C:\\1.dxf", creationClass)) { return 0; } #endif if (CFrameWnd::OnCreate(lpCreateStruct_) == -1) return -1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("未能创建工具栏\n"); return -1; // 未能创建 } if (!m_wndEditToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_LEFT | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndEditToolBar.LoadToolBar(IDR_EDIT)) { TRACE0("未能创建工具栏\n"); return -1; // 未能创建 } if (!CreateComboBox(ID_COMBOBOX)) { TRACE0("Failed to create combo box\n"); return -1; } if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("未能创建状态栏\n"); return -1; // 未能创建 } // TODO: Delete these three lines if you don't want the toolbar to // be dockable // m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); // EnableDocking(CBRS_ALIGN_ANY); // DockControlBar(&m_wndToolBar); //////////////////////////////////////////// if( !m_wndCoolBar.Create(_T("控制栏"),this, CSize( 250, 400 ), TRUE, 123 ) ) { TRACE0("Failed to create mybar\n"); return -1; } //设置样式 m_wndCoolBar.SetBarStyle( m_wndCoolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC ); //设置停靠 m_wndCoolBar.EnableDocking( CBRS_ALIGN_ANY ); EnableDocking(CBRS_ALIGN_ANY); DockControlBar( &m_wndCoolBar, AFX_IDW_DOCKBAR_RIGHT);///停靠 ////// m_wndTabCtrl.Create( TCS_DOWN | WS_CHILD | WS_VISIBLE, CRect( 0, 0, 200, 200), &m_wndCoolBar, 125); //生成TOC对话框,并加入m_wndTabCtrl中 if( m_formDlg.Create( IDD_FORMVIEW, &m_wndTabCtrl ) ) m_wndTabCtrl.AddPage( &m_formDlg ,_T("控制")); m_formDlg.ShowWindow( SW_SHOW ); m_wndTabCtrl.UpdateWindow(); //////////////////////////////////////////// if( !m_wndBotmCoolBar.Create(_T("CNC控制栏"),this, CSize( 250, 165 ), TRUE, 123 ) ) { TRACE0("Failed to create mybar\n"); return -1; } //设置样式 m_wndBotmCoolBar.SetBarStyle( m_wndBotmCoolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC ); //设置停靠 m_wndBotmCoolBar.EnableDocking( CBRS_ALIGN_ANY ); EnableDocking(CBRS_ALIGN_ANY); DockControlBar( &m_wndBotmCoolBar, AFX_IDW_DOCKBAR_BOTTOM);///停靠 ////// m_tabCtrlBottom.Create( TCS_UP | WS_CHILD | WS_VISIBLE, CRect( 0, 0, 200, 200), &m_wndBotmCoolBar, 125); //生成TOC对话框,并加入m_wndTabCtrl中 if( m_dialogCCD.Create( IDD_FORMVIEW_CCD, &m_tabCtrlBottom ) ) { m_tabCtrlBottom.AddPage(&m_dialogCCD ,_T("CCD")); } m_dialogCCD.ShowWindow( SW_SHOW ); /*if(m_dialogCameraConfig.Create(IDD_CAMERA_CONFIG, &m_tabCtrlBottom)) m_tabCtrlBottom.AddPage( &m_dialogCameraConfig ,_T("相机参数配置")); if(m_dialogImageConfig.Create(IDD_IMAGE_CONFIG, &m_tabCtrlBottom)) m_tabCtrlBottom.AddPage( &m_dialogImageConfig ,_T("图像参数配置")); if(m_dialogMotionConfig.Create(IDD_MOTION_CONFIG, &m_tabCtrlBottom)) m_tabCtrlBottom.AddPage( &m_dialogMotionConfig ,_T("运动参数配置")); m_dialogMotionConfig,ShowWindow(SW_SHOW); m_dialogImageConfig.ShowWindow(SW_SHOW); m_dialogCameraConfig.ShowWindow( SW_SHOW );*/ m_wndTabCtrl.UpdateWindow(); // TODO: 如果不需要工具栏可停靠,则删除这三行 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); m_wndEditToolBar.EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndEditToolBar); #ifdef _MAKELANG OnViewLanguage(IDM_View_Default); #else // 列出语言文件 if (CLanguage::List(GetSubMenu(GetSubMenu(this->GetMenu()->m_hMenu, 2), 3)) != IDM_View_Default) { CLanguage::TranslateMenu(this->GetMenu()->m_hMenu, MAKEINTRESOURCE(IDR_MAINFRAME)); } #endif //初始化运动控制卡 InitMCard(); RegistMsgWnd(m_hWnd); //SetTimer(100,300,NULL); return 0; }
//--------------------------------------------------------- bool CDXF_Import::On_Execute(void) { CSG_String fName = Parameters("FILE")->asString(); Parameters("TABLES")->asTableList() ->Del_Items(); Parameters("SHAPES")->asShapesList()->Del_Items(); m_Filter = Parameters("FILTER") ->asInt(); m_dArc = Parameters("DCIRCLE") ->asDouble() * M_DEG_TO_RAD; //----------------------------------------------------- if( SG_File_Exists(fName) ) { m_pLayers = SG_Create_Table(); m_pLayers ->Set_Name(CSG_String::Format(SG_T("%s [%s]"), SG_File_Get_Name(fName, false).c_str(), _TL("Layers"))); m_pLayers ->Add_Field("LAYER" , SG_DATATYPE_String); m_pLayers ->Add_Field("FLAGS" , SG_DATATYPE_Int); m_pBlocks = SG_Create_Table(); m_pBlocks ->Set_Name(CSG_String::Format(SG_T("%s [%s]"), SG_File_Get_Name(fName, false).c_str(), _TL("Blocks"))); m_pBlocks ->Add_Field("BLOCK" , SG_DATATYPE_String); m_pBlocks ->Add_Field("FLAGS" , SG_DATATYPE_Int); m_pBlocks ->Add_Field("X" , SG_DATATYPE_Double); m_pBlocks ->Add_Field("Y" , SG_DATATYPE_Double); m_pBlocks ->Add_Field("Z" , SG_DATATYPE_Double); m_pPoints = SG_Create_Shapes(SHAPE_TYPE_Point , CSG_String::Format(SG_T("%s [%s]"), SG_File_Get_Name(fName, false).c_str(), _TL("Points"))); m_pPoints ->Add_Field("LAYER" , SG_DATATYPE_String); m_pPoints ->Add_Field("Z" , SG_DATATYPE_Double); m_pLines = SG_Create_Shapes(SHAPE_TYPE_Line , CSG_String::Format(SG_T("%s [%s]"), SG_File_Get_Name(fName, false).c_str(), _TL("Lines"))); m_pLines ->Add_Field("LAYER" , SG_DATATYPE_String); m_pLines ->Add_Field("Z1" , SG_DATATYPE_Double); m_pLines ->Add_Field("Z2" , SG_DATATYPE_Double); m_pPolyLines = SG_Create_Shapes(SHAPE_TYPE_Line , CSG_String::Format(SG_T("%s [%s]"), SG_File_Get_Name(fName, false).c_str(), _TL("Polylines"))); m_pPolyLines ->Add_Field("LAYER" , SG_DATATYPE_String); m_pPolyLines ->Add_Field("FLAGS" , SG_DATATYPE_Int); m_pPolygons = SG_Create_Shapes(SHAPE_TYPE_Polygon , CSG_String::Format(SG_T("%s [%s]"), SG_File_Get_Name(fName, false).c_str(), _TL("Polygons"))); m_pPolygons ->Add_Field("LAYER" , SG_DATATYPE_String); m_pPolygons ->Add_Field("FLAGS" , SG_DATATYPE_Int); m_pCircles = SG_Create_Shapes(SHAPE_TYPE_Line , CSG_String::Format(SG_T("%s [%s]"), SG_File_Get_Name(fName, false).c_str(), _TL("Circles"))); m_pCircles ->Add_Field("LAYER" , SG_DATATYPE_String); m_pCircles ->Add_Field("FLAGS" , SG_DATATYPE_Int); m_pTriangles = SG_Create_Shapes(SHAPE_TYPE_Polygon , CSG_String::Format(SG_T("%s [%s]"), SG_File_Get_Name(fName, false).c_str(), _TL("Triangles"))); m_pTriangles ->Add_Field("LAYER" , SG_DATATYPE_String); m_pTriangles ->Add_Field("THICK" , SG_DATATYPE_Int); m_pTriangles ->Add_Field("Z1" , SG_DATATYPE_Double); m_pTriangles ->Add_Field("Z2" , SG_DATATYPE_Double); m_pTriangles ->Add_Field("Z3" , SG_DATATYPE_Double); m_pText = SG_Create_Shapes(SHAPE_TYPE_Point , CSG_String::Format(SG_T("%s [%s]"), SG_File_Get_Name(fName, false).c_str(), _TL("Text"))); m_pText ->Add_Field("LAYER" , SG_DATATYPE_String); m_pText ->Add_Field("Z" , SG_DATATYPE_Double); m_pText ->Add_Field("TEXT" , SG_DATATYPE_String); m_pText ->Add_Field("HEIGHT", SG_DATATYPE_Int); m_pText ->Add_Field("ANGLE" , SG_DATATYPE_Double); m_pText ->Add_Field("APX" , SG_DATATYPE_Double); m_pText ->Add_Field("APY" , SG_DATATYPE_Double); m_pText ->Add_Field("APZ" , SG_DATATYPE_Double); m_pText ->Add_Field("SCALE" , SG_DATATYPE_Double); m_pText ->Add_Field("HJUST" , SG_DATATYPE_Int); m_pText ->Add_Field("VJUST" , SG_DATATYPE_Int); m_pText ->Add_Field("STYLE" , SG_DATATYPE_String); m_pText ->Add_Field("FLAGS" , SG_DATATYPE_Int); //------------------------------------------------- m_Offset.x = 0.0; m_Offset.y = 0.0; m_Offset.z = 0.0; m_pPolyLine = NULL; DL_Dxf *pDXF = new DL_Dxf(); pDXF->in(fName.b_str(), this); delete(pDXF); //------------------------------------------------- ADD_RESULT("TABLES", m_pLayers); ADD_RESULT("TABLES", m_pBlocks); ADD_RESULT("SHAPES", m_pPoints); ADD_RESULT("SHAPES", m_pLines); ADD_RESULT("SHAPES", m_pPolyLines); ADD_RESULT("SHAPES", m_pPolygons); ADD_RESULT("SHAPES", m_pCircles); ADD_RESULT("SHAPES", m_pTriangles); ADD_RESULT("SHAPES", m_pText); } //----------------------------------------------------- return( Parameters("SHAPES")->asShapesList()->Get_Count() > 0 ); }
void writeLineTypes(DL_Dxf &output, DL_WriterA *writer) { writer->tableLineTypes(25); output.writeLineType(*writer, DL_LineTypeData("BYBLOCK", 0)); output.writeLineType(*writer, DL_LineTypeData("BYLAYER", 0)); output.writeLineType(*writer, DL_LineTypeData("CONTINUOUS", 0)); output.writeLineType(*writer, DL_LineTypeData("ACAD_ISO02W100", 0)); output.writeLineType(*writer, DL_LineTypeData("ACAD_ISO03W100", 0)); output.writeLineType(*writer, DL_LineTypeData("ACAD_ISO04W100", 0)); output.writeLineType(*writer, DL_LineTypeData("ACAD_ISO05W100", 0)); output.writeLineType(*writer, DL_LineTypeData("BORDER", 0)); output.writeLineType(*writer, DL_LineTypeData("BORDER2", 0)); output.writeLineType(*writer, DL_LineTypeData("BORDERX2", 0)); output.writeLineType(*writer, DL_LineTypeData("CENTER", 0)); output.writeLineType(*writer, DL_LineTypeData("CENTER2", 0)); output.writeLineType(*writer, DL_LineTypeData("CENTERX2", 0)); output.writeLineType(*writer, DL_LineTypeData("DASHDOT", 0)); output.writeLineType(*writer, DL_LineTypeData("DASHDOT2", 0)); output.writeLineType(*writer, DL_LineTypeData("DASHDOTX2", 0)); output.writeLineType(*writer, DL_LineTypeData("DASHED", 0)); output.writeLineType(*writer, DL_LineTypeData("DASHED2", 0)); output.writeLineType(*writer, DL_LineTypeData("DASHEDX2", 0)); output.writeLineType(*writer, DL_LineTypeData("DIVIDE", 0)); output.writeLineType(*writer, DL_LineTypeData("DIVIDE2", 0)); output.writeLineType(*writer, DL_LineTypeData("DIVIDEX2", 0)); output.writeLineType(*writer, DL_LineTypeData("DOT", 0)); output.writeLineType(*writer, DL_LineTypeData("DOT2", 0)); output.writeLineType(*writer, DL_LineTypeData("DOTX2", 0)); writer->tableEnd(); }
int main(int argc, char **argv) { if (argc < 5) { std::cerr << "Usage: dxf-import <main input file> <overlay input file> <overlay layer name prefix> <output file>\n"; return 1; } std::string mainInput = argv[1]; std::string overlayInput = argv[2]; std::string layerPrefix = argv[3]; LayerCounter mainLayerCounter(layerPrefix, false); mainLayerCounter.input(mainInput); LayerCounter overlayLayerCounter(layerPrefix, true); overlayLayerCounter.input(overlayInput); DL_Dxf output; DL_WriterA *writer = output.out(argv[4]); if (!writer) { std::cerr << "Unable to open output file '" << argv[4] << "'\n"; return 1; } output.writeHeader(*writer); VariableWriter(&output, writer).input(mainInput); writer->sectionEnd(); writer->sectionTables(); output.writeVPort(*writer); writeLineTypes(output, writer); writer->tableLayers(mainLayerCounter.layers() + overlayLayerCounter.layers()); LayerWriter(layerPrefix, false, &output, writer).input(mainInput); LayerWriter(layerPrefix, true, &output, writer).input(overlayInput); writer->tableEnd(); output.writeStyle(*writer); output.writeView(*writer); output.writeUcs(*writer); writer->tableAppid(1); writer->tableAppidEntry(0x12); writer->dxfString(2, "ACAD"); writer->dxfInt(70, 0); writer->tableEnd(); output.writeDimStyle(*writer, 3.0, 3.0, 1.5, 2.0, 3.0); output.writeBlockRecord(*writer); BlockRecordWriter(layerPrefix, false, &output, writer).input(mainInput); BlockRecordWriter(layerPrefix, true, &output, writer).input(overlayInput); writer->tableEnd(); writer->sectionEnd(); std::map<std::string, ImageHandle> images; writer->sectionBlocks(); output.writeBlock(*writer, DL_BlockData("*Model_Space", 0, 0.0, 0.0, 0.0)); output.writeEndBlock(*writer, "*Model_Space"); output.writeBlock(*writer, DL_BlockData("*Paper_Space", 0, 0.0, 0.0, 0.0)); output.writeEndBlock(*writer, "*Paper_Space"); output.writeBlock(*writer, DL_BlockData("*Paper_Space0", 0, 0.0, 0.0, 0.0)); output.writeEndBlock(*writer, "*Paper_Space0"); EntityWriter(layerPrefix, false, &output, writer, true, &images).input(mainInput); EntityWriter(layerPrefix, true, &output, writer, true, &images).input(overlayInput); writer->sectionEnd(); writer->sectionEntities(); EntityWriter(layerPrefix, false, &output, writer, false, &images).input(mainInput); EntityWriter(layerPrefix, true, &output, writer, false, &images).input(overlayInput); writer->sectionEnd(); output.writeObjects(*writer); ObjectWriter(&output, writer, &images).input(mainInput); ObjectWriter(&output, writer, &images).input(overlayInput); output.writeObjectsEnd(*writer); writer->dxfEOF(); writer->close(); delete writer; return 0; }
CC_FILE_ERROR DxfFilter::saveToFile(ccHObject* root, const char* filename) { #ifndef CC_DXF_SUPPORT ccLog::Error("[DXF] DXF format not supported! Check compilation parameters!"); return CC_FERR_CONSOLE_ERROR; #else if (!root || !filename) return CC_FERR_BAD_ARGUMENT; ccHObject::Container polylines; root->filterChildren(polylines,true,CC_POLY_LINE); //only polylines are handled for now size_t polyCount = polylines.size(); if (!polyCount) return CC_FERR_NO_SAVE; //get global bounding box ccBBox box; for (size_t i=0; i<polyCount; ++i) { ccBBox polyBox = polylines[i]->getBB(); if (i) { box += polyBox; } else { box = polyBox; } } CCVector3 diag = box.getDiagVec(); double baseSize = static_cast<double>(std::max(diag.x,diag.y)); double lineWidth = baseSize / 40.0; double pageMargin = baseSize / 20.0; DL_Dxf dxf; DL_WriterA* dw = dxf.out(qPrintable(filename), DL_VERSION_R12); if (!dw) { return CC_FERR_WRITING; } //write header dxf.writeHeader(*dw); //add dimensions dw->dxfString(9, "$INSBASE"); dw->dxfReal(10,0.0); dw->dxfReal(20,0.0); dw->dxfReal(30,0.0); dw->dxfString(9, "$EXTMIN"); dw->dxfReal(10,static_cast<double>(box.minCorner().x)-pageMargin); dw->dxfReal(20,static_cast<double>(box.minCorner().y)-pageMargin); dw->dxfReal(30,static_cast<double>(box.minCorner().z)-pageMargin); dw->dxfString(9, "$EXTMAX"); dw->dxfReal(10,static_cast<double>(box.maxCorner().x)+pageMargin); dw->dxfReal(20,static_cast<double>(box.maxCorner().y)+pageMargin); dw->dxfReal(30,static_cast<double>(box.maxCorner().z)+pageMargin); dw->dxfString(9, "$LIMMIN"); dw->dxfReal(10,static_cast<double>(box.minCorner().x)-pageMargin); dw->dxfReal(20,static_cast<double>(box.minCorner().y)-pageMargin); dw->dxfString(9, "$LIMMAX"); dw->dxfReal(10,static_cast<double>(box.maxCorner().x)+pageMargin); dw->dxfReal(20,static_cast<double>(box.maxCorner().y)+pageMargin); //close header dw->sectionEnd(); //Opening the Tables Section dw->sectionTables(); //Writing the Viewports dxf.writeVPort(*dw); //Writing the Linetypes (all by default) { dw->tableLineTypes(25); dxf.writeLineType(*dw, DL_LineTypeData("BYBLOCK", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BYLAYER", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CONTINUOUS", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO02W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO03W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO04W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO05W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BORDER", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BORDER2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BORDERX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CENTER", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CENTER2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CENTERX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHDOT", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHDOT2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHDOTX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHED", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHED2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHEDX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DIVIDE", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DIVIDE2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DIVIDEX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DOT", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DOT2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DOTX2", 0)); dw->tableEnd(); } //Writing the Layers dw->tableLayers(static_cast<int>(polyCount)+1); QStringList layerNames; { //default layer dxf.writeLayer(*dw, DL_LayerData("0", 0), DL_Attributes( std::string(""), // leave empty DL_Codes::black, // default color 100, // default width (in 1/100 mm) "CONTINUOUS")); // default line style //polylines layers for (unsigned i=0; i<polyCount; ++i) { //default layer name //TODO: would be better to use the polyline name! //but it can't be longer than 31 characters (R14 limit) QString layerName = QString("POLYLINE_%1").arg(i+1,3,10,QChar('0')); layerNames << layerName; dxf.writeLayer(*dw, DL_LayerData(layerName.toStdString(), 0), DL_Attributes( std::string(""), i == 0 ? DL_Codes::green : /*-*/DL_Codes::green, //invisible if negative! lineWidth, "CONTINUOUS")); } } dw->tableEnd(); //Writing Various Other Tables dxf.writeStyle(*dw); dxf.writeView(*dw); dxf.writeUcs(*dw); dw->tableAppid(1); dw->tableAppidEntry(0x12); dw->dxfString(2, "ACAD"); dw->dxfInt(70, 0); dw->tableEnd(); //Writing Dimension Styles dxf.writeDimStyle( *dw, /*arrowSize*/1, /*extensionLineExtension*/1, /*extensionLineOffset*/1, /*dimensionGap*/1, /*dimensionTextSize*/1); //Writing Block Records dxf.writeBlockRecord(*dw); dw->tableEnd(); //Ending the Tables Section dw->sectionEnd(); //Writing the Blocks Section { dw->sectionBlocks(); dxf.writeBlock(*dw, DL_BlockData("*Model_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Model_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space0", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space0"); dw->sectionEnd(); } //Writing the Entities Section { dw->sectionEntities(); //write polylines for (unsigned i=0; i<polyCount; ++i) { const ccPolyline* poly = static_cast<ccPolyline*>(polylines[i]); unsigned vertexCount = poly->size(); int flags = poly->isClosed() ? 1 : 0; if (!poly->is2DMode()) flags |= 8; //3D polyline dxf.writePolyline( *dw, DL_PolylineData(static_cast<int>(vertexCount),0,0,flags), DL_Attributes(layerNames[i].toStdString(), DL_Codes::bylayer, -1, "BYLAYER") ); for (unsigned i=0; i<vertexCount; ++i) { CCVector3 P; poly->getPoint(i,P); dxf.writeVertex(*dw, DL_VertexData( P.x, P.y, P.y ) ); } dxf.writePolylineEnd(*dw); } dw->sectionEnd(); } //Writing the Objects Section dxf.writeObjects(*dw); dxf.writeObjectsEnd(*dw); //Ending and Closing the File dw->dxfEOF(); dw->close(); delete dw; dw = 0; ccLog::Print("[DXF] File %s saved successfully",filename); return CC_FERR_NO_ERROR; #endif }
int main() { DL_Dxf dxf; DL_WriterA* dw = dxf.out("dimension.dxf", DL_Codes::AC1015); // section header: dxf.writeHeader(*dw); dw->sectionEnd(); // section tables: dw->sectionTables(); // VPORT: dxf.writeVPort(*dw); // LTYPE: dw->tableLinetypes(1); dxf.writeLinetype(*dw, DL_LinetypeData("CONTINUOUS", "Continuous", 0, 0, 0.0)); dxf.writeLinetype(*dw, DL_LinetypeData("BYLAYER", "", 0, 0, 0.0)); dxf.writeLinetype(*dw, DL_LinetypeData("BYBLOCK", "", 0, 0, 0.0)); dw->tableEnd(); // LAYER: dw->tableLayers(1); dxf.writeLayer( *dw, DL_LayerData("0", 0), DL_Attributes("", 1, 0x00ff0000, 15, "CONTINUOUS") ); dw->tableEnd(); // STYLE: dw->tableStyle(1); DL_StyleData style("Standard", 0, 0.0, 1.0, 0.0, 0, 2.5, "txt", ""); style.bold = false; style.italic = false; dxf.writeStyle(*dw, style); dw->tableEnd(); // VIEW: dxf.writeView(*dw); // UCS: dxf.writeUcs(*dw); // APPID: dw->tableAppid(1); dxf.writeAppid(*dw, "ACAD"); dw->tableEnd(); // DIMSTYLE: dxf.writeDimStyle(*dw, 2.5, 0.625, 0.625, 0.625, 2.5); // BLOCK_RECORD: dxf.writeBlockRecord(*dw); dw->tableEnd(); dw->sectionEnd(); // BLOCK: dw->sectionBlocks(); dxf.writeBlock(*dw, DL_BlockData("*Model_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Model_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space0", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space0"); dw->sectionEnd(); // ENTITIES: dw->sectionEntities(); DL_Attributes attributes("0", 256, -1, -1, "BYLAYER"); // LINE: DL_LineData lineData(10, 5, 0, 30, 5, 0); dxf.writeLine(*dw, lineData, attributes); // DIMENSION: DL_DimensionData dimData(10.0, // def point (dimension line pos) 50.0, 0.0, 0, // text pos (irrelevant if flag 0x80 (128) set for type 0, 0.0, 0x1, // type: aligned with auto text pos (0x80 NOT set) 8, // attachment point: bottom center 2, // line spacing: exact 1.0, // line spacing factor "", // text "Standard", // style 0.0, // text angle 1.0, // linear factor 1.0); // dim scale DL_DimAlignedData dimAlignedData(10.0, // extension point 1 5.0, 0.0, 30.0, // extension point 2 5.0, 0.0); dxf.writeDimAligned(*dw, dimData, dimAlignedData, attributes); // end section ENTITIES: dw->sectionEnd(); dxf.writeObjects(*dw, "MY_OBJECTS"); dxf.writeObjectsEnd(*dw); dw->dxfEOF(); dw->close(); delete dw; return 0; }
bool DxfProfilesExporter::SaveHorizontalProfiles( const QSharedPointer<DistanceMapGenerationTool::Map>& map, ccPolyline* profile, QString filename, unsigned heightStepCount, double angularStep_rad, double radToUnitConvFactor, QString angleUnit, const Parameters& params, ccMainAppInterface* app/*= 0*/) { #ifdef CC_DXF_SUPPORT assert(c_pageMargin_mm < c_profileMargin_mm); assert(2.0*c_profileMargin_mm < std::min(c_pageWidth_mm,c_pageHeight_mm)); if (!map || !profile || heightStepCount == 0 || angularStep_rad <= 0) { //invalid parameters return false; } //Theoretical profile bounding box PointCoordinateType profileBBMin[3],profileBBMax[3]; profile->getAssociatedCloud()->getBoundingBox(profileBBMin,profileBBMax); //Mix with the map's boundaries along 'Y' double yMin = std::max( map->yMin + 0.5 * map->xStep, //central height of first row static_cast<double>(profileBBMin[1])); double yMax = std::min( map->yMin + (static_cast<double>(map->ySteps)-0.5) * map->yStep, //central height of last row static_cast<double>(profileBBMax[1])); const double ySpan = yMax - yMin; //For the 'X' dimension, it's easier to stick with the th. profile // const double xMin = profileBBMin[0]; const double xMax = profileBBMax[0]; const double xSpan = profileBBMax[0] - profileBBMin[0]; //shortcut for clarity const double& maxRadius = xMax; if (xSpan == 0.0 || ySpan == 0.0) { if (app) app->dispToConsole(QString("Internal error: null profile?!"),ccMainAppInterface::ERR_CONSOLE_MESSAGE); return false; } DL_Dxf dxf; DL_WriterA* dw = dxf.out(qPrintable(filename), DL_VERSION_R12); if (!dw) { if (app) app->dispToConsole(QString("Failed to open '%1' file for writing!").arg(filename),ccMainAppInterface::ERR_CONSOLE_MESSAGE); return false; } //write header dxf.writeHeader(*dw); //add dimensions dw->dxfString(9, "$INSBASE"); dw->dxfReal(10,0.0); dw->dxfReal(20,0.0); dw->dxfReal(30,0.0); dw->dxfString(9, "$EXTMIN"); dw->dxfReal(10,0.0); dw->dxfReal(20,0.0); dw->dxfReal(30,0.0); dw->dxfString(9, "$EXTMAX"); dw->dxfReal(10,c_pageWidth_mm); dw->dxfReal(20,c_pageHeight_mm); dw->dxfReal(30,0.0); dw->dxfString(9, "$LIMMIN"); dw->dxfReal(10,0.0); dw->dxfReal(20,0.0); dw->dxfString(9, "$LIMMAX"); dw->dxfReal(10,c_pageWidth_mm); dw->dxfReal(20,c_pageHeight_mm); //close header dw->sectionEnd(); //Opening the Tables Section dw->sectionTables(); //Writing the Viewports dxf.writeVPort(*dw); //Writing the Linetypes (all by default) { dw->tableLineTypes(25); dxf.writeLineType(*dw, DL_LineTypeData("BYBLOCK", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BYLAYER", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CONTINUOUS", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO02W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO03W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO04W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO05W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BORDER", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BORDER2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BORDERX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CENTER", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CENTER2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CENTERX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHDOT", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHDOT2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHDOTX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHED", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHED2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHEDX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DIVIDE", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DIVIDE2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DIVIDEX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DOT", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DOT2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DOTX2", 0)); dw->tableEnd(); } //Writing the Layers dw->tableLayers(heightStepCount+2); QStringList profileNames; { //default layer dxf.writeLayer(*dw, DL_LayerData("0", 0), DL_Attributes( std::string(""), // leave empty DL_Codes::black, // default color 100, // default width (in 1/100 mm) "CONTINUOUS")); // default line style //legend layer dxf.writeLayer(*dw, DL_LayerData(LEGEND_LAYER, 0), DL_Attributes( std::string(""), DL_Codes::black, s_lineWidth, "CONTINUOUS")); //horiz. profile layers for (unsigned i=0; i<heightStepCount; ++i) { //default profile name QString layerName = QString(HORIZ_PROFILE_LAYER).arg(i+1,3,10,QChar('0')); //but we use the profile title if we have one! //DGM: nope, as it may be longer than 31 characters (R14 limit) //if (params.profileTitles.size() == 1) //{ // //profile height // double height = yMin + static_cast<double>(i) / static_cast<double>(heightStepCount-1) * ySpan; // layerName = QString(params.profileTitles[0]).arg(height,0,'f',params.precision); // layerName.replace(QChar(' '),QChar('_')); //} profileNames << layerName; dxf.writeLayer(*dw, DL_LayerData(layerName.toStdString(), 0), DL_Attributes( std::string(""), i == 0 ? DL_Codes::green : -DL_Codes::green, //invisible if negative! s_lineWidth, "CONTINUOUS")); } } dw->tableEnd(); //Writing Various Other Tables //dxf.writeStyle(*dw); //DXFLIB V2.5 dxf.writeStyle(*dw,DL_StyleData("Standard",0,0.0,0.75,0.0,0,2.5,"txt","")); //DXFLIB V3.3 dxf.writeView(*dw); dxf.writeUcs(*dw); dw->tableAppid(1); dw->tableAppidEntry(0x12); dw->dxfString(2, "ACAD"); dw->dxfInt(70, 0); dw->tableEnd(); //Writing Dimension Styles dxf.writeDimStyle( *dw, /*arrowSize*/1, /*extensionLineExtension*/1, /*extensionLineOffset*/1, /*dimensionGap*/1, /*dimensionTextSize*/1); //Writing Block Records dxf.writeBlockRecord(*dw); dw->tableEnd(); //Ending the Tables Section dw->sectionEnd(); //Writing the Blocks Section { dw->sectionBlocks(); dxf.writeBlock(*dw, DL_BlockData("*Model_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Model_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space0", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space0"); dw->sectionEnd(); } //Writing the Entities Section { dw->sectionEntities(); //we make the profile fit in the middle of the page (21.0 x 29.7 cm) double scale = std::min((c_pageWidth_mm - 2.0 * c_profileMargin_mm)/(2.0*maxRadius), (c_pageHeight_mm - 2.0 * c_profileMargin_mm)/(2.0*maxRadius)); //min corner of profile area // const double x0 = (c_pageWidth_mm - 2.0*maxRadius*scale) / 2.0; const double y0 = (c_pageHeight_mm - 2.0*maxRadius*scale) / 2.0; //center of profile area const double xc = c_pageWidth_mm / 2.0; const double yc = c_pageHeight_mm / 2.0; //write legend { DL_Attributes DefaultLegendMaterial(LEGEND_LAYER, DL_Codes::bylayer, -1, "BYLAYER"); //write page contour { dxf.writePolyline( *dw, DL_PolylineData(4,0,0,1), DefaultLegendMaterial); dxf.writeVertex(*dw, DL_VertexData( c_pageMargin_mm, c_pageMargin_mm, 0.0)); dxf.writeVertex(*dw, DL_VertexData( c_pageMargin_mm, c_pageHeight_mm-c_pageMargin_mm, 0.0)); dxf.writeVertex(*dw, DL_VertexData( c_pageWidth_mm-c_pageMargin_mm, c_pageHeight_mm-c_pageMargin_mm, 0.0)); dxf.writeVertex(*dw, DL_VertexData( c_pageWidth_mm-c_pageMargin_mm, c_pageMargin_mm, 0.0)); dxf.writePolylineEnd(*dw); } double xLegend = c_pageMargin_mm + 2.0*c_textHeight_mm; double yLegend = c_pageMargin_mm + 2.0*c_textHeight_mm; const double legendWidth_mm = 20.0; //Y axis double axisTip = maxRadius*scale + 5.0; dxf.writeLine( *dw, DL_LineData(xc, yc, 0.0, xc, yc-axisTip, 0.0), DefaultLegendMaterial); //Y axis tip as triangle { double axisTipSize = 3.0; dxf.writePolyline( *dw, DL_PolylineData(3,0,0,1), //closed polyline! DefaultLegendMaterial); dxf.writeVertex(*dw, DL_VertexData( xc, yc-(axisTip+axisTipSize), 0.0)); dxf.writeVertex(*dw, DL_VertexData( xc-axisTipSize/2.0, yc-axisTip, 0.0)); dxf.writeVertex(*dw, DL_VertexData( xc+axisTipSize/2.0, yc-axisTip, 0.0)); dxf.writePolylineEnd(*dw); dxf.writeText( *dw, DL_TextData(xc,yc-(axisTip+2.0*axisTipSize),0.0,xc,yc-(axisTip+2.0*axisTipSize),0.0,c_textHeight_mm,1.0,0,1,3,"Y","STANDARD",0.0), DefaultLegendMaterial); } //deviation magnification factor QString magnifyStr = QString::number(params.devMagnifyCoef); dxf.writeText( *dw, DL_TextData(xLegend,yLegend,0.0,xLegend,yLegend,0.0,c_textHeight_mm,1.0,0,0,0,(QString("Deviation magnification factor: ")+magnifyStr).toStdString(),"STANDARD",0.0), DefaultLegendMaterial); //next line yLegend += c_textHeight_mm*2.0; //units QString unitsStr("mm"); dxf.writeText( *dw, DL_TextData(xLegend,yLegend,0.0,xLegend,yLegend,0.0,c_textHeight_mm,1.0,0,0,0,(QString("Deviation units: ")+unitsStr).toStdString(),"STANDARD",0.0), DefaultLegendMaterial); //next line yLegend += c_textHeight_mm*2.0; //true profile line (red) dxf.writeLine( *dw, DL_LineData(xLegend,yLegend,0,xLegend+legendWidth_mm,yLegend,0.0), DL_Attributes(LEGEND_LAYER, DL_Codes::green, -1, "BYLAYER")); dxf.writeText( *dw, DL_TextData(xLegend+legendWidth_mm+c_textMargin_mm,yLegend,0.0,xLegend+legendWidth_mm+c_textMargin_mm,yLegend,0.0,c_textHeight_mm,1.0,0,0,0,params.legendRealProfileTitle.toStdString(),"STANDARD",0.0), DefaultLegendMaterial); //next line yLegend += c_textHeight_mm*2.0; //theoretical profile line (red) dxf.writeLine( *dw, DL_LineData(xLegend,yLegend,0,xLegend+legendWidth_mm,yLegend,0.0), DL_Attributes(LEGEND_LAYER, DL_Codes::red, -1, "BYLAYER")); dxf.writeText( *dw, DL_TextData(xLegend+legendWidth_mm+c_textMargin_mm,yLegend,0.0,xLegend+legendWidth_mm+c_textMargin_mm,yLegend,0.0,c_textHeight_mm,1.0,0,0,0,params.legendTheoProfileTitle.toStdString(),"STANDARD",0.0), DefaultLegendMaterial); } //profile values (fixed size: one per angular step of the input grid) std::vector<HorizStepData> polySteps; try { polySteps.resize(map->xSteps); } catch(std::bad_alloc) { //not engouh memory dw->dxfEOF(); dw->close(); delete dw; return false; } //write horizontal profiles for (unsigned heightStep=0; heightStep<heightStepCount; ++heightStep) { //profile height double height = yMin + static_cast<double>(heightStep) / static_cast<double>(heightStepCount-1) * ySpan; //corresponding index in map if (height < map->yMin || height >= map->yMin + static_cast<double>(map->ySteps) * map->yStep) { assert(false); //we have computed yMin and yMax so that those values are totally included inside the map's boundaries... continue; } unsigned jMap = static_cast<unsigned>((height-map->yMin)/map->yStep); assert(jMap < map->ySteps); //find corresponding radius double currentRadius = 0.0; { bool found = false; for (unsigned i=1; i<profile->size(); ++i) { const CCVector3* A = profile->getPoint(i-1); const CCVector3* B = profile->getPoint(i); double alpha = static_cast<double>((height - A->y)/(B->y - A->y)); if (alpha >= 0.0 && alpha <= 1.0) { //we deduce the right radius by linear interpolation currentRadius = A->x + alpha * (B->x - A->x); found = true; break; } } if (!found) { assert(false); //we have computed yMin and yMax so that 'height' is totally included inside the profile's boundaries... continue; } } const QString& currentLayer = profileNames[heightStep]; const DL_Attributes DefaultMaterial(currentLayer.toStdString(), DL_Codes::bylayer, -1, "BYLAYER"); const DL_Attributes GrayMaterial(currentLayer.toStdString(), DL_Codes::l_gray, -1, ""); //write layer title if (params.profileTitles.size() == 1) { QString title = QString(params.profileTitles[0]).arg(height,0,'f',params.precision); CCVector3d Ptop(xc, y0 + 2.0 * maxRadius * scale + c_profileMargin_mm / 2.0, 0.0); dxf.writeText( *dw, DL_TextData(Ptop.x,Ptop.y,Ptop.z,Ptop.x,Ptop.y,Ptop.z,c_textHeight_mm,1.0,0,1,0,title.toStdString(),"STANDARD",0.0), GrayMaterial); } //write theoretical profile (polyline = circle) { dxf.writeCircle(*dw, DL_CircleData(xc, yc, 0.0, currentRadius*scale), DL_Attributes(currentLayer.toStdString(), DL_Codes::red, -1, "BYLAYER")); } assert(polySteps.size() == map->xSteps); { const DistanceMapGenerationTool::MapCell* cell = &map->at(jMap * map->xSteps); for (unsigned iMap=0; iMap<map->xSteps; ++iMap, ++cell) { HorizStepData step; step.angle_rad = 2.0*M_PI * static_cast<double>(iMap)/static_cast<double>(map->xSteps); step.deviation = cell->count ? cell->value : 0.0; polySteps[iMap] = step; } } //profile "direction" double cwSign = map->counterclockwise ? -1.0 : 1.0; CCVector3d pageShift(xc,yc,0.0); //write profile polyline { dxf.writePolyline( *dw, DL_PolylineData(static_cast<int>(polySteps.size()),0,0,1), //closed shape! DefaultMaterial); for (size_t i=0; i<polySteps.size(); ++i) { const HorizStepData& step = polySteps[i]; double radius = currentRadius + step.deviation * params.devMagnifyCoef; dxf.writeVertex(*dw, DL_VertexData( pageShift.x - (cwSign * radius * sin(step.angle_rad)) * scale, pageShift.y - (radius * cos(step.angle_rad)) * scale, 0.0)); } dxf.writePolylineEnd(*dw); } //write corresponding 'deviation bars' and labels { size_t lastStep = 0; for (size_t i=0; i<polySteps.size(); ++i) { const HorizStepData& step = polySteps[i]; bool displayIt = (i == 0/*|| i+1 == polySteps.size()*/); //warning: cycle if (i != 0) { double dAngle = polySteps[i].angle_rad - polySteps[lastStep].angle_rad; double next_dAngle = (i+1 == polySteps.size() ? polySteps[0].angle_rad + 2.0*M_PI : polySteps[i+1].angle_rad) - polySteps[lastStep].angle_rad; if (dAngle >= angularStep_rad || (next_dAngle > angularStep_rad && fabs(dAngle - angularStep_rad) < fabs(next_dAngle - angularStep_rad))) { displayIt = true; } } if (displayIt && i != 0) //we skip 0 as we always display a vertical axis! { CCVector3d relativePos( -cwSign * sin(step.angle_rad), -cos(step.angle_rad), 0.0); CCVector3d Pangle = relativePos * currentRadius; CCVector3d Pdev = relativePos * (currentRadius + step.deviation * params.devMagnifyCoef); //page scaling Pangle = pageShift + Pangle * scale; Pdev = pageShift + Pdev * scale; //deviation bar dxf.writeLine(*dw, DL_LineData(Pangle.x,Pangle.y,Pangle.z,Pdev.x,Pdev.y,Pdev.z), GrayMaterial); //labels //justification depends on the current angle const double c_angleMargin_rad = 5.0 / 180.0 * M_PI; //margin: 5 degrees const double c_margin = sin(c_angleMargin_rad); //Horizontal justification: 0 = Left , 1 = Center, 2 = Right int hJustification = 1; if (relativePos.x < -c_margin) //point on the left hJustification = 2; //Right else if (relativePos.x > c_margin) //point on the right hJustification = 0; //Left //Vertical justification: 0 = Baseline, 1 = Bottom, 2 = Middle, 3 = Top int vJustification = 2; if (relativePos.y < -c_margin) //point in the lower part vJustification = 3; //Top else if (relativePos.y > c_margin) //point in the upper part vJustification = 1; //Bottom int hJustificationDev = hJustification; int hJustificationAng = hJustification; int vJustificationDev = vJustification; int vJustificationAng = vJustification; //negative deviation: profile is inside the circle // - deviation is displayed insde // - angle is displayed outside if (step.deviation < 0.0) { Pdev -= relativePos * 2.0*c_textMargin_mm; Pangle += relativePos * c_textMargin_mm; //invert dev. text justification if (hJustificationDev != 1) hJustificationDev = 2-hJustificationDev; // 0 <-> 2 if (vJustificationDev != 2) vJustificationDev = 4-vJustificationDev; // 1 <-> 3 } else { Pdev += relativePos * 2.0*c_textMargin_mm; Pangle -= relativePos * c_textMargin_mm; //invert ang. text justification if (hJustificationAng != 1) hJustificationAng = 2-hJustificationAng; // 0 <-> 2 if (vJustificationAng != 2) vJustificationAng = 4-vJustificationAng; // 1 <-> 3 } QString devText = QString::number(polySteps[i].deviation * params.devLabelMultCoef,'f',params.precision); dxf.writeText( *dw, DL_TextData(Pdev.x,Pdev.y,Pdev.z,Pdev.x,Pdev.y,Pdev.z,c_textHeight_mm,1.0,0,hJustificationDev,vJustificationDev,devText.toStdString(),"STANDARD",0.0), DefaultMaterial); QString angleText = QString::number(polySteps[i].angle_rad *radToUnitConvFactor,'f',params.precision)+angleUnit; dxf.writeText( *dw, DL_TextData(Pangle.x,Pangle.y,Pangle.z,Pangle.x,Pangle.y,Pangle.z,c_textHeight_mm,1.0,0,hJustificationAng,vJustificationAng,angleText.toStdString(),"STANDARD",0.0), GrayMaterial); lastStep = i; } } } } dw->sectionEnd(); } //Writing the Objects Section dxf.writeObjects(*dw); dxf.writeObjectsEnd(*dw); //Ending and Closing the File dw->dxfEOF(); dw->close(); delete dw; dw = 0; return true; #else return false; #endif }
bool DxfProfilesExporter::SaveVerticalProfiles( const QSharedPointer<DistanceMapGenerationTool::Map>& map, ccPolyline* profile, QString filename, unsigned angularStepCount, double heightStep, const Parameters& params, ccMainAppInterface* app/*=0*/) { #ifdef CC_DXF_SUPPORT assert(c_pageMargin_mm < c_profileMargin_mm); assert(2.0*c_profileMargin_mm < std::min(c_pageWidth_mm,c_pageHeight_mm)); if (!map || !profile || angularStepCount == 0 || heightStep <= 0) { //invalid parameters return false; } //Theoretical profile bounding box PointCoordinateType profileBBMin[3],profileBBMax[3]; profile->getAssociatedCloud()->getBoundingBox(profileBBMin,profileBBMax); //Mix with the map's boundaries along 'Y' double yMin = std::max(map->yMin,static_cast<double>(profileBBMin[1])); double yMax = std::min(map->yMin + static_cast<double>(map->ySteps) * map->yStep, static_cast<double>(profileBBMax[1])); const double ySpan = yMax - yMin; //For the 'X' dimension, it's easier to stick with the th. profile const double xMin = profileBBMin[0]; // const double xMax = profileBBMax[0]; const double xSpan = profileBBMax[0] - profileBBMin[0]; if (xSpan == 0.0 || ySpan == 0.0) { if (app) app->dispToConsole(QString("Internal error: null profile?!"),ccMainAppInterface::ERR_CONSOLE_MESSAGE); return false; } DL_Dxf dxf; DL_WriterA* dw = dxf.out(qPrintable(filename), DL_VERSION_R12); if (!dw) { if (app) app->dispToConsole(QString("Failed to open '%1' file for writing!").arg(filename),ccMainAppInterface::ERR_CONSOLE_MESSAGE); return false; } //write header dxf.writeHeader(*dw); //add dimensions dw->dxfString(9, "$INSBASE"); dw->dxfReal(10,0.0); dw->dxfReal(20,0.0); dw->dxfReal(30,0.0); dw->dxfString(9, "$EXTMIN"); dw->dxfReal(10,0.0); dw->dxfReal(20,0.0); dw->dxfReal(30,0.0); dw->dxfString(9, "$EXTMAX"); dw->dxfReal(10,c_pageWidth_mm); dw->dxfReal(20,c_pageHeight_mm); dw->dxfReal(30,0.0); dw->dxfString(9, "$LIMMIN"); dw->dxfReal(10,0.0); dw->dxfReal(20,0.0); dw->dxfString(9, "$LIMMAX"); dw->dxfReal(10,c_pageWidth_mm); dw->dxfReal(20,c_pageHeight_mm); //close header dw->sectionEnd(); //Opening the Tables Section dw->sectionTables(); //Writing the Viewports dxf.writeVPort(*dw); //Writing the Linetypes (all by default) { dw->tableLineTypes(25); dxf.writeLineType(*dw, DL_LineTypeData("BYBLOCK", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BYLAYER", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CONTINUOUS", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO02W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO03W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO04W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("ACAD_ISO05W100", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BORDER", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BORDER2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("BORDERX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CENTER", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CENTER2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("CENTERX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHDOT", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHDOT2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHDOTX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHED", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHED2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DASHEDX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DIVIDE", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DIVIDE2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DIVIDEX2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DOT", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DOT2", 0)); dxf.writeLineType(*dw, DL_LineTypeData("DOTX2", 0)); dw->tableEnd(); } //Writing the Layers dw->tableLayers(angularStepCount+3); QStringList profileNames; { //default layer dxf.writeLayer(*dw, DL_LayerData("0", 0), DL_Attributes( std::string(""), // leave empty DL_Codes::black, // default color 100, // default width (in 1/100 mm) "CONTINUOUS")); // default line style //theoretical profile layer dxf.writeLayer(*dw, DL_LayerData(PROFILE_LAYER, 0), DL_Attributes( std::string(""), DL_Codes::red, s_lineWidth, "CONTINUOUS")); //legend layer dxf.writeLayer(*dw, DL_LayerData(LEGEND_LAYER, 0), DL_Attributes( std::string(""), DL_Codes::black, s_lineWidth, "CONTINUOUS")); //vert. profile layers for (unsigned i=0; i<angularStepCount; ++i) { //default layer name QString layerName = QString(VERT_PROFILE_LAYER).arg(i+1,3,10,QChar('0')); //but we use the profile title if we have one! //DGM: nope, as it may be longer than 31 characters (R14 limit) //if (params.profileTitles.size() >= static_cast<int>(angularStepCount)) //{ // layerName = params.profileTitles[i]; // layerName.replace(QChar(' '),QChar('_')); //} profileNames << layerName; dxf.writeLayer(*dw, DL_LayerData(layerName.toStdString(), 0), DL_Attributes( std::string(""), i == 0 ? DL_Codes::green : -DL_Codes::green, //invisible if negative! s_lineWidth, "CONTINUOUS")); } } dw->tableEnd(); //Writing Various Other Tables //dxf.writeStyle(*dw); //DXFLIB V2.5 dxf.writeStyle(*dw,DL_StyleData("Standard",0,0.0,0.75,0.0,0,2.5,"txt","")); //DXFLIB V3.3 dxf.writeView(*dw); dxf.writeUcs(*dw); dw->tableAppid(1); dw->tableAppidEntry(0x12); dw->dxfString(2, "ACAD"); dw->dxfInt(70, 0); dw->tableEnd(); //Writing Dimension Styles dxf.writeDimStyle( *dw, /*arrowSize*/1, /*extensionLineExtension*/1, /*extensionLineOffset*/1, /*dimensionGap*/1, /*dimensionTextSize*/1); //Writing Block Records dxf.writeBlockRecord(*dw); //dxf.writeBlockRecord(*dw, "myblock1"); //dxf.writeBlockRecord(*dw, "myblock2"); dw->tableEnd(); //Ending the Tables Section dw->sectionEnd(); //Writing the Blocks Section { dw->sectionBlocks(); dxf.writeBlock(*dw, DL_BlockData("*Model_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Model_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space0", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space0"); dw->sectionEnd(); } //Writing the Entities Section { dw->sectionEntities(); //we make the profile fit in the middle of the page (21.0 x 29.7 cm) double scale = std::min((c_pageWidth_mm - 2.0 * c_profileMargin_mm)/xSpan, (c_pageHeight_mm - 2.0 * c_profileMargin_mm)/ySpan); //min corner of profile area const double x0 = (c_pageWidth_mm - xSpan*scale) / 2.0; const double y0 = (c_pageHeight_mm - ySpan*scale) / 2.0; //write theoretical profile (polyline) { unsigned vertexCount = profile->size(); dxf.writePolyline( *dw, DL_PolylineData(static_cast<int>(vertexCount),0,0,0), DL_Attributes(PROFILE_LAYER, DL_Codes::bylayer, -1, "BYLAYER")); for (unsigned i=0; i<vertexCount; ++i) { const CCVector3* P = profile->getPoint(i); dxf.writeVertex(*dw, DL_VertexData(x0+(P->x-xMin)*scale,y0+(P->y-yMin)*scale,0.0)); } dxf.writePolylineEnd(*dw); } //write legend { DL_Attributes DefaultLegendMaterial(LEGEND_LAYER, DL_Codes::bylayer, -1, "BYLAYER"); //write page contour { dxf.writePolyline( *dw, DL_PolylineData(4,0,0,1), DefaultLegendMaterial); dxf.writeVertex(*dw, DL_VertexData( c_pageMargin_mm, c_pageMargin_mm, 0.0)); dxf.writeVertex(*dw, DL_VertexData( c_pageMargin_mm, c_pageHeight_mm-c_pageMargin_mm, 0.0)); dxf.writeVertex(*dw, DL_VertexData( c_pageWidth_mm-c_pageMargin_mm, c_pageHeight_mm-c_pageMargin_mm, 0.0)); dxf.writeVertex(*dw, DL_VertexData( c_pageWidth_mm-c_pageMargin_mm, c_pageMargin_mm, 0.0)); dxf.writePolylineEnd(*dw); } double xLegend = c_pageMargin_mm + 2.0*c_textHeight_mm; double yLegend = c_pageMargin_mm + 2.0*c_textHeight_mm; const double legendWidth_mm = 20.0; //deviation magnification factor QString magnifyStr = QString::number(params.devMagnifyCoef); dxf.writeText( *dw, DL_TextData(xLegend,yLegend,0.0,xLegend,yLegend,0.0,c_textHeight_mm,1.0,0,0,0,(QString("Deviation magnification factor: ")+magnifyStr).toStdString(),"STANDARD",0.0), DefaultLegendMaterial); //next line yLegend += c_textHeight_mm*2.0; //units QString unitsStr("mm"); dxf.writeText( *dw, DL_TextData(xLegend,yLegend,0.0,xLegend,yLegend,0.0,c_textHeight_mm,1.0,0,0,0,(QString("Deviation units: ")+unitsStr).toStdString(),"STANDARD",0.0), DefaultLegendMaterial); //next line yLegend += c_textHeight_mm*2.0; //true profile line (red) dxf.writeLine( *dw, DL_LineData(xLegend,yLegend,0,xLegend+legendWidth_mm,yLegend,0.0), DL_Attributes(LEGEND_LAYER, DL_Codes::green, -1, "BYLAYER")); dxf.writeText( *dw, DL_TextData(xLegend+legendWidth_mm+c_textMargin_mm,yLegend,0.0,xLegend+legendWidth_mm+c_textMargin_mm,yLegend,0.0,c_textHeight_mm,1.0,0,0,0,params.legendRealProfileTitle.toStdString(),"STANDARD",0.0), DefaultLegendMaterial); //next line yLegend += c_textHeight_mm*2.0; //theoretical profile line (red) dxf.writeLine( *dw, DL_LineData(xLegend,yLegend,0,xLegend+legendWidth_mm,yLegend,0.0), DL_Attributes(LEGEND_LAYER, DL_Codes::red, -1, "BYLAYER")); dxf.writeText( *dw, DL_TextData(xLegend+legendWidth_mm+c_textMargin_mm,yLegend,0.0,xLegend+legendWidth_mm+c_textMargin_mm,yLegend,0.0,c_textHeight_mm,1.0,0,0,0,params.legendTheoProfileTitle.toStdString(),"STANDARD",0.0), DefaultLegendMaterial); } //write vertical profiles for (unsigned angleStep=0; angleStep<angularStepCount; ++angleStep) { std::vector<VertStepData> polySteps; try { polySteps.reserve(map->ySteps); } catch(std::bad_alloc) { //not enough memory dw->dxfEOF(); dw->close(); delete dw; return false; } unsigned iMap = static_cast<unsigned>(static_cast<double>(angleStep * map->xSteps) / static_cast<double>(angularStepCount)); for (unsigned jMap=0; jMap < map->ySteps; ++jMap) { const DistanceMapGenerationTool::MapCell& cell = map->at(iMap + jMap * map->xSteps); VertStepData step; step.height = map->yMin + static_cast<double>(jMap) * map->yStep; if (step.height >= yMin && step.height <= yMax) { //find corresponding radius bool found = false; for (unsigned i=1; i<profile->size(); ++i) { const CCVector3* A = profile->getPoint(i-1); const CCVector3* B = profile->getPoint(i); double alpha = static_cast<double>((step.height - A->y)/(B->y - A->y)); if (alpha >= 0.0 && alpha <= 1.0) { //we deduce the right radius by linear interpolation step.radius_th = A->x + alpha * (B->x - A->x); found = true; break; } } if (found) { step.deviation = cell.count ? cell.value : 0.0; polySteps.push_back(step); } } } const DL_Attributes DefaultMaterial(profileNames[angleStep].toStdString(), DL_Codes::bylayer, -1, "BYLAYER"); const DL_Attributes GrayMaterial(profileNames[angleStep].toStdString(), DL_Codes::l_gray, -1, ""); //write layer title if (static_cast<int>(angleStep) < params.profileTitles.size()) { const QString& title = params.profileTitles[angleStep]; CCVector3d Ptop(c_pageWidth_mm / 2.0, y0 + ySpan * scale + c_profileMargin_mm / 2.0, 0.0); dxf.writeText( *dw, DL_TextData(Ptop.x,Ptop.y,Ptop.z,Ptop.x,Ptop.y,Ptop.z,c_textHeight_mm,1.0,0,1,0,title.toStdString(),"STANDARD",0.0), GrayMaterial); } //write corresponding polyline { dxf.writePolyline( *dw, DL_PolylineData(static_cast<int>(polySteps.size()),0,0,0), DefaultMaterial); for (size_t i=0; i<polySteps.size(); ++i) { const VertStepData& step = polySteps[i]; dxf.writeVertex(*dw, DL_VertexData( x0 + (step.radius_th + step.deviation * params.devMagnifyCoef - xMin) * scale, y0 + (step.height - yMin) * scale, 0.0)); } dxf.writePolylineEnd(*dw); } //write corresponding 'deviation bars' and labels CCVector3d pageShift(x0 - xMin * scale, y0 - yMin * scale, 0.0); { size_t lastStep = 0; for (size_t i=0; i<polySteps.size(); ++i) { const VertStepData& step = polySteps[i]; bool displayIt = (i == 0 || i+1 == polySteps.size()); if (!displayIt) { double dh = polySteps[i].height - polySteps[lastStep].height; double next_dh = polySteps[i+1].height - polySteps[lastStep].height; if (dh >= heightStep || (next_dh > heightStep && fabs(dh - heightStep) < fabs(next_dh - heightStep))) { displayIt = true; } } if (displayIt) { CCVector3d Pheight(step.radius_th,step.height,0.0); CCVector3d Pdev(step.radius_th + step.deviation * params.devMagnifyCoef,step.height,0.0); //page scaling Pheight = pageShift + Pheight * scale; Pdev = pageShift + Pdev * scale; //deviation bar dxf.writeLine(*dw, DL_LineData(Pheight.x,Pheight.y,Pheight.z,Pdev.x,Pdev.y,Pdev.z), GrayMaterial); //labels //Horizontal justification: 0 = Left , 1 = Center, 2 = Right int hJustification = 0; //Vertical justification: 0 = Baseline, 1 = Bottom, 2 = Middle, 3 = Top int vJustification = 2; if (step.deviation < 0.0) { //deviation label on the left Pdev.x -= 2.0*c_textMargin_mm; //opposite for the height label Pheight.x += c_textMargin_mm; hJustification = 2; //Right } else { //deviation label on the right Pdev.x += 2.0*c_textMargin_mm; //opposite for the height label Pheight.x -= c_textMargin_mm; hJustification = 0; //Left } QString devText = QString::number(polySteps[i].deviation * params.devLabelMultCoef,'f',params.precision); dxf.writeText( *dw, DL_TextData(Pdev.x,Pdev.y,Pdev.z,Pdev.x,Pdev.y,Pdev.z,c_textHeight_mm,1.0,0,hJustification,vJustification,devText.toStdString(),"STANDARD",0.0), DefaultMaterial); QString heightText = QString::number(polySteps[i].height,'f',params.precision); dxf.writeText( *dw, DL_TextData(Pheight.x,Pheight.y,Pheight.z,Pheight.x,Pheight.y,Pheight.z,c_textHeight_mm,1.0,0,2-hJustification,vJustification,heightText.toStdString(),"STANDARD",0.0), GrayMaterial); lastStep = i; } } } } dw->sectionEnd(); } //Writing the Objects Section dxf.writeObjects(*dw); dxf.writeObjectsEnd(*dw); //Ending and Closing the File dw->dxfEOF(); dw->close(); delete dw; dw = 0; return true; #else return false; #endif }
int main() { DL_Dxf dxf; DL_WriterA* dw = dxf.out("hatch.dxf", DL_Codes::AC1015); // section header: dxf.writeHeader(*dw); dw->sectionEnd(); // section tables: dw->sectionTables(); // VPORT: dxf.writeVPort(*dw); // LTYPE: dw->tableLinetypes(1); dxf.writeLinetype(*dw, DL_LinetypeData("CONTINUOUS", "Continuous", 0, 0, 0.0)); dxf.writeLinetype(*dw, DL_LinetypeData("BYLAYER", "", 0, 0, 0.0)); dxf.writeLinetype(*dw, DL_LinetypeData("BYBLOCK", "", 0, 0, 0.0)); dw->tableEnd(); // LAYER: dw->tableLayers(1); dxf.writeLayer( *dw, DL_LayerData("0", 0), DL_Attributes("", 2, 0, 100, "CONTINUOUS") ); dw->tableEnd(); // STYLE: dw->tableStyle(1); DL_StyleData style("Standard", 0, 0.0, 1.0, 0.0, 0, 2.5, "txt", ""); style.bold = false; style.italic = false; dxf.writeStyle(*dw, style); dw->tableEnd(); // VIEW: dxf.writeView(*dw); // UCS: dxf.writeUcs(*dw); // APPID: dw->tableAppid(1); dxf.writeAppid(*dw, "ACAD"); dw->tableEnd(); // DIMSTYLE: dxf.writeDimStyle(*dw, 2.5, 0.625, 0.625, 0.625, 2.5); // BLOCK_RECORD: dxf.writeBlockRecord(*dw); dw->tableEnd(); dw->sectionEnd(); // BLOCK: dw->sectionBlocks(); dxf.writeBlock(*dw, DL_BlockData("*Model_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Model_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space"); dxf.writeBlock(*dw, DL_BlockData("*Paper_Space0", 0, 0.0, 0.0, 0.0)); dxf.writeEndBlock(*dw, "*Paper_Space0"); dw->sectionEnd(); // ENTITIES: dw->sectionEntities(); DL_Attributes attributes("0", 2, 0, -1, "BYLAYER"); // start hatch with one loop: DL_HatchData data(1, false, 100.0, 0.0, "ESCHER", 0.0, 0.0); dxf.writeHatch1(*dw, data, attributes); // start loop: DL_HatchLoopData lData(1); dxf.writeHatchLoop1(*dw, lData); // write edge: DL_HatchEdgeData eData( 0.0, 0.0, 100.0, 0.0, M_PI*2, true ); dxf.writeHatchEdge(*dw, eData); // end loop: dxf.writeHatchLoop2(*dw, lData); // end hatch: dxf.writeHatch2(*dw, data, attributes); // end section ENTITIES: dw->sectionEnd(); dxf.writeObjects(*dw, "MY_OBJECTS"); dxf.writeObjectsEnd(*dw); dw->dxfEOF(); dw->close(); delete dw; return 0; }