Ejemplo n.º 1
0
    def add_line(self, entity):
        '''
        Converts a DXF line entity (or entitines) to the proper form and adds
        the information to the list of vertices and to the set of segments

        ARGUMENTS:
        entity (obj)            --  DXF entity from dxfgrabber

        RAISES:
        TypeError               --  if entitiy.dxftype is not 'LINE'
        '''
        # Check input
        if entity.dxftype != 'LINE':
            msg = 'dxf entitiy passed was not a LINE but a {}'.format(
                entity.dxftype)
            raise TypeError(msg)

        # Find end-points
        start = (approx(entity.start[0],
                        tol=self.tol), approx(entity.start[1], tol=self.tol))
        end = (approx(entity.end[0],
                      tol=self.tol), approx(entity.end[1], tol=self.tol))

        # Add vertices and connect them
        self.verts.add(start)
        self.verts.add(end)
        self.verts.connect(start, end)

        # Collect segment data and add to set
        initial_len = len(self.segments)
        seg = ((start, end), ())
        self.vprint('adding line {}'.format(seg[0]))
        self.segments.add(seg)
        if len(self.segments) == initial_len:
            self.vprint('\tSegment already exists... skipped')
Ejemplo n.º 2
0
 def test_add_line(self):
     '''add a line to the geometry'''
     # Loop through entities and add only lines
     tol = self.empty_dxfgeom.tol
     for e in self.test_dxf.entities:
         if e.dxftype == 'LINE':
             self.empty_dxfgeom.add_line(e)
             start = (approx(e.start[0], tol=tol), 
                      approx(e.start[1], tol=tol))
             end = (e.end[0], e.end[1])
             self.check_vertices((start, end), self.empty_dxfgeom, e)
Ejemplo n.º 3
0
 def check_vertices(self, tup, dxfgeom, entity):
     '''vertices are in vertex list and they are connected'''
     tol = dxfgeom.tol
     start = (approx(tup[0][0], tol), approx(tup[0][1],tol))
     end = (approx(tup[1][0], tol), approx(tup[1][1],tol))
     # Check to make sure start and end are vertices now
     check = (start in dxfgeom.verts.coordinates) and (end in dxfgeom.verts.coordinates)
     msg = '{} and {} were not added to vertices'.format(start, end)
     self.assertTrue(check, msg)
     # Make sure vertices are connected
     check = end in dxfgeom.verts.vertices[start].connections
     msg = '{} not properly connected by line {}'.format(end, entity)
     self.assertTrue(check, msg)
Ejemplo n.º 4
0
 def test_add_polyline(self):
     '''add a polyline to the geometry'''
     # Loop through entities and add only arcs
     tol = self.empty_dxfgeom.tol
     for e in self.test_dxf.entities:
         if e.dxftype == 'POLYLINE':
             self.empty_dxfgeom.add_polyline(e)
             for i, p in enumerate(e.points):
                 try:
                     p_next = e.points[i+1]
                 except IndexError:
                     if e.is_closed:
                         p_next = e.points[0]
                     else:
                         break
                 start = (approx(p[0], tol=tol),
                          approx(p[1], tol=tol))
                 end = (approx(p_next[0], tol=tol), 
                         approx(p_next[1], tol=tol))
                 self.check_vertices((start, end), self.empty_dxfgeom, e)
Ejemplo n.º 5
0
    def add_arc(self, entity):
        '''
        Converts a DXF arc entity (or entities) to the proper form and adds the 
        information to the list of vertices and to the set of segments. Bulge
        and arc information is also compiled and computed.

        ARGUMENTS:
        entity (obj)            --  DXF entity from dxfgrabber

        RAISES:
        TypeError               --  if entitiy.dxftype is not 'ARC'
        '''
        # Check input
        if entity.dxftype != 'ARC':
            msg = 'dxf entitiy passed was not an ARC but a {}'.format(
                entity.dxftype)
            raise TypeError(msg)

        # Extract information (again ignoring z-coordinate)
        start_angle = np.radians(entity.startangle)
        end_angle = np.radians(entity.endangle)
        center = (approx(entity.center[0],
                         tol=self.tol), approx(entity.center[1], tol=self.tol))
        radius = approx(entity.radius, tol=1.0e-12)

        # Calculate bulge and start/stop information
        theta = ccw_angle_diff(start_angle, end_angle)
        bulge = np.tan(theta / 4)
        start = (approx(radius * np.cos(start_angle) + center[0],
                        tol=self.tol),
                 approx(radius * np.sin(start_angle) + center[1],
                        tol=self.tol))
        end = (approx(radius * np.cos(end_angle) + center[0], tol=self.tol),
               approx(radius * np.sin(end_angle) + center[1], tol=self.tol))

        # Add vertices and connect them
        self.verts.add(start)
        self.verts.add(end)
        self.verts.connect(start, end)

        # Collect segment data and add to set
        initial_len = len(self.segments)
        seg = ((start, end), (bulge, start_angle, end_angle, center, radius))
        self.vprint('adding arc {}'.format(seg[0]))
        self.segments.add(seg)
        if len(self.segments) == initial_len:
            self.vprint('\tSegment already exists... skipped')
