Esempio n. 1
0
    def test_dxf(self):
        drawings = g.get_2D()

        # split drawings into single body parts
        splits = []
        for d in drawings:
            s = d.split()
            # check area of split result vs source
            assert g.np.isclose(sum(i.area for i in s), d.area)
            splits.append(s)

            d.export(file_obj='temp.dxf')
            r = g.trimesh.load('temp.dxf')
            assert g.np.isclose(r.area, d.area)

        single = g.np.hstack(splits)

        for p in single:
            p.vertices /= p.scale
            p.export(file_obj='temp.dxf')
            r = g.trimesh.load('temp.dxf')
            ratio = abs(p.length - r.length) / p.length
            if ratio > .01:
                g.log.error('perimeter ratio on export %s wrong! %f %f %f',
                            p.metadata['file_name'], p.length, r.length, ratio)

                raise ValueError('perimeter ratio too large ({}) on {}'.format(
                    ratio, p.metadata['file_name']))
Esempio n. 2
0
    def test_discrete(self):
        for d in g.get_2D():
            self.assertTrue(len(d.polygons_closed) == len(d.paths))

            # file_name should be populated, and if we have a DXF file
            # the layer field should be populated with layer names
            if d.metadata['file_name'][-3:] == 'dxf':
                assert len(d.layers) == len(d.entities)

            for path in d.paths:
                verts = d.discretize_path(path)
                dists = g.np.sum((g.np.diff(verts, axis=0))**2, axis=1)**.5

                if not g.np.all(dists > g.tol_path.zero):
                    raise ValueError('{} had zero distance in discrete!',
                                     d.metadata['file_name'])

                circuit_dist = g.trimesh.util.euclidean(verts[0], verts[-1])
                circuit_test = circuit_dist < g.tol_path.merge
                if not circuit_test:
                    g.log.error('On file %s First and last vertex distance %f',
                                d.metadata['file_name'], circuit_dist)
                self.assertTrue(circuit_test)

                is_ccw = g.trimesh.path.util.is_ccw(verts)
                if not is_ccw:
                    g.log.error('discrete %s not ccw!',
                                d.metadata['file_name'])
                # self.assertTrue(is_ccw)

            for i in range(len(d.paths)):
                self.assertTrue(d.polygons_closed[i].is_valid)
                self.assertTrue(d.polygons_closed[i].area > g.tol_path.zero)
            export_dict = d.export(file_type='dict')
            to_dict = d.to_dict()
            assert isinstance(to_dict, dict)
            assert isinstance(export_dict, dict)
            assert len(to_dict) == len(export_dict)

            export_svg = d.export(file_type='svg')
            simple = d.simplify()
            split = d.split()
            g.log.info('Split %s into %d bodies, checking identifiers',
                       d.metadata['file_name'], len(split))
            for body in split:
                body.identifier

            if len(d.root) == 1:
                d.apply_obb()

            if len(d.vertices) < 150:
                g.log.info('Checking medial axis on %s',
                           d.metadata['file_name'])
                m = d.medial_axis()
                assert len(m.entities) > 0

            # transform to first quadrant
            d.rezero()
            # run process manually
            d.process()
Esempio n. 3
0
    def test_dxf(self):

        # get a path we can write
        temp_name = g.tempfile.NamedTemporaryFile(suffix='.dxf',
                                                  delete=False).name

        # split drawings into single body parts
        splits = []
        for d in g.get_2D():
            s = d.split()
            # check area of split result vs source
            assert g.np.isclose(sum(i.area for i in s), d.area)
            splits.append(s)

            # export the drawing to the file
            d.export(file_obj=temp_name)

            # try using ezdxf as a simple validator
            # it raises exceptions aggressively
            if ezdxf is not None:
                with open(temp_name, 'r') as f:
                    ezdxf.read(f)

            # export to a string
            text = d.export(file_type='dxf')

            # DXF files are always pairs of lines
            lines = str.splitlines(str(text))
            assert (len(lines) % 2) == 0
            assert all(len(L.strip()) > 0 for L in lines)

            # reload the file by name and by stream
            rc = [
                g.trimesh.load(temp_name),
                g.trimesh.load(g.io_wrap(text), file_type='dxf')
            ]

            # compare reloaded with original
            for r in rc:
                assert g.np.isclose(r.area, d.area)
                assert g.np.isclose(r.length, d.length, rtol=1e-4)
                assert len(r.entities) == len(d.entities)

        single = g.np.hstack(splits)
        for p in single:
            p.vertices /= p.scale

            # make sure exporting by name works
            # use tempfile to avoid dumping file in
            # our working directory
            p.export(temp_name)
            r = g.trimesh.load(temp_name)

            ratio = abs(p.length - r.length) / p.length
            if ratio > .01:
                g.log.error('perimeter ratio on export %s wrong! %f %f %f',
                            p.metadata['file_name'], p.length, r.length, ratio)

                raise ValueError('perimeter ratio too large ({}) on {}'.format(
                    ratio, p.metadata['file_name']))
