-
Notifications
You must be signed in to change notification settings - Fork 1
/
skeinforge_engine.py
138 lines (110 loc) · 5.22 KB
/
skeinforge_engine.py
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/python
"""
Skeins a 3D model into gcode.
"""
from config import config
from datetime import timedelta
from entities import SlicedModel, RuntimeParameters
from fabmetheus_utilities import archive
from importlib import import_module
from utilities import memory_tracker
import StringIO
import argparse
import logging
import os
import re
import sys
import time
import traceback
try:
import cPickle as pickle
except:
import pickle
__plugins_path__ = 'plugins'
logger = logging.getLogger('engine')
def getCraftedTextFromPlugins(pluginSequence, gcode):
'Get a crafted shape file from a list of pluginSequence.'
lastProcedureTime = time.time()
if __plugins_path__ not in sys.path:
sys.path.insert(0, __plugins_path__)
for plugin in pluginSequence:
pluginModule = import_module(plugin)
if pluginModule != None:
if gcode.runtimeParameters.profileMemory:
memory_tracker.create_snapshot('Before %s action' % plugin)
pluginModule.performAction(gcode)
logger.info('%s plugin took %s seconds.', plugin.capitalize(), timedelta(seconds=time.time() - lastProcedureTime).total_seconds())
lastProcedureTime = time.time()
def main(argv=None):
"Starting point for skeinforge engine."
parser = argparse.ArgumentParser(description='Skeins a 3D model into slicedModel.')
parser.add_argument('file', help='The file to skein. Files accepted: stl, obj, gts, and svg. Or sliced model files produced by SkeinforgeEngine.')
parser.add_argument('-c', metavar='config', help='Configuration for skeinforge engine.', default='skeinforge_engine.cfg')
parser.add_argument('-p', metavar='profile', help='Profile for the skeining.')
parser.add_argument('-o', metavar='output', help='Output filename. Overrides other export filename settings.')
parser.add_argument('-r', metavar='reprocess', help='Comma seperated list of plugins to reprocess a sliced model file. The export plugin is automatically appended.')
if argv is None:
argv = sys.argv[1:]
args = parser.parse_args(argv)
if args.c == None:
logger.error('Invalid or missing configuration file.')
return
config.read(args.c)
logLevel = config.get('general', 'log.level')
logging.basicConfig(level=logLevel, format='%(asctime)s %(levelname)s (%(name)s) %(message)s')
defaultProfile = config.get('general', 'default.profile')
if defaultProfile != None:
config.read(defaultProfile)
profileName = config.get('profile', 'name')
if args.p != None:
config.read(args.p)
if profileName == 'default':
profileName = os.path.splitext(os.path.basename(args.p))[0]
logger.info("Profile: %s", profileName)
inputFilename = args.file
if not os.path.isfile(inputFilename):
logger.error('File not found: %s', inputFilename)
return
logger.info("Processing file: %s", os.path.basename(inputFilename))
exportedSlicedModelExtension = config.get('export', 'export.slicedmodel.extension')
if inputFilename.endswith(exportedSlicedModelExtension):
slicedModel = pickle.load(open(inputFilename))
slicedModel.runtimeParameters = RuntimeParameters()
inputFilename = inputFilename.replace('.'+exportedSlicedModelExtension, '')
else:
slicedModel = SlicedModel()
if args.o != None:
slicedModel.runtimeParameters.outputFilename = args.o
if args.r != None:
pluginSequence = args.r.split(',')
if 'export' not in pluginSequence:
pluginSequence.append('export')
else:
pluginSequence = config.get('general', 'plugin.sequence').split(',')
if inputFilename.endswith(exportedSlicedModelExtension) and 'carve' in pluginSequence:
logger.error('Reprocessing a sliced model file with carve is not possible. Please process the original file or choose a different reprocessing sequence.')
return
logger.debug("Plugin Sequence: %s", pluginSequence)
if slicedModel.runtimeParameters.profileMemory:
memory_tracker.track_object(slicedModel)
memory_tracker.create_snapshot('Start')
slicedModel.runtimeParameters.profileName = profileName
slicedModel.runtimeParameters.inputFilename = inputFilename
getCraftedTextFromPlugins(pluginSequence[:], slicedModel)
slicedModel.runtimeParameters.endTime = time.time()
logger.info('It took %s seconds to complete.', timedelta(seconds=slicedModel.runtimeParameters.endTime - slicedModel.runtimeParameters.startTime).total_seconds())
if slicedModel.runtimeParameters.profileMemory:
memory_tracker.create_snapshot('End')
if config.getboolean('general', 'profile.memory.print.summary'):
memory_tracker.tracker.stats.print_summary()
if config.getboolean('general', 'profile.memory.export.data'):
memory_tracker.tracker.stats.dump_stats('%s.memory_tracker.dat' % inputFilename)
if config.getboolean('general', 'profile.memory.export.html'):
from pympler.classtracker_stats import HtmlStats
HtmlStats(tracker=memory_tracker.tracker).create_html('%s.memory_tracker.html' % inputFilename)
return slicedModel
def handleError(self, record):
traceback.print_stack()
if __name__ == "__main__":
logging.Handler.handleError = handleError
main()