示例#1
0
 def test_flat_DXFList(self):
     atoms = DXFList()
     atoms.append(DXFAtom('HEADER'))
     atoms.append(DXFAtom('SECTION', 1))
     self.assertEqual(dxfstr(atoms), '  0\nHEADER\n  1\nSECTION\n')
     result = tags2str(atoms)
     self.assertEqual(dxfstr(atoms), result)
示例#2
0
 def test_Sublists(self):
     atoms = DXFList([
         DXFList([
             DXFAtom('TAG1'),
             DXFAtom('TAG2'),
             DXFList([
                 DXFAtom('TAG14'),
                 DXFAtom('TAG15'),
                 DXFAtom('TAG16'),
             ]),
             DXFAtom('TAG3'),
         ]),
         DXFList([
             DXFAtom('TAG4'),
             DXFAtom('TAG5'),
             DXFAtom('TAG6'),
             DXFList([
                 DXFAtom('TAG11'),
                 DXFAtom('TAG12'),
                 DXFAtom('TAG13'),
             ]),
         ]),
         DXFAtom('TAG7'),
     ])
     self.assertEqual(dxfstr(atoms), tags2str(atoms))
示例#3
0
文件: rect.py 项目: msarch/py
 def _build_rect(self):
     data = DXFList()
     self._calc_corners()
     if self.color is not None:
         data.append(self._build_polyline())
     if self.bgcolor is not None:
         data.append(self._build_solid())
     return data
示例#4
0
 def _get_body(self):
     """ Return header section content as DXFList.
     """
     varlist = [
         DXFList((DXFAtom(key, 9), value))
         for key, value in self.variables.items()
     ]
     return DXFList((DXFName('HEADER'), DXFList(varlist)))
示例#5
0
class Entities(_Section):
    def __init__(self):
        self.entities = DXFList()

    def _get_body(self):
        return DXFList( (DXFName('ENTITIES'),
                          self.entities))

    def add(self, entity):
        self.entities.append(entity)
示例#6
0
class Entities(_Section):
    def __init__(self):
        self.entities = DXFList()

    def _get_body(self):
        return DXFList((DXFName('ENTITIES'), self.entities))

    def add(self, entity):
        """ Add a DXF entity to the entities section.
        """
        self.entities.append(entity)