Esempio n. 4
0
    def test_dxf(self):

        # get a path we can write
        temp_name = g.tempfile.NamedTemporaryFile(
            suffix='.dxf', delete=False).name

        # split drawings into single body parts
        splits = []
        for d in g.get_2D():
            s = d.split()
            # check area of split result vs source
            assert g.np.isclose(sum(i.area for i in s),
                                d.area)
            splits.append(s)

            # export the drawing to the file
            d.export(file_obj=temp_name)

            # export to a string
            text = d.export(file_type='dxf')

            # DXF files are always pairs of lines
            assert (len(str.splitlines(str(text))) % 2) == 0

            # reload the file by name and by stream
            rc = [g.trimesh.load(temp_name),
                  g.trimesh.load(g.io_wrap(text),
                                 file_type='dxf')]

            # compare reloaded with original
            for r in rc:
                assert g.np.isclose(r.area, d.area)
                assert g.np.isclose(r.length, d.length)
                assert len(r.entities) == len(d.entities)

        single = g.np.hstack(splits)
        for p in single:
            p.vertices /= p.scale

            # make sure exporting by name works
            # use tempfile to avoid dumping file in
            # our working directory
            p.export(temp_name)
            r = g.trimesh.load(temp_name)

            ratio = abs(p.length - r.length) / p.length
            if ratio > .01:
                g.log.error('perimeter ratio on export %s wrong! %f %f %f',
                            p.metadata['file_name'],
                            p.length,
                            r.length,
                            ratio)

                raise ValueError('perimeter ratio too large ({}) on {}'.format(
                    ratio,
                    p.metadata['file_name']))
Esempio n. 5
0
    def test_svg(self):
        for d in g.get_2D():
            # export as svg string
            exported = d.export('svg')
            # load the exported SVG
            stream = g.trimesh.util.wrap_as_stream(exported)
            loaded = g.trimesh.load(stream, file_type='svg')

            # we only have line and arc primitives as SVG export and import
            if all(i.__class__.__name__ in ['Line', 'Arc']
                   for i in d.entities):
                # perimeter should stay the same-ish on export/inport
                assert g.np.isclose(d.length, loaded.length, rtol=.01)
Esempio n. 6
0
    def test_dxf(self):

        # get a path we can write
        temp_name = g.tempfile.NamedTemporaryFile(
            suffix='.dxf', delete=False).name

        # split drawings into single body parts
        splits = []
        for d in g.get_2D():
            s = d.split()
            # check area of split result vs source
            assert g.np.isclose(sum(i.area for i in s),
                                d.area)
            splits.append(s)

            d.export(file_obj=temp_name)
            r = g.trimesh.load(temp_name)
            assert g.np.isclose(r.area, d.area)

        single = g.np.hstack(splits)

        for p in single:
            p.vertices /= p.scale

            # make sure exporting by name works
            # use tempfile to avoid dumping file in
            # our working directory
            p.export(temp_name)
            r = g.trimesh.load(temp_name)

            ratio = abs(p.length - r.length) / p.length
            if ratio > .01:
                g.log.error('perimeter ratio on export %s wrong! %f %f %f',
                            p.metadata['file_name'],
                            p.length,
                            r.length,
                            ratio)

                raise ValueError('perimeter ratio too large ({}) on {}'.format(
                    ratio,
                    p.metadata['file_name']))
