Remote Debug exampleΒΆ

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# STL saver plug-in, written in Python

import lx
import lxifc


# We're going to use a visitor to examine the polygons in the meshes. The Evaluate()
# method is called for each polygon, and we read the vertex count from the accessor.
# The result is just a count of triangles and non-triangles.
#
class TriangleVisitor(lxifc.Visitor):
    def __init__(self):
        self.n_tri = 0
        self.n_not = 0

    def set_mesh(self, mesh):
        self.poly = mesh.PolygonAccessor()

    def vis_Evaluate(self):
        if (self.poly.VertexCount() == 3):
            self.n_tri += 1
        else:
            self.n_not += 1


# Another visitor does the actual output. We need a point accessor to read out the
# point positions for the polygon vertices. The lines will contain the output lines
# if all is successful.
#
class OutputVisitor(lxifc.Visitor):
    def __init__(self, mon, n):
        self.lines = []
        self.mon   = lx.object.Monitor(mon)
        self.mon.Initialize(n)

    def set_mesh(self, mesh):
        self.poly  = mesh.PolygonAccessor()
        self.point = mesh.PointAccessor()

    def vis_Evaluate(self):
        if (self.poly.VertexCount() != 3):
            return

        norm = self.poly.Normal()
        self.lines.append("facet {0:.8f} {1:.8f} {2:.8f}".format(-norm[0], norm[1], norm[2]))
        self.lines.append("  outer loop")

        for i in range(3):
            self.point.Select(self.poly.VertexByIndex(i))
            pos = self.point.Pos()
            self.lines.append("    vertex {0} {1} {2}".format (-pos[0], -pos[1], -pos[2]))

        self.lines.append("  end loop")
        self.lines.append("end facet")


# Our STL saver class, with verify and save methods.
#
class STLSaver(lxifc.Saver):
    def __init__(self):
        self.scene_svc = lx.service.Scene()

        # Mesh item type. We could look it up but don't have a symbol for that at the mo
        #
        self.mesh_type = 4      # shoud be: scene_svc.LookupType(lx.symbol.sITYPE_MESH)

    # Enumeration scans the mesh items and enumerates the polygons for each.
    #
    def enum(self, scene, vis):
        cread = scene.Channels(lx.symbol.s_ACTIONLAYER_SETUP, 0.0)

        for i in range(scene.ItemCount(self.mesh_type)):
            item = scene.ItemByIndex(self.mesh_type, i)
            k = item.ChannelLookup('mesh')      # should be: lx.symbol.sICHAN_MESH_MESH
            mesh = lx.object.Mesh(cread.ValueObj(item, k))
            vis.set_mesh(mesh)
            vis.poly.Enumerate(lx.symbol.iMARK_ANY, vis, 0)

    # Verify presents errors for no triangles and warnings for a mix of triangles and not.
    #
    def sav_Verify(self, source, message):
        scene = lx.object.Scene(source)
        msg   = lx.object.Message(message)
        vis   = TriangleVisitor()

        self.enum(scene, vis)
        self.n_tri = vis.n_tri

        if vis.n_tri == 0:
            msg.SetCode(lx.result.NOTFOUND)
            msg.SetMessage('common', '', 99)
            msg.SetArgumentString(1, "Scene contains no triangles.")
        elif vis.n_not:
            msg.SetCode(lx.result.WARNING)
            msg.SetMessage('common', '', 99)
            msg.SetArgumentString(1, "Faces with more than 3 sides will be skipped.")

    # Saving counts the triangles, and then scans them a second time to write
    # them to the line buffer. Finally that's output to the STL text file.
    #
    def sav_Save(self, source, filename, monitor):
        scene = lx.object.Scene(source)
        cread = scene.Channels(lx.symbol.s_ACTIONLAYER_SETUP, 0.0)

        vis = TriangleVisitor()
        self.enum(scene, vis)

        vis = OutputVisitor(monitor, vis.n_tri)
        self.enum(scene, vis)

        file = open(filename, 'w')
        file.writelines( [x + '\n' for x in vis.lines] )
        file.close()


# Bless the class to make it a first-class saver.
#
tags = {
    lx.symbol.sSRV_USERNAME: "Stereolithograhpy STL",
    lx.symbol.sSAV_OUTCLASS:  lx.symbol.a_SCENE,
    lx.symbol.sSAV_DOSTYPE : "STL"
}
lx.bless(STLSaver, "pySTLScene", tags)