thanimpdxfget.py :  » Business-Application » ThanCad » thancad-0.0.9 » p_gimdxf » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Business Application » ThanCad 
ThanCad » thancad 0.0.9 » p_gimdxf » thanimpdxfget.py
# -*- coding: iso-8859-7 -*-
import sys
import p_ggen
from thanimpdxf import ThanImportDxf


def _prt(s):
    "This function consumes a string that should be printed, but prints nothing."
    pass


class ThanDrIgnore:
    "A class which ignores the elements read by ThanImportDxf."

    def __init__(self, prt=p_ggen.prg):
        if prt == None: self.prt = _prt   # No message will be printed
        else:           self.prt = prt

    def dxfVport   (self, name, x1, y1, x2, y2):  pass
    def dxfXymm    (self, x1, y1, x2, y2):        pass
    def dxfLayer   (self, name, atts):            pass
    def dxfLtype   (self, name, desc, elems):     pass
    def dxfPolyline(self, xx, yy, zz, lay, handle, col):   pass
    def dxfLine    (self, xx, yy, zz, lay, handle, col):   pass
    def dxfCircle  (self, xx, yy, zz, lay, handle, col, r):pass
    def dxfPoint   (self, xx, yy, zz, lay, handle, col):   pass
    def dxfArc     (self, xx, yy, zz, lay, handle, col, r, theta1, theta2): pass
    def dxfText    (self, xx, yy, zz, lay, handle, col, text, h, theta):    pass
    def dxfBlockAtt(self, xx, yy, zz, lay, handle, col, blname, blatts):    pass
    def dxfThanImage(self, xx, yy, zz, lay, handle, col, filnam, size, ale, theta): pass
    def dxf3dface  (self, xx, yy, zz, lay, handle, col): pass


class ThanDrLayer(ThanDrIgnore):
    "A class which saves layers and ignores anything else."
    
    def __init__(self, *args, **kw):
        "Initialize layer container."
        ThanDrIgnore.__init__(self, *args, **kw)
  self.layer = {}
    
    def dxfLayer (self, name, atts):
        "Collect the layers."
  self.layer[name] = atts


class ThanDrWarn:
    """A class which warns about unknown object/layer pairs.
    
    I think that this is the safest class to derive from. If new functionality is 
    added to the library, this class will be updated. So the derived classes will
    dynamically inherit and they will produce warnings about things not implemented,
    or not accessed, or ignored.
    """

    def __init__(self, laykno=None, prt=p_ggen.prg):
        "Set known and unknown layers."
  self._objunk = {}
  self._functy = {}
        self._laykno = {}
  self._layunk = {}
  self._allLayKno = False
  if laykno == "*":
      self._allLayKno = True
        elif laykno != None:
            for lay in laykno: self._laykno[lay] = 0
        if prt == None: self.prt = _prt   # No message will be printed
  else:           self.prt = prt

    def warnObj(self, lay, obj):
        "Warn once if an unknown object/layer pair is found."
  if self._allLayKno or lay in self._laykno:
            m = self._objunk.get((obj, lay), 0) + 1
      self._objunk[obj, lay] = m
      if m > 1: return
      self.prt("Dxf import Warning: (duplicate) objects of type '%s'" % obj)
      self.prt("                    are ignored in layer %s." % lay)
  else:
      m = self._layunk.get(lay, 0) + 1
          self._layunk[lay] = m
      if m > 1: return
      self.prt("Dxf import Warning: layer %s will be ignored." % lay)

    def warnFuncty(self, functyname):
        "Warn once for every unimplemented type of functionality."
        n = self._functy.get(functyname, 0) + 1
  self._functy[functyname] = n
  if n > 1: return
  self.prt("Dxf import Warning: %s will be ignored." % functyname)

    def dxfVport    (self, name, x1, y1, x2, y2):  self.warnFuncty("Viewport definition")
    def dxfXymm     (self, x1, y1, x2, y2):        self.warnFuncty("Extents definition")
    def dxfLayer    (self, name, atts):            self.warnFuncty("Layer definition")
    def dxfLtype    (self, name, desc, elems):     self.warnFuncty("Line type definition")

    POLYLINE = "polyline"
    LINE     = "line"
    CIRCLE   = "circle"
    POINT    = "point"
    ARC      = "arc"
    TEXT     = "text"
    BLOCK    = "block"
    IMAGE    = "image"
    FACE3D   = "3dface"

    def dxfPolyline (self, xx, yy, zz, lay, handle, col):                 self.warnObj(lay, self.POLYLINE)
    def dxfLine     (self, xx, yy, zz, lay, handle, col):                 self.warnObj(lay, self.LINE) 
    def dxfCircle   (self, xx, yy, zz, lay, handle, col, r):              self.warnObj(lay, self.CIRCLE) 
    def dxfPoint    (self, xx, yy, zz, lay, handle, col):                 self.warnObj(lay, self.POINT)
    def dxfArc      (self, xx, yy, zz, lay, handle, col, r, theta1,
                     theta2):                                             self.warnObj(lay, self.ARC)
    def dxfText     (self, xx, yy, zz, lay, handle, col, text, h, theta): self.warnObj(lay, self.TEXT)
    def dxfBlockAtt (self, xx, yy, zz, lay, handle, col, blname, blatts): self.warnObj(lay, self.BLOCK)
    def dxfThanImage(self, xx, yy, zz, lay, handle, col, filnam, size, 
                     scale,  theta):                                      self.warnObj(lay, self.IMAGE)
    def dxf3dface   (self, xx, yy, zz, lay, handle, col):                 self.warnObj(lay, self.FACE3D)