Esempio n. 7
0
    def test_svg(self):
        for d in g.get_2D():
            # export as svg string
            exported = d.export(file_type='svg')
            # load the exported SVG
            stream = g.trimesh.util.wrap_as_stream(exported)

            if g.np.isclose(d.area, 0.0):
                continue

            loaded = g.trimesh.load(stream, file_type='svg')

            # we only have line and arc primitives as SVG
            # export and import
            if all(i.__class__.__name__ in ['Line', 'Arc']
                   for i in d.entities):
                # perimeter should stay the same-ish
                # on export/inport
                assert g.np.isclose(d.length,
                                    loaded.length,
                                    rtol=.01)
Esempio n. 8
0
    def test_svg(self):
        for d in g.get_2D():
            if g.np.isclose(d.area, 0.0):
                continue
            # export and reload the exported SVG
            loaded = g.trimesh.load(g.trimesh.util.wrap_as_stream(
                d.export(file_type='svg')),
                                    file_type='svg')

            # we only have line and arc primitives as SVG
            # export and import
            if all(i.__class__.__name__ in ['Line', 'Arc']
                   for i in d.entities):
                # perimeter should stay the same-ish
                # on export/import
                assert g.np.isclose(d.length, loaded.length, rtol=.01)

            path_str = g.trimesh.path.exchange.svg_io.export_svg(
                d, return_path=True)
            assert isinstance(path_str, str)
            assert len(path_str) > 0
Esempio n. 9
0
    def test_discrete(self):
        for d in g.get_2D():
            # store md5 before requesting passive functions
            md5 = d.md5()

            # make sure various methods return
            # basically the same bounds
            atol = d.scale / 1000
            for dis, pa, pl in zip(d.discrete,
                                   d.paths,
                                   d.polygons_closed):
                # bounds of discrete version of path
                bd = g.np.array([g.np.min(dis, axis=0),
                                 g.np.max(dis, axis=0)])
                # bounds of polygon version of path
                bl = g.np.reshape(pl.bounds, (2, 2))
                # try bounds of included entities from path
                pad = g.np.vstack([d.entities[i].discrete(d.vertices)
                                   for i in pa])
                bp = g.np.array([g.np.min(pad, axis=0),
                                 g.np.max(pad, axis=0)])

                assert g.np.allclose(bd, bl, atol=atol)
                assert g.np.allclose(bl, bp, atol=atol)

            # run some checks
            g.check_path2D(d)

            # copying shouldn't touch original file
            copied = d.copy()

            # these operations shouldn't have mutated anything!
            assert d.md5() == md5

            # copy should have saved the metadata
            assert set(copied.metadata.keys()) == set(d.metadata.keys())

            # file_name should be populated, and if we have a DXF file
            # the layer field should be populated with layer names
            if d.metadata['file_name'][-3:] == 'dxf':
                assert len(d.layers) == len(d.entities)

            for path in d.paths:
                verts = d.discretize_path(path)
                dists = g.np.sum((g.np.diff(verts, axis=0))**2, axis=1)**.5

                if not g.np.all(dists > g.tol_path.zero):
                    raise ValueError('{} had zero distance in discrete!',
                                     d.metadata['file_name'])

                circuit_dist = g.trimesh.util.euclidean(verts[0], verts[-1])
                circuit_test = circuit_dist < g.tol_path.merge
                if not circuit_test:
                    g.log.error('On file %s First and last vertex distance %f',
                                d.metadata['file_name'],
                                circuit_dist)
                assert circuit_test

                is_ccw = g.trimesh.path.util.is_ccw(verts)
                if not is_ccw:
                    g.log.error('discrete %s not ccw!',
                                d.metadata['file_name'])

            for i in range(len(d.paths)):
                assert d.polygons_closed[i].is_valid
                assert d.polygons_closed[i].area > g.tol_path.zero
            export_dict = d.export(file_type='dict')
            to_dict = d.to_dict()
            assert isinstance(to_dict, dict)
            assert isinstance(export_dict, dict)
            assert len(to_dict) == len(export_dict)

            export_svg = d.export(file_type='svg')  # NOQA
            simple = d.simplify()  # NOQA
            split = d.split()
            g.log.info('Split %s into %d bodies, checking identifiers',
                       d.metadata['file_name'],
                       len(split))
            for body in split:
                body.identifier

            if len(d.root) == 1:
                d.apply_obb()

            # store the X values of bounds
            ori = d.bounds.copy()
            # apply a translation
            d.apply_translation([10, 0])
            # X should have translated by 10.0
            assert g.np.allclose(d.bounds[:, 0] - 10, ori[:, 0])
            # Y should not have moved
            assert g.np.allclose(d.bounds[:, 1], ori[:, 1])

            if len(d.polygons_full) > 0 and len(d.vertices) < 150:
                g.log.info('Checking medial axis on %s',
                           d.metadata['file_name'])
                m = d.medial_axis()
                assert len(m.entities) > 0

            # shouldn't crash
            d.fill_gaps()

            # transform to first quadrant
            d.rezero()
            # run process manually
            d.process()
