<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    TWaver - 專注UI技術

    http://twaver.servasoft.com/
    posts - 171, comments - 191, trackbacks - 0, articles - 2
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    TWaver導入導出AutoCAD DXF圖紙

    Posted on 2010-12-14 09:41 TWaver 閱讀(2447) 評論(1)  編輯  收藏

    幾年前就有用戶提出TWaver讀取并轉(zhuǎn)換AutoCAD圖紙的需求了,最近又需要修改并保存AutoCAD圖紙。用戶的需求就是我們的動力,目前TWaver終于有了導入導出AutoCAD圖紙的解決方案。



    首先我們先看看AutoCAD的幾種文件格式:
    1. DWG:是原始圖紙格式,包含了圖紙所有的信息,Autodesk公司出于安全考慮沒有給出詳細的格式說明
    2. DWF:比DWG文件小很多,用于其他用戶瀏覽,添加備注等,不能編輯
    3. DXF:是用于和其他CAD系統(tǒng)交換數(shù)據(jù)的文件格式,分二進制和ASCII格式,AutoCAD的幫助里包含了DXF文件的詳細描述

    雖然Open Design Specification(http://www.opendesign.com)對DWG文件格式有很詳細的介紹(http://www.opendesign.com/files/guestdownloads/OpenDesign_Specification_for_.dwg_files.pdf),但是研究其二進制格式的復雜程度可想而知,因此公開的ASCII格式的DXF文件格式成為了TWaver與AutoCAD數(shù)據(jù)交換的首選。

    進入正題之前,我們先來了解一下DXF文件的格式,具體規(guī)范在Autodesk的網(wǎng)站有詳細說明(http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=12272454&linkID=10809853, 另外, 這里還有個中文的http://docs.autodesk.com/ACD/2011/CHS/filesDXF/WSfacf1429558a55de185c428100849a0ab7-5f35.htm):
    1. DXF文件由組碼(Group Code)和值(Value)組成,Group Code和Value都分別占一行,Group Code是整數(shù)(從-5到1071),Value可以是整數(shù)、十六進制整數(shù)、布爾值(0或者1)、浮點數(shù)(精度可以達到16位小數(shù))或者字符串。
    2. Group Code確定了下一行Value的意義,有些Group Code有明確的意義(比如0代表entity類型,8代表Layer Name,9代表變量名并只用在HEADER段,62代表顏色),有些Group Code的代表一類值(比如10代表一個點的x值,11代表y值,12代表z值,這個點可能是一個Circle的中心點,也可能是一個Line的起始點/結(jié)束點等)。
    3. DXF文件共分為7個段(Section):
    3.1 HEADER,包含了一系列和圖紙相關的變量信息,每個變量由給出變量名稱的組碼 9 指定,其后是提供變量值的組。比如AutoCAD版本,坐標系的最小、最大值等。
    3.2 CLASSES,包含了在BLOCKS,ENTITIES和OBJECTS段用到的類的定義,比如LWPOLYLINE
    3.3 TABLES,包含各種表,比如圖層(Layer)、線條類型(LTYPE)等;每個表可以包含多個條目
    3.4 BLOCKS,包含構成圖形中每個塊參照的塊定義和圖形圖元,由一系列Entity組成
    3.5 ENTITIES,包含各種圖形對象,也叫圖元(Entity),比如點(POINT)、線(LINE),圓(CIRCLE),?。ˋRC),多邊形(LWPOLYLINE)等,是我們解析的重點
    3.6 OBJECTS,包括非圖形對象的數(shù)據(jù),供 AutoLISP 以及 ObjectARX 應用程序所使用
    3.7 THUMBNAILIMAGE,包含DXF文件的縮略圖
    4. 每個Section以Group Code(0)和Value(SECTION)開始,以Group Code(0)和Value(ENDSEC)結(jié)束

    下面對TWaver DXF包做詳細的解釋:
    1 twaver.dxf.common包下的類對所有DXF的數(shù)據(jù)進行了封裝(基類DXFData)


    1.1 section包下的類分別封裝了DXF文件的7個段,實現(xiàn)接口DxfSection

    1.2 entities包下的所有類對應Entity段的所有圖元,基類為DxfEntity

    1.3 objects包對應Objects段下的元素,基類為DxfObject
    1.4 tables包對應Tables段下的元素,基類為DxfTable

    1.5 DxfBlock類對應Blocks段下的元素
    1.6 DxfClass類對應Classes段下的元素
    1.7 DxfVariable類對應Header段下的一個變量
    1.8 DxfValue類封裝了DXF文件的Value值
    1.9 DxfValuePair類封裝了DXF文件的一個組碼和值對
    1.10 DxfValuePairCollection類包含構成一個Block或Entity等的組碼和值集合
    2 twaver.dxf.element包對DXF文件的Entity段的每種圖元和TWaver的Element網(wǎng)元進行了一一對應

    3 twaver.dxf.parser包是解析DXF文件的核心
    3.1 handle包對DXF文件的7個段分別進行解析,接口為DxfSectionHandler
    3.2 entities包對Entity段的每種圖元進行細化解析
    3.3 objects包對Objects段進行細化解析
    3.4 tables包對Table段進行細化解析
    4 DxfDocument封裝了DXF文件的7個段
    5 DxfReader讀取DXF文件,生成DxfDocument
    6 DxfViewer繼承TNetwork類,將 DxfDocument顯示成TWaver的拓撲圖,并可以添加、修改和刪除DxfDocument中的元素
    7 DxfWriter將DxfDocument的修改保存為DXF文件

    現(xiàn)在可以正式進入DXF文件的解析了,這里只拿一個簡單的情況(Circle圖元)舉個例子,其他圖元的解析大同小異,具體需要研究DXF的參考文檔。下面的圖片是從DXF參考文檔中截取出來的,其中最主要的是Group Code 10、20、30以及40。Group Code 10、20、30分別代表Circle的中心點的X、Y以及Z坐標,40代表Circle的半徑。

    這里是從DXF文件中截取的關于Cricle圖元的片段:

     

     1  0            //組碼0代表一個Entity的開始
     2CIRCLE        //值CIRCLE代表這個Entity是一個Cricle
     3  5            //組碼5代表唯一標識這個Entity的編號,或者叫句柄
     4BC4E        //十六進制的Entity的編號值
     5330            //組碼330代表指向所有者字典的句柄(可省略)
     61F            //十六進制的所有者句柄值
     7100            //組碼100代表子類標記
     8AcDbEntity    //所有Entity的父類都是AcDbEntity
     9  8            //組碼8代表圖層
    10圖層1        //圖層的名字
    11370            //組碼370代表線寬,是一個枚舉值
    12    35
    13100            //組碼100代表子類標記
    14AcDbCircle    //Circle的類名為AcDbCircle
    15 10            //組碼10代表中心點X坐標
    16-708.4449011916222
    17 20            //組碼20代表中心點Y坐標
    183306.535626846471
    19 30            //組碼30代表中心點Z坐標
    200.0
    21 40            //組碼40代表半徑
    2212.4186311615631

     

    TWaver DXF包對DXF文件的解析進行了封裝,只需要創(chuàng)建DxfReader對象,調(diào)用parse方法,就可以返回DxfDocument對象,然后調(diào)用DXFViewer的setDxfDocument方法即可顯示DXF文件,setDxfDocument內(nèi)部會將所有DXF圖元映射成TWaver的網(wǎng)元(接口為DxfElement):

     

     1private void initDatabox(File file, double scale){
     2    DxfReader dxfReader = new DxfReader();
     3    FileInputStream in = null;
     4    try {
     5        in = new FileInputStream(file);
     6        doc = dxfReader.parse(in, new HashMap());
     7    }
     catch (Exception e) {
     8        handleException(e);
     9    }
    finally{
    10        if(in != null){
    11            try {
    12                in.close();
    13            }
     catch (IOException e) {
    14            }

    15        }

    16    }

    17    if(doc == null){
    18        return;
    19    }

    20    this.network.setScale(scale);
    21    this.network.setDxfDocument(doc);
    22}

     

    DXFViewer. setDxfDocument創(chuàng)建TWaver網(wǎng)元的代碼片段如下:

     

     1private void initDataBox(DxfDocument dxfDocument) throws Exception {
     2    if(dxfDocument == null){
     3        return;
     4    }

     5    this.getDataBox().clear();
     6    this.dxfDocument = dxfDocument;
     7    this.context.setOriginX(this.dxfDocument.getHeader().getOriginX());
     8    this.context.setOriginY(-this.dxfDocument.getHeader().getOriginY());
     9
    10    for(DxfEntity entity : this.dxfDocument.getAllEntities()){
    11        entity.transform(context);
    12        if(!entity.getLayer().isVisible()){
    13            continue;
    14        }

    15        if(!entity.isVisibile()){
    16            continue;
    17        }

    18        addDxfElement(entity);
    19    }

    20}

    21
    22private void addDxfElement(DxfEntity entity) throws Exception {
    23    Class< ? extends DxfElement> elementClass = entity.getElementClass();
    24    if (elementClass == null{
    25        System.err.println("Can not handle entity: " + entity.getType());
    26        return;
    27    }

    28
    29    DxfElement element = elementClass.newInstance();
    30    if (entity instanceof DxfEntityInsert) {
    31        DxfEntityInsert insert = (DxfEntityInsert) entity;
    32        this.addDxfInsertItems(insert, (DxfInsert)element);
    33
    34        Point2D point = element.getLocation();
    35        point = context.restore(point, entity.isBlockEntity());
    36        insert.setOffsetX(insert.getValue(10).getDoubleValue() - point.getX());
    37        insert.setOffsetY(insert.getValue(20).getDoubleValue() - point.getY());
    38    }

    39    element.setDxfEntity(entity);
    40    this.getDataBox().addElement(element);
    41}

    42
    43private void addDxfInsertItems(DxfEntityInsert insert, DxfInsert parent) throws Exception {
    44    DxfBlock block = insert.getBlock();
    45    if (block != null{
    46        for (DxfEntity itemEntity : block.getEntities()) {
    47            if (!itemEntity.getLayer().isVisible()) {
    48                continue;
    49            }

    50            if (!itemEntity.isVisibile()) {
    51                continue;
    52            }

    53
    54            Class< ? extends DxfElement> itemElementClass = itemEntity.getElementClass();
    55            if (itemElementClass == null{
    56                System.err.println("Can not handle entity in block: " + itemEntity.getType());
    57                return;
    58            }

    59
    60            DxfElement itemElement = itemElementClass.newInstance();
    61            itemElement.setDxfEntity(itemEntity);
    62            itemElement.putRenderColor(DxfUtils.getColor(insert.getLayer().getColor()));
    63            parent.addChild(itemElement);
    64            this.getDataBox().addElement(itemElement);
    65        }

    66    }

    67}

    在DxfViewer中修改網(wǎng)元后,需要將修改結(jié)果從DxfElement中保存到DxfEntity中,代碼片段如下:

     1private void handleDxfElementPropertyChange(PropertyChangeEvent evt) {
     2    if(this.zooming || this.initializing){
     3        return;
     4    }

     5
     6    DxfElement element = (DxfElement)evt.getSource();
     7    if(element.getDxfEntity().isBlockEntity()){
     8        return;
     9    }

    10    String propertyName = TWaverUtil.getPropertyName(evt);
    11    if(TWaverConst.PROPERTYNAME_LOCATION.equals(propertyName)
    12            || TWaverConst.PROPERTYNAME_WIDTH.equals(propertyName)
    13            || TWaverConst.PROPERTYNAME_HEIGHT.equals(propertyName)
    14            || TWaverConst.PROPERTYNAME_SHAPELINKPOINTS.equals(propertyName)
    15            || TWaverConst.PROPERTYNAME_NAME.equals(propertyName)){
    16        element.saveDxfEntity(this.context);
    17    }

    18}

     

    最后解釋一下如何創(chuàng)建DXF圖元,下面是從Demo中DxfButton.java類中截取的代碼片段,也拿圖元Cricle做例子:


     1protected void preProcess(ResizableNode node){
     2 DxfCircle circle = (DxfCircle)node;
     3
     4 DxfEntityCircle circleEntity = new DxfEntityCircle();
     5 circleEntity.setDocument(dxfViewer.getDxfDocument());
     6 circleEntity.setBlockEntity(false);
     7
     8 circleEntity.setID(dxfViewer.getDxfDocument().getHeader().getNextID());
     9 Point2D point = dxfViewer.getTransformContext().restore(circle.getCenterLocation(), circleEntity.isBlockEntity());
    10 circleEntity.getCenterPoint().setX(point.getX());
    11 circleEntity.getCenterPoint().setY(point.getY());
    12 circleEntity.setLayer(dxfViewer.getDxfDocument().getRootLayer());
    13 circleEntity.setRadius(dxfViewer.getTransformContext().restoreWidth(circle.getWidth()/2));
    14
    15 circleEntity.put(DxfConsts.GROUPCODE_HANDLE, DxfUtils.toHexString(circleEntity.getID()));
    16 circleEntity.put(DxfConsts.GROUPCODE_SUBCLASS_MARKER, "AcDbEntity");
    17 circleEntity.put(DxfConsts.GROUPCODE_LAYER_NAME, circleEntity.getLayer().getName());
    18 circleEntity.put(DxfConsts.GROUPCODE_SUBCLASS_MARKER, "AcDbCircle");
    19 circleEntity.put(DxfConsts.GROUPCODE_START_X, DxfUtils.toString(circleEntity.getCenterPoint().getX()));
    20 circleEntity.put(DxfConsts.GROUPCODE_START_Y, DxfUtils.toString(circleEntity.getCenterPoint().getY()));
    21 circleEntity.put(DxfConsts.GROUPCODE_START_Z, "0");
    22 circleEntity.put(DxfConsts.GROUPCODE_CIRCLE_RADIUS, DxfUtils.toString(circleEntity.getRadius()));
    23
    24 dxfViewer.getDxfDocument().addEntity(circleEntity);
    25 circleEntity.transform(dxfViewer.getTransformContext());
    26
    27 circle.setDxfEntity(circleEntity);
    28}

     

    這里再解釋一下TransformContext類:主要目的是將AutoCAD的坐標系映射成Java的坐標系,里面的transform和restore方法在縮放和保存時使用

    注意點:
    1 絕對值小于1E-3或者大于1E7的非零double數(shù)據(jù)轉(zhuǎn)化成String時,JDK默認會用科學計數(shù)法表示,具體可以參考JDK文檔,所以需要用DecimalFormat特殊處理一把,參考DxfUtils.toString(double value)
    2 MText的text字段包含了一些格式信息,可以通過DxfUtils.stripMText(String text)過濾
    3 HEADER段的$HANDSEED變量代表下一個可用的句柄,可以用這個變量的值作為新加的Entity的句柄值,然后這個變量的值要加1
    4 AutoCAD的坐標原點在左下,Java的坐標原點在左上,通過TransformContext進行轉(zhuǎn)換
    5 AutoCAD的縮放模式只縮放位置和寬高,線條粗細不會縮放,但TWaver的縮放模式跟放大鏡是一樣的效果,所以DxfViewer做了特殊處理,通過鼠標滾輪實現(xiàn)和AutoCAD一樣的縮放

    目前已有功能:
    1 導入AutoCAD DXF文件并在Network中展示,目前能處理包含在ENTITY和BLOCK段的ARC、CIRCLE、HATCH、INSERT、LINE、LWPOLYLINE、MTEXT、POLYLINE以及TEXT等entity。
    2 能修改TEXT的文字,LINE的起始和結(jié)束點的位置,LWPOLYLINE和POLYLINE的頂點位置,CIRCLE的半徑和位置等并保存。
    3 能添加刪除已支持的Entity,并保存。
    4 鼠標滾輪能實現(xiàn)和AutoCAD一樣的縮放效果
    5 對于不能顯示的Entity不會做任何修改,保存時也不會遺漏。

    后續(xù)待開發(fā)的功能:
    1 支持更多Entity,比如標注(DIMENSION)等
    2 支持創(chuàng)建全新的DXF文件,實現(xiàn)將TWaver的拓撲圖保存為AutoCAD的DXF圖紙



    評論

    # 我們需要TWaver導入導出AutoCAD DXF圖紙功能請問哪里有下載開發(fā)包?  回復  更多評論   

    2016-04-13 13:06 by 曾曉南
    我們的項目需要TWaver導入導出AutoCAD DXF圖紙功能請問哪里有下載開發(fā)包?
    我的郵箱是:1391211019@qq.com

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    主站蜘蛛池模板: 久久伊人免费视频| 亚洲天堂免费在线视频| 男男gay做爽爽的视频免费| 免费毛片毛片网址| 免费人成在线观看视频高潮| 亚欧在线精品免费观看一区| 女人被弄到高潮的免费视频| 久久亚洲AV无码西西人体| 亚洲福利秒拍一区二区| 亚洲国产精品美女久久久久| 精品一区二区三区免费观看| 最好看最新的中文字幕免费| 成年女人免费v片| 国产精品亚洲高清一区二区| 亚洲视频日韩视频| 在线观看亚洲专区| 国产一区二区三区免费观看在线| 97视频免费在线| 亚洲国产一成久久精品国产成人综合 | 免费人成在线观看播放a| 黄页免费在线观看| 成人午夜性A级毛片免费| 亚洲乱码无码永久不卡在线| 亚洲午夜国产精品无卡| 国产免费AV片在线观看播放| 曰批视频免费30分钟成人| 亚洲精品老司机在线观看| 亚洲第一二三四区| 国产免费一区二区三区免费视频| 亚洲免费在线视频观看| 亚洲国产黄在线观看| 亚洲嫩草影院在线观看| 国产99视频精品免费视频76| 永久免费毛片在线播放| 亚洲精品无码久久久久去q| 亚洲欧美日韩综合俺去了| 久久国产乱子伦精品免费一| 国产成人免费片在线视频观看| 亚洲三级电影网站| 一级毛片免费在线观看网站| 欧美a级在线现免费观看|