class ThanDrLine(ThanDrWarn):
    "A class which gets only lines/polylines; it is an example of ThanDrWarn usage."

    def dxfPolyline (self, xx, yy, zz, lay, handle, col):
        "Get polyline if it is in known layers."
        if self._allLayKno or lay in self._laykno:
      self.processLine(xx, yy, zz, lay, handle, col)
  else:
      self.warnObj(lay, self.POLYLINE)
  
    def dxfLine     (self, xx, yy, zz, lay, handle, col):
        "Get line if it is in known layers."
        if self._allLayKno or lay in self._laykno:
      self.processLine(xx, yy, zz, lay, handle, col)
  else:
      self.warnObj(lay, self.LINE) 

    def processLine(self, xx, yy, zz, lay, handle, col):
        "What to do with the line/polyline; overwrite it."
  self.prt("Line x1=%.3f  y1=%.3f z1=%.3f ... in layer=%s" % (xx[0], yy[0], zz[0], lay))


class ThanDrSave:
    "A class which stores the elements read by ThanImportDxf."

    def __init__(self, prt=p_ggen.prg):
        "Creates an instance of the class."
        if prt == None: self.prt = _prt   # No message will be printed
  else:           self.prt = prt
  
        self.thanVports = [ ]
  self.thanLayers = [ ]
  self.thanLtypes = [ ]
  self.thanXymm = None
        self.thanPolylines = [ ]
        self.thanLines = [ ]
  self.thanCircles = [ ]
  self.thanPoints = [ ]
  self.thanArcs = [ ]
  self.thanTexts = [ ]
  self.thanBlocks = []
  self.thanImages = []
  self.than3dfaces = []

    def dxfVport(self, name, x1, y1, x2, y2):
        "Saves a View Port."
  self.thanVports.append((name, x1, y1, x2, y2))

    def dxfXymm(self, x1, y1, x2, y2):
        "Saves xmin,ymin,xmax,ymax of the dxf drawing."
  self.thanXymm = x1, y1, x2, y2

    def dxfLayer(self, name, atts):
        "Saves a layer."
  self.thanLayers.append((name, atts))

    def dxfLtype(self, name, desc, elems):
        "Saves a line type."
  self.thanLtypes.append((name, desc, elems))

    def dxfPolyline(self, xx, yy, zz, lay, handle, col):
        "Saves a polyline."
  self.thanPolylines.append((xx, yy, zz, lay, col))

    def dxfLine(self, xx, yy, zz, lay, handle, col):
        "Saves a line."
  self.thanLines.append((xx, yy, zz, lay, col))

    def dxfCircle(self, xx, yy, zz, lay, handle, col, r):
        "Saves a View Port."
  self.thanCircles.append((xx, yy, zz, lay, col, r))

    def dxfPoint(self, xx, yy, zz, lay, handle, col):
        "Saves a point."
  self.thanPoints.append((xx, yy, lay, col))

    def dxfArc(self, xx, yy, zz, lay, handle, col, r, theta1, theta2):
        "Saves a point."
  self.thanArcs.append((xx, yy, lay, col, r, theta1, theta2))

    def dxfText(self, xx, yy, zz, lay, handle, col, text, h, theta):
        "Saves a text."
  self.thanTexts.append((xx, yy, lay, col, text, h, theta))

    def dxfBlockAtt(self, xx, yy, zz, lay, handle, col, blname, blatts):
        "Saves a block insertion."
  self.thanBlocks.append((xx, yy, zz, lay, col, handle, col, blname, blatts))

    def dxfThanImage(self, xx, yy, zz, lay, handle, col, filnam, size, scale, theta):
        "Saves an ThanImage."
  self.thanImages.append((xx, yy, zz, lay, col, handle, filnam, size, scale, theta))

    def dxf3dface  (self, xx, yy, zz, lay, handle, col):
        "Saves a 3dface."
  self.than3dfaces.append((xx, yy, zz, lay, handle, col))
  
    def statistics(self):
        "Saves a text."
        self.prt("Contents of dxf file:")
        n = ""
  if self.thanXymm == None: n = "NOT"
  self.prt("Max, min of x,y     : %s defined in dxf file" % n)

  self.prt("Number of view ports: %d" % len(self.thanVports))
  self.prt("Number of layers    : %d" % len(self.thanLayers))
  self.prt("Number of line types: %d" % len(self.thanLtypes))
  self.prt("Number of polylines : %d" % len(self.thanPolylines))
  self.prt("Number of lines     : %d" % len(self.thanLines))
  self.prt("Number of texts     : %d" % len(self.thanTexts))
  self.prt("Number of points    : %d" % len(self.thanPoints))
  self.prt("Number of circles   : %d" % len(self.thanCircles))
        self.prt("Number of arcs      : %d" % len(self.thanArcs))
        self.prt("Number of blocks ins: %d" % len(self.thanBlocks))
        self.prt("Number of thanImages: %d" % len(self.thanImages))
        self.prt("Number of 3dfaces   : %d" % len(self.than3dfaces))