示例#7
0
    def _build(self):
        data = DXFList()
        self.transformed_points = self._transform_points(self.points)
        if self.color is not None:
            data.append(self._build_polyline())
        if self.bgcolor is not None:
            if len(self.points) <= 4:
                data.append(self._build_solid())
            elif self.solidFillQuads:
                for i in range(len(self.points) // 2 - 1):
                    data.append(self._build_solid_quad(i))
            else:
                for i in range(len(self.points) - 2):
                    data.append(self._build_solid_triangle(i))

        return data
示例#8
0
    def get_dxf_entity(self, coords, layer):
        """ Create the cell content as MText-object.

        :param coords: tuple of border-coordinates : left, right, top, bottom
        :param layer: layer, which should be used for dxf entities
        """
        if not len(self.text):
            return DXFList()
        left, right, top, bottom = self.get_workspace_coords(coords)
        style = self.style
        halign = style['halign']
        valign = style['valign']
        rotated = self.style['rotation']
        text = self.text
        if style['stacked']:
            rotated = 0.
            text = '\n'.join((char for char in self.text.replace('\n', ' ')))
        xpos = (left, float(left + right) / 2., right)[halign]
        ypos = (bottom, float(bottom + top) / 2., top)[valign - 1]
        return MText(text, (xpos, ypos),
                     linespacing=self.style['linespacing'],
                     style=self.style['textstyle'],
                     height=self.style['textheight'],
                     rotation=rotated,
                     xscale=self.style['xscale'],
                     halign=halign,
                     valign=valign,
                     color=self.style['textcolor'],
                     layer=layer)
示例#9
0
    def __init__(self, insert, nrows, ncols, default_grid=True):
        """
        :param insert: insert point as 2D or 3D point
        :param int nrows: row count
        :param int ncols: column count
        :param bool default_grid: if **True** always a solid line grid will
            be drawn, if **False**, only explicit defined borders will be
            drawn, default grid has a priority of 50.
        """
        self.insert = insert
        self.nrows = nrows
        self.ncols = ncols
        self.row_heights = [DEFAULT_TABLE_HEIGHT] * nrows
        self.col_widths = [DEFAULT_TABLE_WIDTH] * ncols
        self.bglayer = DEFAULT_TABLE_BGLAYER
        self.fglayer = DEFAULT_TABLE_FGLAYER
        self.gridlayer = DEFAULT_TABLE_GRIDLAYER
        self.styles = {'default': Style.get_default_cell_style()}
        if not default_grid:
            default_style = self.get_cell_style('default')
            default_style.set_border_status(False, False, False, False)

        self._cells = {} # data cells
        self.frames = [] # border frame objects
        # visibility_map stores the visibilty of the cells, created in _setup
        self.visibility_map = None
        # grid manages the border lines, created in _setup
        self.grid = None
        # data contains the resulting dxf entities
        self.data = DXFList()
        self.empty_cell = Cell(self) # represents all empty cells
示例#10
0
文件: mtext.py 项目: pprodano/pputils
 def _build_dxf_entities(self):
     """ Create the DXF-TEXT entities. 
     """
     dxf_entities = DXFList()
     textlines = self.textlines
     
     if len(textlines) > 1:
         if self.mirror & dxfwrite.MIRROR_Y:
             textlines.reverse()
         for linenum, text in enumerate(textlines):
             alignpoint = self._get_align_point(linenum)
             params = self._build_text_params(alignpoint)
             dxf_entities.append(Text(text=text, **params))
     elif len(textlines) == 1:
         params = self._build_text_params(self.insert)
         dxf_entities = Text(text=textlines[0], **params).__dxftags__()
     return dxf_entities
示例#11
0
    def _build_dxf_entities(self):
        """ Create the DXF-TEXT entities. 
        """
        dxf_entities = DXFList()
        textlines = self.textlines

        if len(textlines) > 1:
            if self.mirror & dxfwrite.MIRROR_Y:
                textlines.reverse()
            for linenum, text in enumerate(textlines):
                alignpoint = self._get_align_point(linenum)
                params = self._build_text_params(alignpoint)
                dxf_entities.append(Text(text=text, **params))
        elif len(textlines) == 1:
            params = self._build_text_params(self.insert)
            dxf_entities = Text(text=textlines[0], **params).__dxftags__()
        return dxf_entities
示例#12
0
文件: sections.py 项目: msarch/py
 def _get_body(self):
     return DXFList( (DXFName('TABLES'),
                       self.linetypes,
                       self.layers,
                       self.styles,
                       self.views,
                       self.appids,
                       self.viewports,
                       self.ucs,
                       ) )
示例#13
0
 def test_flat_DXFList(self):
     atoms = DXFList()
     atoms.append(DXFAtom('HEADER'))
     atoms.append(DXFAtom('SECTION', 1))
     self.assertEqual(dxfstr(atoms), '  0\nHEADER\n  1\nSECTION\n')
     result = tags2str(atoms)
     self.assertEqual(dxfstr(atoms), result)
示例#14
0
文件: rect.py 项目: msarch/py
 def _build_rect(self):
     data = DXFList()
     self._calc_corners()
     if self.color is not None:
         data.append(self._build_polyline())
     if self.bgcolor is not None:
         data.append(self._build_solid())
     return data
示例#15
0
 def __init__(self, insert, width, height, rotation=0.,
              halign=const.LEFT, valign=const.TOP,
              color=const.BYLAYER, bgcolor=None,
              layer='0', linetype=None):
     self.insert = insert
     self.width = float(width)
     self.height = float(height)
     self.rotation = math.radians(rotation)
     self.halign = halign
     self.valign = valign
     self.color = color
     self.bgcolor = bgcolor
     self.layer = layer
     self.linetype = linetype
     self.points = None
     self.data = DXFList()
示例#16
0
 def _build(self):
     data = DXFList()
     ralign = self._get_radius_align()
     self.points = self._calc_points(ralign)
     align_vector = self._get_align_vector()
     self._transform_points(align_vector)
     if self.color is not None:
         data.append(self._build_polyline())
     if self.bgcolor is not None:
         #if _calc_points has been run, rmin is already set
         if self.rmin <= 0:
             #if self.angle%(2*math.pi) == math.radians(90): #rounded corner case
             for i in range(self.segments + 1):
                 data.append(self._build_solid_triangle(i))
         else:  #rmin>0, normal operation
             for i in range(self.segments + 1):
                 data.append(self._build_solid_quad(i))
     return data
示例#17
0
 def _build(self):
     data = DXFList()
     self.points = self._calc_points()
     self._transform_points()
     if self.color is not None:
         data.append(self._build_polyline())
     if self.bgcolor is not None:
         #if _calc_points has been run, rmin is already set
         for i in range(self.segments):
             data.append(self._build_solid_triangle(i))
     return data
示例#18
0
    def __init__(self, text, insert, linespacing=1.5, **kwargs):
        self.textlines = text.split('\n')
        self.insert = insert
        self.linespacing = linespacing
        self.valign = kwargs.get('valign', dxfwrite.TOP) # only top, middle, bottom
        if self.valign == dxfwrite.BASELINE: # baseline for MText not usefull
            self.valign = dxfwrite.BOTTOM
        self.halign = kwargs.get('halign', dxfwrite.LEFT) # only left, center, right
        self.height = kwargs.get('height', 1.0)
        self.style = kwargs.get('style', 'STANDARD')
        self.oblique = kwargs.get('oblique', 0.0) # in degree
        self.rotation = kwargs.get('rotation', 0.0) # in degree
        self.xscale = kwargs.get('xscale', 1.0)
        self.mirror = kwargs.get('mirror', 0)
        self.layer = kwargs.get('layer', '0')
        self.color = kwargs.get('color', dxfwrite.BYLAYER)
        self.data = DXFList()

        if len(self.textlines)>1: # more than one line
            self._build_dxf_text_entities()
        elif len(self.textlines) == 1: # just a normal text with one line
            kwargs['alignpoint'] = insert # text() needs the align point
            self.data.append(Text(text=text, insert=insert, **kwargs))
示例#19
0
 def __init__(self):
     self.entities = DXFList()
示例#20
0
class MText(object):
    """ MultiLine-Text buildup with simple Text-Entities.

    Mostly the same kwargs like DXFEngine.text().
    Caution: align point is always the insert point, I don't need a second
    alignpoint because horizontal alignment FIT, ALIGN, BASELINE_MIDDLE is not
    supported.

    linespacing -- linespacing in percent of height, 1.5 = 150% = 1+1/2 lines
    """
    name = 'MTEXT'

    def __init__(self, text, insert, linespacing=1.5, **kwargs):
        self.textlines = text.split('\n')
        self.insert = insert
        self.linespacing = linespacing
        self.valign = kwargs.get('valign', dxfwrite.TOP) # only top, middle, bottom
        if self.valign == dxfwrite.BASELINE: # baseline for MText not usefull
            self.valign = dxfwrite.BOTTOM
        self.halign = kwargs.get('halign', dxfwrite.LEFT) # only left, center, right
        self.height = kwargs.get('height', 1.0)
        self.style = kwargs.get('style', 'STANDARD')
        self.oblique = kwargs.get('oblique', 0.0) # in degree
        self.rotation = kwargs.get('rotation', 0.0) # in degree
        self.xscale = kwargs.get('xscale', 1.0)
        self.mirror = kwargs.get('mirror', 0)
        self.layer = kwargs.get('layer', '0')
        self.color = kwargs.get('color', dxfwrite.BYLAYER)
        self.data = DXFList()

        if len(self.textlines)>1: # more than one line
            self._build_dxf_text_entities()
        elif len(self.textlines) == 1: # just a normal text with one line
            kwargs['alignpoint'] = insert # text() needs the align point
            self.data.append(Text(text=text, insert=insert, **kwargs))

    @property
    def lineheight(self):
        """ absolute linespacing in drawing units """
        return self.height * self.linespacing

    def _build_dxf_text_entities(self):
        """ create the dxf TEXT entities """
        if self.mirror & dxfwrite.MIRROR_Y:
            self.textlines.reverse()
        for linenum, text in enumerate(self.textlines):
            alignpoint = self._get_align_point(linenum)
            params = self._build_text_params(alignpoint)
            self.data.append(Text(text=text, **params))

    def _get_align_point(self, linenum):
        """Calculate the align point depending on the line number. """
        x = self.insert[0]
        y = self.insert[1]
        try:
            z = self.insert[2]
        except IndexError:
            z = 0.
        # rotation not respected
        if self.valign == dxfwrite.TOP:
            y -= linenum * self.lineheight
        elif self.valign == dxfwrite.MIDDLE:
            y0 = linenum * self.lineheight
            fullheight = (len(self.textlines) - 1) * self.lineheight
            y += (fullheight/2) - y0
        else: # dxfwrite.BOTTOM
            y += (len(self.textlines) - 1 - linenum) * self.lineheight
        return self._rotate( (x, y, z) ) # consider rotation

    def _rotate(self, alignpoint):
        """Rotate alignpoint around insert point about rotation degrees."""
        dx = alignpoint[0] - self.insert[0]
        dy = alignpoint[1] - self.insert[1]
        beta = math.radians(self.rotation)
        x = self.insert[0] + dx * math.cos(beta) - dy * math.sin(beta)
        y = self.insert[1] + dy * math.cos(beta) + dx * math.sin(beta)
        return (round(x, 6), round(y, 6), alignpoint[2])

    def _build_text_params(self, alignpoint):
        """Build the calling dict for Text()."""
        return {
            'insert': alignpoint,
            'alignpoint': alignpoint,
            'layer': self.layer,
            'color': self.color,
            'style': self.style,
            'height': self.height,
            'xscale': self.xscale,
            'mirror': self.mirror,
            'rotation': self.rotation,
            'oblique': self.oblique,
            'halign': self.halign,
            'valign': self.valign,
        }

    def __dxf__(self):
        """ get the dxf string """
        return self.data.__dxf__()
示例#21
0
 def _get_body(self):
     return DXFList((DXFName('ENTITIES'), self.entities))
示例#22
0
 def __dxftags__(self):
     return DXFList(
         (DXFAtom('SECTION'), DXFList(self._get_body()), DXFAtom('ENDSEC')))
示例#23
0
 def test_empty_DXFList(self):
     atoms = DXFList()
     self.assertEqual(dxfstr(atoms), '')
     self.assertEqual(dxfstr(atoms), tags2str(atoms))
示例#24
0
 def __init__(self):
     self.entities = DXFList()
示例#25
0
 def _get_body(self):
     body = DXFList()
     body.append(DXFName('BLOCKS'))
     body.extend(self.blocks.values())
     return body
示例#26
0
 def _setup(self):
     """ Table generation setup.
     """
     self.data = DXFList()
     self.visibility_map = VisibilityMap(self)
     self.grid = Grid(self)
示例#27
0
 def get_dxf_entity(self, coords, layer):
     return DXFList()
示例#28
0
 def __dxf__(self):
     self._build_table()
     result = self.data.__dxf__()
     self.data = DXFList() # don't need to keep this data in memory
     return result
示例#29
0
class Table(object):
    """A HTML-table like object.

    The table object contains the table data cells.
    """
    name = 'TABLE'

    def __init__(self, insert, nrows, ncols, default_grid=True):
        """
        :param insert: insert point as 2D or 3D point
        :param int nrows: row count
        :param int ncols: column count
        :param bool default_grid: if **True** always a solid line grid will
            be drawn, if **False**, only explicit defined borders will be
            drawn, default grid has a priority of 50.
        """
        self.insert = insert
        self.nrows = nrows
        self.ncols = ncols
        self.row_heights = [DEFAULT_TABLE_HEIGHT] * nrows
        self.col_widths = [DEFAULT_TABLE_WIDTH] * ncols
        self.bglayer = DEFAULT_TABLE_BGLAYER
        self.fglayer = DEFAULT_TABLE_FGLAYER
        self.gridlayer = DEFAULT_TABLE_GRIDLAYER
        self.styles = {'default': Style.get_default_cell_style()}
        if not default_grid:
            default_style = self.get_cell_style('default')
            default_style.set_border_status(False, False, False, False)

        self._cells = {} # data cells
        self.frames = [] # border frame objects
        # visibility_map stores the visibilty of the cells, created in _setup
        self.visibility_map = None
        # grid manages the border lines, created in _setup
        self.grid = None
        # data contains the resulting dxf entities
        self.data = DXFList()
        self.empty_cell = Cell(self) # represents all empty cells

    def set_col_width(self, column, value):
        """Set column width of **column** to **value** (in drawing units).
        """
        self.col_widths[column] = float(value)

    def set_row_height(self, row, value):
        """Set row heigth of **row** to **value** (in drawing units).
        """
        self.row_heights[row] = float(value)

    def text_cell(self, row, col, text, span=(1, 1), style='default'):
        """Create a new text cell at pos (**row**, **col**), with **text** as
        content, text can be a multi line text, use ``'\\n'`` as line
        seperator.

        The cell spans over **span** cells and has the cell style with the
        name **style**.
        """
        cell = TextCell(self, text, style=style, span=span)
        return self.set_cell(row, col, cell)

    # pylint: disable-msg=W0102
    def block_cell(self, row, col, blockdef, span=(1, 1), attribs={}, style='default'):
        """Create a new block cell at position (**row**, **col**), content is
        a block reference inserted by a :ref:`INSERT` entity, attributes will
        be added if the block definition contains :ref:`ATTDEF`. Assignments
        are defined by attribs-key to attdef-tag association.
        Example: attribs = {'num': 1} if an :ref:`ATTDEF` with tag=='num' in
        the block definition exists, an attrib with text=str(1) will be
        created and added to the insert entity.

        The cell spans over **span** cells and has the cell style with the
        name **style**.
        """
        cell = BlockCell(self, blockdef, style=style, attribs=attribs, span=span)
        return self.set_cell(row, col, cell)

    def set_cell(self, row, col, cell):
        """Insert a **cell** at position (**row**, **col**)."""
        row, col = self.validate_index(row, col)
        self._cells[row, col] = cell
        return cell

    def get_cell(self, row, col):
        """Get cell at position (**row**, **col**)."""
        row, col = self.validate_index(row, col)
        try:
            return self._cells[row, col]
        except KeyError:
            return self.empty_cell # emtpy cell with default style

    def validate_index(self, row, col):
        row = int(row)
        col = int(col)
        if row < 0 or row >= self.nrows or \
           col < 0 or col >= self.ncols:
            raise IndexError('cell index out of range')
        return row, col

    def frame(self, row, col, width=1, height=1, style='default'):
        """Create a Frame object which frames the cell area starting at
        **row**, **col** covering **widths** columns and **heigth** rows.
        """
        frame = Frame(self, pos=(row, col), span=(height, width),
                      style=style)
        self.frames.append(frame)
        return frame

    def new_cell_style(self, name, **kwargs):
        """Create a new Style object with the name **name**.

        :param kwargs: see Style.get_default_cell_style()
        """
        style = deepcopy(self.get_cell_style('default'))
        style.update(kwargs)
        self.styles[name] = style
        return style

    def new_border_style(self, color=const.BYLAYER, status=True,
                         priority=100, linetype=None):
        """Create a new border style.

        :param bool status: if **True** border is visible, **False** border
            is hidden
        :param int color: dxf color index
        :param string linetype: linetype name, BYLAYER if None
        :param int priority: drawing priority - higher values covers lower
            values
        """
        border_style = Style.get_default_border_style()
        border_style['color'] = color
        border_style['linetype'] = linetype
        border_style['status'] = status
        border_style['priority'] = priority
        return border_style

    def get_cell_style(self, name):
        """Get cell style by **name**.
        """
        return self.styles[name]

    def iter_visible_cells(self):
        """Iterate over all visible cells.

        returns a generator which yields all visible cells as tuples:
        **row**, **col**, **cell**
        """
        if self.visibility_map is None:
            raise Exception("Can only be called at dxf creation.")
        return ((row, col, self.get_cell(row, col))
                for row, col in self.visibility_map)

    def __dxf__(self):
        self._build_table()
        result = self.data.__dxf__()
        self.data = DXFList() # don't need to keep this data in memory
        return result

    def _setup(self):
        """Table generation setup."""
        self.visibility_map = VisibilityMap(self, status=VISIBLE)
        self.grid = Grid(self)

    def _build_table(self):
        """Table is generated on calling the __dxf__() method."""
        self._setup()
        self.grid.draw_lines()
        for row, col, cell in self.iter_visible_cells():
            self.grid.draw_cell_background(row, col, cell)
            self.grid.draw_cell_content(row, col, cell)
        self._cleanup()

    def _cleanup(self):
        """Table generation cleanup. """
        self.visibility_map = None
        self.grid = None
示例#30
0
 def _get_body(self):
     body = DXFList()
     body.append(DXFName('BLOCKS'))
     body.extend(self.blocks.values())
     return body
示例#31
0
class Rectangle(object):
    """ 2D Rectangle, consisting of a polyline and a solid as background filling.
    """
    name = 'RECTANGLE'

    def __init__(self, insert, width, height, rotation=0.,
                 halign=const.LEFT, valign=const.TOP,
                 color=const.BYLAYER, bgcolor=None,
                 layer='0', linetype=None):
        self.insert = insert
        self.width = float(width)
        self.height = float(height)
        self.rotation = math.radians(rotation)
        self.halign = halign
        self.valign = valign
        self.color = color
        self.bgcolor = bgcolor
        self.layer = layer
        self.linetype = linetype
        self.points = None
        self.data = DXFList()

    def _build_rect(self):
        self._calc_corners()
        if self.color is not None:
            self._build_polyline()
        if self.bgcolor is not None:
            self._build_solid()

    def _calc_corners(self):
        points = [(0., 0.), (self.width, 0.), (self.width, self.height),
                  (0., self.height)]
        align_vector = self._get_align_vector()
        self.points = [vadd(self.insert, # move to insert point
                            rotate_2d( # rotate at origin
                                vadd(point, align_vector), self.rotation))
                       for point in points]

    def _get_align_vector(self):
        if self.halign == const.CENTER:
            dx = -self.width/2.
        elif self.halign == const.RIGHT:
            dx = -self.width
        else: # const.LEFT
            dx = 0.

        if self.valign == const.MIDDLE:
            dy = -self.height/2.
        elif self.valign == const.BOTTOM:
            dy = -self.height
        else: #const.TOP
            dy = 0.

        return (dx, dy)

    def _build_polyline(self):
        """ build the rectangle with a polyline """
        polyline = Polyline(self.points, color=self.color, layer=self.layer)
        polyline.close()
        if self.linetype is not None:
            polyline['linetype'] = self.linetype
        self.data.append(polyline)

    def _build_solid(self):
        """ build the background solid """
        self.data.append(Solid(
            self.points, color=self.bgcolor, layer=self.layer))

    def __dxf__(self):
        """ get the dxf string """
        self._build_rect()
        return self.data.__dxf__()