Ejemplo n.º 6
0
 def test_add_arc(self):
     '''add an arc to the geometry'''
     # Loop through entities and add only arcs
     for e in self.test_dxf.entities:
         if e.dxftype == 'ARC':
             self.empty_dxfgeom.add_arc(e)
             tol = self.empty_dxfgeom.tol
             start_angle = math.radians(e.startangle)
             end_angle = math.radians(e.endangle)
             center = (approx(e.center[0], tol=tol), 
                       approx(e.center[1], tol=tol))
             radius = e.radius
             # Calculate bulge and start/stop information
             theta = ccw_angle_diff(start_angle, end_angle)
             bulge = math.tan(theta/4)
             start = (approx(radius*math.cos(start_angle) + center[0], tol=tol), 
                      approx(radius*math.sin(start_angle) + center[1], tol=tol))
             end = (approx(radius*math.cos(end_angle) + center[0], tol=tol), 
                    approx(radius*math.sin(end_angle) + center[1], tol=tol))
             self.check_vertices((start, end), self.empty_dxfgeom, e)
Ejemplo n.º 7
0
    def add_polyline(self, entity):
        '''
        Converts a DXF polyline entity into segments while transforming bulges
        into arcs (defined by a center of curvature and radius of curvature) and
        storing the vertex and segment information.

        ARGUMENTS:
        entity (obj)            --  DXF entity from dxfgrabber
        
        RAISES:
        TypeError               --  if entitiy.dxftype is not 'POLYLINE'
        '''
        # Check input
        if entity.dxftype != 'POLYLINE' and entity.dxftype != 'LWPOLYLINE':
            msg = 'dxf entitiy passed was not a POLYLINE but a {}'.format(
                entity.dxftype)
            raise TypeError(msg)

        self.vprint(
            'Breaking up this polyline into segments:\n{}'.format(entity))
        # Loop through the points in the polyline
        for i, point in enumerate(entity.points):
            # Add the current point
            start = (approx(point[0],
                            tol=self.tol), approx(point[1], tol=self.tol))
            self.verts.add(start)
            try:
                # Add the next point if it exists
                next_point = entity.points[i + 1]
            except IndexError:
                # Next point DOESN'T exist therefore this is the end of the
                # polyline
                if entity.is_closed:
                    # If polyline is closed, connect the last point (the current
                    # point) back to the first point
                    first_point = entity.points[0]
                    end = (approx(first_point[0], tol=self.tol),
                           approx(first_point[1], tol=self.tol))
                    self.verts.connect(start, end)
                else:
                    # Otherwise the polyline is open so all segments have been
                    # added already
                    self.vprint('\tThis polyline is not closed!')
                    break
            else:
                # The next point DOES exist so add it and connect it to the
                # current point
                end = (approx(next_point[0],
                              tol=self.tol), approx(next_point[1],
                                                    tol=self.tol))
                self.verts.add(end)
                # Connect the two points
                #print start, end
                self.verts.connect(start, end)

            # Find number of segments before adding this one
            initial_len = len(self.segments)

            # Check whether there is a bulge in this segment
            if entity.bulge[i] != 0:
                # Convert bulge information to arc and store information
                bulge = entity.bulge[i]
                # Distance between points
                d = np.sqrt((start[0] - end[0])**2 + (start[1] - end[1])**2)
                # Angle between points from center
                theta = 4 * np.arctan(bulge)
                # Radius of circle making arc
                radius = approx(d / 2 / np.sin(abs(theta) / 2), tol=1e-12)
                # Find angle of segment relative to x axis
                alpha = np.arctan2(end[1] - start[1], end[0] - start[0])
                # beta = (np.pi/2 - abs(theta)/2)*(np.pi - abs(theta))/abs(np.pi - abs(theta))
                # # Angle to radius vector from x-axis is then the sum of alpha
                # # and beta
                # gamma = alpha + beta
                if bulge > 0:
                    # Find angle between segment and radius. Beta is negative if
                    # theta is greater than pi
                    beta = np.pi / 2 - theta / 2
                    # Angle to radius vector from x-axis is then the SUM of
                    # alpha and beta
                    gamma = alpha + beta
                else:
                    # Find angle between segment and radius. Beta is negative if
                    # theta is greater than pi
                    beta = np.pi / 2 + theta / 2
                    # Angle to radius vector from x-axis is then the DIFFERENCE
                    # between alpha and beta
                    gamma = alpha - beta
                # Gamma angle and radius describe the vector pointing from the
                # start point to the center
                center = (approx(radius * np.cos(gamma) + start[0],
                                 tol=self.tol),
                          approx(radius * np.sin(gamma) + start[1],
                                 tol=self.tol))
                # Now compute start and stop angles relative to horizontal in
                # a counter-clockwise sense
                start_angle = angle360(
                    np.arctan2(start[1] - center[1], start[0] - center[0]))
                end_angle = angle360(
                    np.arctan2(end[1] - center[1], end[0] - center[0]))

                # Compile all bulge/arc information and add it to segments
                seg = ((start, end), (bulge, start_angle, end_angle, center,
                                      radius))
                self.vprint('\tadding arc {}'.format(seg[0]))
                self.segments.add(seg)
                if len(self.segments) == initial_len:
                    self.vprint('\tSegment already exists... skipped')

            # Segment is a straight line
            else:
                seg = ((start, end), ())
                # Add info to segments
                self.vprint('\tadding line {}'.format(seg[0]))
                self.segments.add(seg)
                if len(self.segments) == initial_len:
                    self.vprint('\tSegment already exists... skipped')