Esempio n. 10
0
 def setUp(self):
     self.drawings = g.get_2D()
     self.single = g.np.hstack([i.split() for i in self.drawings])
Esempio n. 11
0
    def test_discrete(self):

        for d in g.get_2D():
            # store md5 before requesting passive functions
            md5 = d.md5()

            # make sure various methods return
            # basically the same bounds
            atol = d.scale / 1000
            for dis, pa, pl in zip(d.discrete,
                                   d.paths,
                                   d.polygons_closed):
                # bounds of discrete version of path
                bd = g.np.array([g.np.min(dis, axis=0),
                                 g.np.max(dis, axis=0)])
                # bounds of polygon version of path
                bl = g.np.reshape(pl.bounds, (2, 2))
                # try bounds of included entities from path
                pad = g.np.vstack([d.entities[i].discrete(d.vertices)
                                   for i in pa])
                bp = g.np.array([g.np.min(pad, axis=0),
                                 g.np.max(pad, axis=0)])

                assert g.np.allclose(bd, bl, atol=atol)
                assert g.np.allclose(bl, bp, atol=atol)

            # run some checks
            g.check_path2D(d)

            # copying shouldn't touch original file
            copied = d.copy()

            # these operations shouldn't have mutated anything!
            assert d.md5() == md5

            # copy should have saved the metadata
            assert set(copied.metadata.keys()) == set(d.metadata.keys())

            # file_name should be populated, and if we have a DXF file
            # the layer field should be populated with layer names
            if d.metadata['file_name'][-3:] == 'dxf':
                assert len(d.layers) == len(d.entities)

            for path in d.paths:
                verts = d.discretize_path(path)
                dists = g.np.sum((g.np.diff(verts, axis=0))**2, axis=1)**.5

                if not g.np.all(dists > g.tol_path.zero):
                    raise ValueError('{} had zero distance in discrete!',
                                     d.metadata['file_name'])

                circuit_dist = g.trimesh.util.euclidean(verts[0], verts[-1])
                circuit_test = circuit_dist < g.tol_path.merge
                if not circuit_test:
                    g.log.error('On file %s First and last vertex distance %f',
                                d.metadata['file_name'],
                                circuit_dist)
                assert circuit_test

                is_ccw = g.trimesh.path.util.is_ccw(verts)
                if not is_ccw:
                    g.log.error('discrete %s not ccw!',
                                d.metadata['file_name'])

            for i in range(len(d.paths)):
                assert d.polygons_closed[i].is_valid
                assert d.polygons_closed[i].area > g.tol_path.zero
            export_dict = d.export(file_type='dict')
            to_dict = d.to_dict()
            assert isinstance(to_dict, dict)
            assert isinstance(export_dict, dict)
            assert len(to_dict) == len(export_dict)

            export_svg = d.export(file_type='svg')  # NOQA
            simple = d.simplify()  # NOQA
            split = d.split()
            g.log.info('Split %s into %d bodies, checking identifiers',
                       d.metadata['file_name'],
                       len(split))
            for body in split:
                body.identifier

            if len(d.root) == 1:
                d.apply_obb()

            # store the X values of bounds
            ori = d.bounds.copy()
            # apply a translation
            d.apply_translation([10, 0])
            # X should have translated by 10.0
            assert g.np.allclose(d.bounds[:, 0] - 10, ori[:, 0])
            # Y should not have moved
            assert g.np.allclose(d.bounds[:, 1], ori[:, 1])

            if len(d.polygons_full) > 0 and len(d.vertices) < 150:
                g.log.info('Checking medial axis on %s',
                           d.metadata['file_name'])
                m = d.medial_axis()
                assert len(m.entities) > 0

            # shouldn't crash
            d.fill_gaps()

            # transform to first quadrant
            d.rezero()
            # run process manually
            d.process()