class ThanDrConpas(ThanDrWarn):
    "A class which gets control/pass points from a .dxf file."

    def __init__(self, filnam="<undefined>", ctype="noname", layer="fotost", prt=p_ggen.prg):
        """Sets the type of points and the layers to serach.
  
  If type == "noname" then x, y, z coordinates of all points plus an
            arbitrary name are returned.
        If type == "pixel" then x, y, z coordinates of all points are returned.
      Furthermore, the program looks for texts and finds the closest text to 
      a point, and considers it as the point's name. As a precaution, this
      point must also be the closest point to the text found, or else there
      is ambiguity and the program returns an error. The texts must not
      contain the character '/'.
        If type == "EGSA87" then x, y coordinates of all points are returned.
      Furthermore, the program looks for texts and finds the closest text to 
      a point, and considers it as the point's name. As a precaution, this
      point must also be the closest point to the text found, or else there
      is ambiguity and the program returns an error. The texts must
      contain the character '/' and after this the z coordinate of the point
      for example "Point1/123.457". This z is returned.
  if layer == "*" all the layers are searched. Else only the layer with name
      the content of the variable layer is searched.
  """
  self.layer = layer.lower()
  ThanDrWarn.__init__(self, self.layer, prt=prt)
        self.cxypix = []       # pixel coordinates of control points
        self.cname =  []       # names of control points
  self.filnam = filnam   # Name of the dxf file
  self.ctype = ctype     # Coordinate system type: pixel, EGSA87, or noname


    def dxfPoint(self, xx, yy, zz, lay, handle, col):
        "Selects the polylines only in certain layers."
  if self.layer == "*" or self.layer == lay.lower():
      self.cxypix.append([None, xx, yy, zz])
  else:
            self.warnObj(lay, self.POINT)


    def dxfText(self, xx, yy, zz, lay, handle, col, t, h, theta):
        "Selects the circle of layer plaisio; its center is the origin point."
  if self.layer == "*" or self.layer == lay.lower():
      self.cname.append((t, xx, yy))
  else:
            self.warnObj(lay, self.TEXT)


    def findHeight(self):
        "Tests and finds the height for the EGSA87 coordinates, or put zero height for pixel coordinates."
  if self.ctype == "nonamez":
      for j,(t,xt,yt) in enumerate(self.cname):
          try:
              ht = float(t)
    except ValueError, IndexError:
              self.prt("Error in file %s: Illegal height '%s':" % (self.filnam, t))
        self.prt("The height must be a numeic value.")
        self.prt("For example: '128.89' or '12.989'")
        raise ThanImportError
    self.cname[j] = "noname", xt, yt, ht
  elif self.ctype != "pixel":
      for j,(t,xt,yt) in enumerate(self.cname):
          try:
              t1, t2 = t.split("/")
        ht = float(t2)
    except ValueError, IndexError:
              self.prt("Error in file %s: Illegal point name '%s':" % (self.filnam, t))
        self.prt("The point should be of the form:")
        self.prt(" <name> / <height>")
        self.prt("For example: 'P1 / 128.89' or '1/12.989'")
        raise ThanImportError
    self.cname[j] = t1.strip(), xt, yt, ht
  else:
      for j,(t,xt,yt) in enumerate(self.cname):
          try:
              t1, t2 = t.split("/")
        ht = float(t2)
    except ValueError, IndexError:
        pass
    else:
              self.prt("Warning in file %s: It seems that you defined height to point '%s':" % (self.filnam, t))
        self.prt("    The point should NOT be of the form:")
        self.prt("     <name> / <height>")
        self.prt("    Please remove the height from the point.")
    self.cname[j] = t.strip(), xt, yt, 0.0
        


    def corNameHeight(self):
        "Correlates names with points; the name of a point is the closest text to it."
  for i,(aa,x,y,h) in enumerate(self.cxypix):
      if len(self.cname) < 1:
          self.prt("Error in file %s: Point with %s coordinates %.1f %.1f:" % (self.filnam, self.ctype, x,y))
    self.prt("The name and/or the height of this point was not defined.")
          self.prt("(The number of point names and/or heights is less than the number of points!)")
    raise ThanImportError
      ds = [((x-xt)**2+(y-yt)**2, j) for j,(t,xt,yt,ht) in enumerate(self.cname)]
      d, j = min(ds); t,xt,yt,ht = self.cname[j]
      ds = [((x1-xt)**2+(y1-yt)**2, i1) for i1,(aa1,x1,y1,h1) in enumerate(self.cxypix) if aa1 == None]
      d, i1 = min(ds)
      if i1 != i:
          self.prt("Error in file %s: Point with %s coordinates %.1f %.1f:" % (self.filnam, self.ctype, x,y))
    self.prt("The name and/or height of this point was probably not defined.")
    self.prt("The nearest name and/or height to this point is: '%s' but it was found to refer to" % t)
    self.prt("point with pixel coordinates %.1f %.1f" % (x1,y1))
    raise ThanImportError
      self.cxypix[i][0] = t
      if self.ctype != "pixel": self.cxypix[i][3] = ht
      del self.cname[j]
        if len(self.cname) > 0:
            self.prt("Warning in file %s: The number of points is less than the number of point names" % self.filnam)
            self.prt("and/or heights. The following point names and/or heights do not refer to any point:")
            if self.ctype == "nonamez":
                for t,xt,yt,ht in self.cname: self.prt(str(ht))
            else:
                for t,xt,yt,ht in self.cname: self.prt(t)


    def addName(self):
        "Adds suitable name to simple points."
        i = 1
        for c in self.cxypix:
            c[0] = str(i)
            i += 1


def thanDxfGetConpas(fdxf, ctype, layer="fotost", prt=p_ggen.prg):
    "Reads the coordinates of the control points from dxf file."
    dr = ThanDrConpas(fdxf.name, ctype, layer, prt)
    t = ThanImportDxf(fdxf, dr)
    t.thanImport()
    if ctype == "noname":
        dr.addName()
    elif ctype == "nonamez":
        dr.findHeight()
        dr.corNameHeight()
        dr.addName()
    else:
        dr.findHeight()
        dr.corNameHeight()
    return dr.cxypix


def testThanDxfGetConpas():
    "Test dxf import of named points."
    f = open("trap.dxf", "r")
    cxypix = thanDxfGetConpas(f, "pixel")
    for a,x,y,h in cxypix:
        print "%10s%15.3f%15.3f%15.3f" % (a,x,y,h)
    f = open("trap.dxe", "r")
    cxypix = thanDxfGetConpas(f, "EGSA87")
    for a,x,y,h in cxypix:
        print "%10s%15.3f%15.3f%15.3f" % (a,x,y,h)


def testThanDrSave():
    "Test dxf import."
    from p_gimdxf import ThanImportDxf,ThanImportError
    f = file("116.dxf", "r")
    dr = ThanDrSave()
    t = ThanImportDxf(f, dr)
    t.thanImport()
    f.close()
    dr.statistics()


def testThanDrLayer():
    "Test dxf import."
    from p_gimdxf import ThanImportDxf,ThanDrLayer,thanDxfColCode2Rgb
    fr = file("shm.dxf", "r")
    dr = ThanDrLayer()           # Instantiate the object that collects the layers
    t = ThanImportDxf(fr, dr)     # Instantiate the object which reads the dxf file
    t.thanImport()               # Read and parse the dxf file
    fr.close()
    del t
    fw = file("shm.csv", "w")
    form = "%s\t" * 9 + "\n"
    fw.write(form % ("Name", "Autocad Color", "RGB color", "line type", "frozen",
                     "off", "locked", "lineweight", "noplot"))
    for name in dr.layer:
        atts = dr.layer[name]
  fw.write(form % (name, atts["color"], thanDxfColCode2Rgb[atts["color"]], 
           atts["linetype"], atts["frozen"], atts["off"], atts["locked"],
     atts["lineweight"], atts["noplot"]))
    fw.close()


def testThanDrWarn():
    "Test dxf import."
    from p_gimdxf import ThanImportDxf,ThanImportError
    f = file("116.dxf", "r")
    dr = ThanDrWarn()
    t = ThanImportDxf(f, dr)
    t.thanImport()
    f.close()


def testThanDrConpas():
    "Test dxf import."
    from p_gimdxf import ThanImportDxf,ThanImportError
    f = file("trap1.dxe", "r")
    xy = thanDxfGetConpas(f, ctype="EGSA87", layer="fotost")
    for xy1 in xy: print xy1
    f.close()



if __name__ == "__main__": testThanDrLayer()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.